*** empty log message ***
[bpt/emacs.git] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985,86,87,88,93,94,95,97,98,99,2000,01,02,03,04
3 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
125
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
131
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
138
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
146
147
148 Frame matrices.
149
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
156
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
168
169 #include <config.h>
170 #include <stdio.h>
171
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
192
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201 #endif
202
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
206
207 #define INFINITY 10000000
208
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
214
215 extern int interrupt_input;
216 extern int command_loop_level;
217
218 extern int minibuffer_auto_raise;
219 extern Lisp_Object Vminibuffer_list;
220
221 extern Lisp_Object Qface;
222 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
223
224 extern Lisp_Object Voverriding_local_map;
225 extern Lisp_Object Voverriding_local_map_menu_flag;
226 extern Lisp_Object Qmenu_item;
227 extern Lisp_Object Qwhen;
228 extern Lisp_Object Qhelp_echo;
229
230 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
231 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
232 Lisp_Object Qredisplay_end_trigger_functions;
233 Lisp_Object Qinhibit_point_motion_hooks;
234 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
235 Lisp_Object Qfontified;
236 Lisp_Object Qgrow_only;
237 Lisp_Object Qinhibit_eval_during_redisplay;
238 Lisp_Object Qbuffer_position, Qposition, Qobject;
239
240 /* Cursor shapes */
241 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
242
243 /* Pointer shapes */
244 Lisp_Object Qarrow, Qhand, Qtext;
245
246 Lisp_Object Qrisky_local_variable;
247
248 /* Holds the list (error). */
249 Lisp_Object list_of_error;
250
251 /* Functions called to fontify regions of text. */
252
253 Lisp_Object Vfontification_functions;
254 Lisp_Object Qfontification_functions;
255
256 /* Non-zero means automatically select any window when the mouse
257 cursor moves into it. */
258 int mouse_autoselect_window;
259
260 /* Non-zero means draw tool bar buttons raised when the mouse moves
261 over them. */
262
263 int auto_raise_tool_bar_buttons_p;
264
265 /* Margin around tool bar buttons in pixels. */
266
267 Lisp_Object Vtool_bar_button_margin;
268
269 /* Thickness of shadow to draw around tool bar buttons. */
270
271 EMACS_INT tool_bar_button_relief;
272
273 /* Non-zero means automatically resize tool-bars so that all tool-bar
274 items are visible, and no blank lines remain. */
275
276 int auto_resize_tool_bars_p;
277
278 /* Non-zero means draw block and hollow cursor as wide as the glyph
279 under it. For example, if a block cursor is over a tab, it will be
280 drawn as wide as that tab on the display. */
281
282 int x_stretch_cursor_p;
283
284 /* Non-nil means don't actually do any redisplay. */
285
286 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
287
288 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
289
290 int inhibit_eval_during_redisplay;
291
292 /* Names of text properties relevant for redisplay. */
293
294 Lisp_Object Qdisplay;
295 extern Lisp_Object Qface, Qinvisible, Qwidth;
296
297 /* Symbols used in text property values. */
298
299 Lisp_Object Vdisplay_pixels_per_inch;
300 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
301 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
302 Lisp_Object Qslice;
303 Lisp_Object Qcenter;
304 Lisp_Object Qmargin, Qpointer;
305 Lisp_Object Qline_height, Qtotal;
306 extern Lisp_Object Qheight;
307 extern Lisp_Object QCwidth, QCheight, QCascent;
308 extern Lisp_Object Qscroll_bar;
309 extern Lisp_Object Qcursor;
310
311 /* Non-nil means highlight trailing whitespace. */
312
313 Lisp_Object Vshow_trailing_whitespace;
314
315 #ifdef HAVE_WINDOW_SYSTEM
316 extern Lisp_Object Voverflow_newline_into_fringe;
317
318 /* Test if overflow newline into fringe. Called with iterator IT
319 at or past right window margin, and with IT->current_x set. */
320
321 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
322 (!NILP (Voverflow_newline_into_fringe) \
323 && FRAME_WINDOW_P (it->f) \
324 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
325 && it->current_x == it->last_visible_x)
326
327 #endif /* HAVE_WINDOW_SYSTEM */
328
329 /* Non-nil means show the text cursor in void text areas
330 i.e. in blank areas after eol and eob. This used to be
331 the default in 21.3. */
332
333 Lisp_Object Vvoid_text_area_pointer;
334
335 /* Name of the face used to highlight trailing whitespace. */
336
337 Lisp_Object Qtrailing_whitespace;
338
339 /* The symbol `image' which is the car of the lists used to represent
340 images in Lisp. */
341
342 Lisp_Object Qimage;
343
344 /* The image map types. */
345 Lisp_Object QCmap, QCpointer;
346 Lisp_Object Qrect, Qcircle, Qpoly;
347
348 /* Non-zero means print newline to stdout before next mini-buffer
349 message. */
350
351 int noninteractive_need_newline;
352
353 /* Non-zero means print newline to message log before next message. */
354
355 static int message_log_need_newline;
356
357 /* Three markers that message_dolog uses.
358 It could allocate them itself, but that causes trouble
359 in handling memory-full errors. */
360 static Lisp_Object message_dolog_marker1;
361 static Lisp_Object message_dolog_marker2;
362 static Lisp_Object message_dolog_marker3;
363 \f
364 /* The buffer position of the first character appearing entirely or
365 partially on the line of the selected window which contains the
366 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
367 redisplay optimization in redisplay_internal. */
368
369 static struct text_pos this_line_start_pos;
370
371 /* Number of characters past the end of the line above, including the
372 terminating newline. */
373
374 static struct text_pos this_line_end_pos;
375
376 /* The vertical positions and the height of this line. */
377
378 static int this_line_vpos;
379 static int this_line_y;
380 static int this_line_pixel_height;
381
382 /* X position at which this display line starts. Usually zero;
383 negative if first character is partially visible. */
384
385 static int this_line_start_x;
386
387 /* Buffer that this_line_.* variables are referring to. */
388
389 static struct buffer *this_line_buffer;
390
391 /* Nonzero means truncate lines in all windows less wide than the
392 frame. */
393
394 int truncate_partial_width_windows;
395
396 /* A flag to control how to display unibyte 8-bit character. */
397
398 int unibyte_display_via_language_environment;
399
400 /* Nonzero means we have more than one non-mini-buffer-only frame.
401 Not guaranteed to be accurate except while parsing
402 frame-title-format. */
403
404 int multiple_frames;
405
406 Lisp_Object Vglobal_mode_string;
407
408
409 /* List of variables (symbols) which hold markers for overlay arrows.
410 The symbols on this list are examined during redisplay to determine
411 where to display overlay arrows. */
412
413 Lisp_Object Voverlay_arrow_variable_list;
414
415 /* Marker for where to display an arrow on top of the buffer text. */
416
417 Lisp_Object Voverlay_arrow_position;
418
419 /* String to display for the arrow. Only used on terminal frames. */
420
421 Lisp_Object Voverlay_arrow_string;
422
423 /* Values of those variables at last redisplay are stored as
424 properties on `overlay-arrow-position' symbol. However, if
425 Voverlay_arrow_position is a marker, last-arrow-position is its
426 numerical position. */
427
428 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
429
430 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
431 properties on a symbol in overlay-arrow-variable-list. */
432
433 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
434
435 /* Like mode-line-format, but for the title bar on a visible frame. */
436
437 Lisp_Object Vframe_title_format;
438
439 /* Like mode-line-format, but for the title bar on an iconified frame. */
440
441 Lisp_Object Vicon_title_format;
442
443 /* List of functions to call when a window's size changes. These
444 functions get one arg, a frame on which one or more windows' sizes
445 have changed. */
446
447 static Lisp_Object Vwindow_size_change_functions;
448
449 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
450
451 /* Nonzero if overlay arrow has been displayed once in this window. */
452
453 static int overlay_arrow_seen;
454
455 /* Nonzero means highlight the region even in nonselected windows. */
456
457 int highlight_nonselected_windows;
458
459 /* If cursor motion alone moves point off frame, try scrolling this
460 many lines up or down if that will bring it back. */
461
462 static EMACS_INT scroll_step;
463
464 /* Nonzero means scroll just far enough to bring point back on the
465 screen, when appropriate. */
466
467 static EMACS_INT scroll_conservatively;
468
469 /* Recenter the window whenever point gets within this many lines of
470 the top or bottom of the window. This value is translated into a
471 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
472 that there is really a fixed pixel height scroll margin. */
473
474 EMACS_INT scroll_margin;
475
476 /* Number of windows showing the buffer of the selected window (or
477 another buffer with the same base buffer). keyboard.c refers to
478 this. */
479
480 int buffer_shared;
481
482 /* Vector containing glyphs for an ellipsis `...'. */
483
484 static Lisp_Object default_invis_vector[3];
485
486 /* Zero means display the mode-line/header-line/menu-bar in the default face
487 (this slightly odd definition is for compatibility with previous versions
488 of emacs), non-zero means display them using their respective faces.
489
490 This variable is deprecated. */
491
492 int mode_line_inverse_video;
493
494 /* Prompt to display in front of the mini-buffer contents. */
495
496 Lisp_Object minibuf_prompt;
497
498 /* Width of current mini-buffer prompt. Only set after display_line
499 of the line that contains the prompt. */
500
501 int minibuf_prompt_width;
502
503 /* This is the window where the echo area message was displayed. It
504 is always a mini-buffer window, but it may not be the same window
505 currently active as a mini-buffer. */
506
507 Lisp_Object echo_area_window;
508
509 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
510 pushes the current message and the value of
511 message_enable_multibyte on the stack, the function restore_message
512 pops the stack and displays MESSAGE again. */
513
514 Lisp_Object Vmessage_stack;
515
516 /* Nonzero means multibyte characters were enabled when the echo area
517 message was specified. */
518
519 int message_enable_multibyte;
520
521 /* Nonzero if we should redraw the mode lines on the next redisplay. */
522
523 int update_mode_lines;
524
525 /* Nonzero if window sizes or contents have changed since last
526 redisplay that finished. */
527
528 int windows_or_buffers_changed;
529
530 /* Nonzero means a frame's cursor type has been changed. */
531
532 int cursor_type_changed;
533
534 /* Nonzero after display_mode_line if %l was used and it displayed a
535 line number. */
536
537 int line_number_displayed;
538
539 /* Maximum buffer size for which to display line numbers. */
540
541 Lisp_Object Vline_number_display_limit;
542
543 /* Line width to consider when repositioning for line number display. */
544
545 static EMACS_INT line_number_display_limit_width;
546
547 /* Number of lines to keep in the message log buffer. t means
548 infinite. nil means don't log at all. */
549
550 Lisp_Object Vmessage_log_max;
551
552 /* The name of the *Messages* buffer, a string. */
553
554 static Lisp_Object Vmessages_buffer_name;
555
556 /* Current, index 0, and last displayed echo area message. Either
557 buffers from echo_buffers, or nil to indicate no message. */
558
559 Lisp_Object echo_area_buffer[2];
560
561 /* The buffers referenced from echo_area_buffer. */
562
563 static Lisp_Object echo_buffer[2];
564
565 /* A vector saved used in with_area_buffer to reduce consing. */
566
567 static Lisp_Object Vwith_echo_area_save_vector;
568
569 /* Non-zero means display_echo_area should display the last echo area
570 message again. Set by redisplay_preserve_echo_area. */
571
572 static int display_last_displayed_message_p;
573
574 /* Nonzero if echo area is being used by print; zero if being used by
575 message. */
576
577 int message_buf_print;
578
579 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
580
581 Lisp_Object Qinhibit_menubar_update;
582 int inhibit_menubar_update;
583
584 /* Maximum height for resizing mini-windows. Either a float
585 specifying a fraction of the available height, or an integer
586 specifying a number of lines. */
587
588 Lisp_Object Vmax_mini_window_height;
589
590 /* Non-zero means messages should be displayed with truncated
591 lines instead of being continued. */
592
593 int message_truncate_lines;
594 Lisp_Object Qmessage_truncate_lines;
595
596 /* Set to 1 in clear_message to make redisplay_internal aware
597 of an emptied echo area. */
598
599 static int message_cleared_p;
600
601 /* Non-zero means we want a hollow cursor in windows that are not
602 selected. Zero means there's no cursor in such windows. */
603
604 Lisp_Object Vcursor_in_non_selected_windows;
605 Lisp_Object Qcursor_in_non_selected_windows;
606
607 /* How to blink the default frame cursor off. */
608 Lisp_Object Vblink_cursor_alist;
609
610 /* A scratch glyph row with contents used for generating truncation
611 glyphs. Also used in direct_output_for_insert. */
612
613 #define MAX_SCRATCH_GLYPHS 100
614 struct glyph_row scratch_glyph_row;
615 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
616
617 /* Ascent and height of the last line processed by move_it_to. */
618
619 static int last_max_ascent, last_height;
620
621 /* Non-zero if there's a help-echo in the echo area. */
622
623 int help_echo_showing_p;
624
625 /* If >= 0, computed, exact values of mode-line and header-line height
626 to use in the macros CURRENT_MODE_LINE_HEIGHT and
627 CURRENT_HEADER_LINE_HEIGHT. */
628
629 int current_mode_line_height, current_header_line_height;
630
631 /* The maximum distance to look ahead for text properties. Values
632 that are too small let us call compute_char_face and similar
633 functions too often which is expensive. Values that are too large
634 let us call compute_char_face and alike too often because we
635 might not be interested in text properties that far away. */
636
637 #define TEXT_PROP_DISTANCE_LIMIT 100
638
639 #if GLYPH_DEBUG
640
641 /* Variables to turn off display optimizations from Lisp. */
642
643 int inhibit_try_window_id, inhibit_try_window_reusing;
644 int inhibit_try_cursor_movement;
645
646 /* Non-zero means print traces of redisplay if compiled with
647 GLYPH_DEBUG != 0. */
648
649 int trace_redisplay_p;
650
651 #endif /* GLYPH_DEBUG */
652
653 #ifdef DEBUG_TRACE_MOVE
654 /* Non-zero means trace with TRACE_MOVE to stderr. */
655 int trace_move;
656
657 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
658 #else
659 #define TRACE_MOVE(x) (void) 0
660 #endif
661
662 /* Non-zero means automatically scroll windows horizontally to make
663 point visible. */
664
665 int automatic_hscrolling_p;
666
667 /* How close to the margin can point get before the window is scrolled
668 horizontally. */
669 EMACS_INT hscroll_margin;
670
671 /* How much to scroll horizontally when point is inside the above margin. */
672 Lisp_Object Vhscroll_step;
673
674 /* The variable `resize-mini-windows'. If nil, don't resize
675 mini-windows. If t, always resize them to fit the text they
676 display. If `grow-only', let mini-windows grow only until they
677 become empty. */
678
679 Lisp_Object Vresize_mini_windows;
680
681 /* Buffer being redisplayed -- for redisplay_window_error. */
682
683 struct buffer *displayed_buffer;
684
685 /* Value returned from text property handlers (see below). */
686
687 enum prop_handled
688 {
689 HANDLED_NORMALLY,
690 HANDLED_RECOMPUTE_PROPS,
691 HANDLED_OVERLAY_STRING_CONSUMED,
692 HANDLED_RETURN
693 };
694
695 /* A description of text properties that redisplay is interested
696 in. */
697
698 struct props
699 {
700 /* The name of the property. */
701 Lisp_Object *name;
702
703 /* A unique index for the property. */
704 enum prop_idx idx;
705
706 /* A handler function called to set up iterator IT from the property
707 at IT's current position. Value is used to steer handle_stop. */
708 enum prop_handled (*handler) P_ ((struct it *it));
709 };
710
711 static enum prop_handled handle_face_prop P_ ((struct it *));
712 static enum prop_handled handle_invisible_prop P_ ((struct it *));
713 static enum prop_handled handle_display_prop P_ ((struct it *));
714 static enum prop_handled handle_composition_prop P_ ((struct it *));
715 static enum prop_handled handle_overlay_change P_ ((struct it *));
716 static enum prop_handled handle_fontified_prop P_ ((struct it *));
717
718 /* Properties handled by iterators. */
719
720 static struct props it_props[] =
721 {
722 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
723 /* Handle `face' before `display' because some sub-properties of
724 `display' need to know the face. */
725 {&Qface, FACE_PROP_IDX, handle_face_prop},
726 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
727 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
728 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
729 {NULL, 0, NULL}
730 };
731
732 /* Value is the position described by X. If X is a marker, value is
733 the marker_position of X. Otherwise, value is X. */
734
735 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
736
737 /* Enumeration returned by some move_it_.* functions internally. */
738
739 enum move_it_result
740 {
741 /* Not used. Undefined value. */
742 MOVE_UNDEFINED,
743
744 /* Move ended at the requested buffer position or ZV. */
745 MOVE_POS_MATCH_OR_ZV,
746
747 /* Move ended at the requested X pixel position. */
748 MOVE_X_REACHED,
749
750 /* Move within a line ended at the end of a line that must be
751 continued. */
752 MOVE_LINE_CONTINUED,
753
754 /* Move within a line ended at the end of a line that would
755 be displayed truncated. */
756 MOVE_LINE_TRUNCATED,
757
758 /* Move within a line ended at a line end. */
759 MOVE_NEWLINE_OR_CR
760 };
761
762 /* This counter is used to clear the face cache every once in a while
763 in redisplay_internal. It is incremented for each redisplay.
764 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
765 cleared. */
766
767 #define CLEAR_FACE_CACHE_COUNT 500
768 static int clear_face_cache_count;
769
770 /* Record the previous terminal frame we displayed. */
771
772 static struct frame *previous_terminal_frame;
773
774 /* Non-zero while redisplay_internal is in progress. */
775
776 int redisplaying_p;
777
778 /* Non-zero means don't free realized faces. Bound while freeing
779 realized faces is dangerous because glyph matrices might still
780 reference them. */
781
782 int inhibit_free_realized_faces;
783 Lisp_Object Qinhibit_free_realized_faces;
784
785 /* If a string, XTread_socket generates an event to display that string.
786 (The display is done in read_char.) */
787
788 Lisp_Object help_echo_string;
789 Lisp_Object help_echo_window;
790 Lisp_Object help_echo_object;
791 int help_echo_pos;
792
793 /* Temporary variable for XTread_socket. */
794
795 Lisp_Object previous_help_echo_string;
796
797 /* Null glyph slice */
798
799 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
800
801 \f
802 /* Function prototypes. */
803
804 static void setup_for_ellipsis P_ ((struct it *));
805 static void mark_window_display_accurate_1 P_ ((struct window *, int));
806 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
807 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
808 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
809 static int redisplay_mode_lines P_ ((Lisp_Object, int));
810 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
811
812 #if 0
813 static int invisible_text_between_p P_ ((struct it *, int, int));
814 #endif
815
816 static int next_element_from_ellipsis P_ ((struct it *));
817 static void pint2str P_ ((char *, int, int));
818 static void pint2hrstr P_ ((char *, int, int));
819 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
820 struct text_pos));
821 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
822 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
823 static void store_frame_title_char P_ ((char));
824 static int store_frame_title P_ ((const unsigned char *, int, int));
825 static void x_consider_frame_title P_ ((Lisp_Object));
826 static void handle_stop P_ ((struct it *));
827 static int tool_bar_lines_needed P_ ((struct frame *));
828 static int single_display_prop_intangible_p P_ ((Lisp_Object));
829 static void ensure_echo_area_buffers P_ ((void));
830 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
831 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
832 static int with_echo_area_buffer P_ ((struct window *, int,
833 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
834 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
835 static void clear_garbaged_frames P_ ((void));
836 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
837 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
838 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
839 static int display_echo_area P_ ((struct window *));
840 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
841 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
842 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
843 static int string_char_and_length P_ ((const unsigned char *, int, int *));
844 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
845 struct text_pos));
846 static int compute_window_start_on_continuation_line P_ ((struct window *));
847 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
848 static void insert_left_trunc_glyphs P_ ((struct it *));
849 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
850 Lisp_Object));
851 static void extend_face_to_end_of_line P_ ((struct it *));
852 static int append_space_for_newline P_ ((struct it *, int));
853 static int make_cursor_line_fully_visible P_ ((struct window *, int));
854 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
855 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
856 static int trailing_whitespace_p P_ ((int));
857 static int message_log_check_duplicate P_ ((int, int, int, int));
858 static void push_it P_ ((struct it *));
859 static void pop_it P_ ((struct it *));
860 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
861 static void select_frame_for_redisplay P_ ((Lisp_Object));
862 static void redisplay_internal P_ ((int));
863 static int echo_area_display P_ ((int));
864 static void redisplay_windows P_ ((Lisp_Object));
865 static void redisplay_window P_ ((Lisp_Object, int));
866 static Lisp_Object redisplay_window_error ();
867 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
868 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
869 static void update_menu_bar P_ ((struct frame *, int));
870 static int try_window_reusing_current_matrix P_ ((struct window *));
871 static int try_window_id P_ ((struct window *));
872 static int display_line P_ ((struct it *));
873 static int display_mode_lines P_ ((struct window *));
874 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
875 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
876 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
877 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
878 static void display_menu_bar P_ ((struct window *));
879 static int display_count_lines P_ ((int, int, int, int, int *));
880 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
881 int, int, struct it *, int, int, int, int));
882 static void compute_line_metrics P_ ((struct it *));
883 static void run_redisplay_end_trigger_hook P_ ((struct it *));
884 static int get_overlay_strings P_ ((struct it *, int));
885 static void next_overlay_string P_ ((struct it *));
886 static void reseat P_ ((struct it *, struct text_pos, int));
887 static void reseat_1 P_ ((struct it *, struct text_pos, int));
888 static void back_to_previous_visible_line_start P_ ((struct it *));
889 static void reseat_at_previous_visible_line_start P_ ((struct it *));
890 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
891 static int next_element_from_display_vector P_ ((struct it *));
892 static int next_element_from_string P_ ((struct it *));
893 static int next_element_from_c_string P_ ((struct it *));
894 static int next_element_from_buffer P_ ((struct it *));
895 static int next_element_from_composition P_ ((struct it *));
896 static int next_element_from_image P_ ((struct it *));
897 static int next_element_from_stretch P_ ((struct it *));
898 static void load_overlay_strings P_ ((struct it *, int));
899 static int init_from_display_pos P_ ((struct it *, struct window *,
900 struct display_pos *));
901 static void reseat_to_string P_ ((struct it *, unsigned char *,
902 Lisp_Object, int, int, int, int));
903 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
904 int, int, int));
905 void move_it_vertically_backward P_ ((struct it *, int));
906 static void init_to_row_start P_ ((struct it *, struct window *,
907 struct glyph_row *));
908 static int init_to_row_end P_ ((struct it *, struct window *,
909 struct glyph_row *));
910 static void back_to_previous_line_start P_ ((struct it *));
911 static int forward_to_next_line_start P_ ((struct it *, int *));
912 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
913 Lisp_Object, int));
914 static struct text_pos string_pos P_ ((int, Lisp_Object));
915 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
916 static int number_of_chars P_ ((unsigned char *, int));
917 static void compute_stop_pos P_ ((struct it *));
918 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
919 Lisp_Object));
920 static int face_before_or_after_it_pos P_ ((struct it *, int));
921 static int next_overlay_change P_ ((int));
922 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
923 Lisp_Object, struct text_pos *,
924 int));
925 static int underlying_face_id P_ ((struct it *));
926 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
927 struct window *));
928
929 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
930 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
931
932 #ifdef HAVE_WINDOW_SYSTEM
933
934 static void update_tool_bar P_ ((struct frame *, int));
935 static void build_desired_tool_bar_string P_ ((struct frame *f));
936 static int redisplay_tool_bar P_ ((struct frame *));
937 static void display_tool_bar_line P_ ((struct it *));
938 static void notice_overwritten_cursor P_ ((struct window *,
939 enum glyph_row_area,
940 int, int, int, int));
941
942
943
944 #endif /* HAVE_WINDOW_SYSTEM */
945
946 \f
947 /***********************************************************************
948 Window display dimensions
949 ***********************************************************************/
950
951 /* Return the bottom boundary y-position for text lines in window W.
952 This is the first y position at which a line cannot start.
953 It is relative to the top of the window.
954
955 This is the height of W minus the height of a mode line, if any. */
956
957 INLINE int
958 window_text_bottom_y (w)
959 struct window *w;
960 {
961 int height = WINDOW_TOTAL_HEIGHT (w);
962
963 if (WINDOW_WANTS_MODELINE_P (w))
964 height -= CURRENT_MODE_LINE_HEIGHT (w);
965 return height;
966 }
967
968 /* Return the pixel width of display area AREA of window W. AREA < 0
969 means return the total width of W, not including fringes to
970 the left and right of the window. */
971
972 INLINE int
973 window_box_width (w, area)
974 struct window *w;
975 int area;
976 {
977 int cols = XFASTINT (w->total_cols);
978 int pixels = 0;
979
980 if (!w->pseudo_window_p)
981 {
982 cols -= WINDOW_SCROLL_BAR_COLS (w);
983
984 if (area == TEXT_AREA)
985 {
986 if (INTEGERP (w->left_margin_cols))
987 cols -= XFASTINT (w->left_margin_cols);
988 if (INTEGERP (w->right_margin_cols))
989 cols -= XFASTINT (w->right_margin_cols);
990 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
991 }
992 else if (area == LEFT_MARGIN_AREA)
993 {
994 cols = (INTEGERP (w->left_margin_cols)
995 ? XFASTINT (w->left_margin_cols) : 0);
996 pixels = 0;
997 }
998 else if (area == RIGHT_MARGIN_AREA)
999 {
1000 cols = (INTEGERP (w->right_margin_cols)
1001 ? XFASTINT (w->right_margin_cols) : 0);
1002 pixels = 0;
1003 }
1004 }
1005
1006 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1007 }
1008
1009
1010 /* Return the pixel height of the display area of window W, not
1011 including mode lines of W, if any. */
1012
1013 INLINE int
1014 window_box_height (w)
1015 struct window *w;
1016 {
1017 struct frame *f = XFRAME (w->frame);
1018 int height = WINDOW_TOTAL_HEIGHT (w);
1019
1020 xassert (height >= 0);
1021
1022 /* Note: the code below that determines the mode-line/header-line
1023 height is essentially the same as that contained in the macro
1024 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1025 the appropriate glyph row has its `mode_line_p' flag set,
1026 and if it doesn't, uses estimate_mode_line_height instead. */
1027
1028 if (WINDOW_WANTS_MODELINE_P (w))
1029 {
1030 struct glyph_row *ml_row
1031 = (w->current_matrix && w->current_matrix->rows
1032 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1033 : 0);
1034 if (ml_row && ml_row->mode_line_p)
1035 height -= ml_row->height;
1036 else
1037 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1038 }
1039
1040 if (WINDOW_WANTS_HEADER_LINE_P (w))
1041 {
1042 struct glyph_row *hl_row
1043 = (w->current_matrix && w->current_matrix->rows
1044 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1045 : 0);
1046 if (hl_row && hl_row->mode_line_p)
1047 height -= hl_row->height;
1048 else
1049 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1050 }
1051
1052 /* With a very small font and a mode-line that's taller than
1053 default, we might end up with a negative height. */
1054 return max (0, height);
1055 }
1056
1057 /* Return the window-relative coordinate of the left edge of display
1058 area AREA of window W. AREA < 0 means return the left edge of the
1059 whole window, to the right of the left fringe of W. */
1060
1061 INLINE int
1062 window_box_left_offset (w, area)
1063 struct window *w;
1064 int area;
1065 {
1066 int x;
1067
1068 if (w->pseudo_window_p)
1069 return 0;
1070
1071 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1072
1073 if (area == TEXT_AREA)
1074 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1075 + window_box_width (w, LEFT_MARGIN_AREA));
1076 else if (area == RIGHT_MARGIN_AREA)
1077 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1078 + window_box_width (w, LEFT_MARGIN_AREA)
1079 + window_box_width (w, TEXT_AREA)
1080 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1081 ? 0
1082 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1083 else if (area == LEFT_MARGIN_AREA
1084 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1085 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1086
1087 return x;
1088 }
1089
1090
1091 /* Return the window-relative coordinate of the right edge of display
1092 area AREA of window W. AREA < 0 means return the left edge of the
1093 whole window, to the left of the right fringe of W. */
1094
1095 INLINE int
1096 window_box_right_offset (w, area)
1097 struct window *w;
1098 int area;
1099 {
1100 return window_box_left_offset (w, area) + window_box_width (w, area);
1101 }
1102
1103 /* Return the frame-relative coordinate of the left edge of display
1104 area AREA of window W. AREA < 0 means return the left edge of the
1105 whole window, to the right of the left fringe of W. */
1106
1107 INLINE int
1108 window_box_left (w, area)
1109 struct window *w;
1110 int area;
1111 {
1112 struct frame *f = XFRAME (w->frame);
1113 int x;
1114
1115 if (w->pseudo_window_p)
1116 return FRAME_INTERNAL_BORDER_WIDTH (f);
1117
1118 x = (WINDOW_LEFT_EDGE_X (w)
1119 + window_box_left_offset (w, area));
1120
1121 return x;
1122 }
1123
1124
1125 /* Return the frame-relative coordinate of the right edge of display
1126 area AREA of window W. AREA < 0 means return the left edge of the
1127 whole window, to the left of the right fringe of W. */
1128
1129 INLINE int
1130 window_box_right (w, area)
1131 struct window *w;
1132 int area;
1133 {
1134 return window_box_left (w, area) + window_box_width (w, area);
1135 }
1136
1137 /* Get the bounding box of the display area AREA of window W, without
1138 mode lines, in frame-relative coordinates. AREA < 0 means the
1139 whole window, not including the left and right fringes of
1140 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1141 coordinates of the upper-left corner of the box. Return in
1142 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1143
1144 INLINE void
1145 window_box (w, area, box_x, box_y, box_width, box_height)
1146 struct window *w;
1147 int area;
1148 int *box_x, *box_y, *box_width, *box_height;
1149 {
1150 if (box_width)
1151 *box_width = window_box_width (w, area);
1152 if (box_height)
1153 *box_height = window_box_height (w);
1154 if (box_x)
1155 *box_x = window_box_left (w, area);
1156 if (box_y)
1157 {
1158 *box_y = WINDOW_TOP_EDGE_Y (w);
1159 if (WINDOW_WANTS_HEADER_LINE_P (w))
1160 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1161 }
1162 }
1163
1164
1165 /* Get the bounding box of the display area AREA of window W, without
1166 mode lines. AREA < 0 means the whole window, not including the
1167 left and right fringe of the window. Return in *TOP_LEFT_X
1168 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1169 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1170 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1171 box. */
1172
1173 INLINE void
1174 window_box_edges (w, area, top_left_x, top_left_y,
1175 bottom_right_x, bottom_right_y)
1176 struct window *w;
1177 int area;
1178 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1179 {
1180 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1181 bottom_right_y);
1182 *bottom_right_x += *top_left_x;
1183 *bottom_right_y += *top_left_y;
1184 }
1185
1186
1187 \f
1188 /***********************************************************************
1189 Utilities
1190 ***********************************************************************/
1191
1192 /* Return the bottom y-position of the line the iterator IT is in.
1193 This can modify IT's settings. */
1194
1195 int
1196 line_bottom_y (it)
1197 struct it *it;
1198 {
1199 int line_height = it->max_ascent + it->max_descent;
1200 int line_top_y = it->current_y;
1201
1202 if (line_height == 0)
1203 {
1204 if (last_height)
1205 line_height = last_height;
1206 else if (IT_CHARPOS (*it) < ZV)
1207 {
1208 move_it_by_lines (it, 1, 1);
1209 line_height = (it->max_ascent || it->max_descent
1210 ? it->max_ascent + it->max_descent
1211 : last_height);
1212 }
1213 else
1214 {
1215 struct glyph_row *row = it->glyph_row;
1216
1217 /* Use the default character height. */
1218 it->glyph_row = NULL;
1219 it->what = IT_CHARACTER;
1220 it->c = ' ';
1221 it->len = 1;
1222 PRODUCE_GLYPHS (it);
1223 line_height = it->ascent + it->descent;
1224 it->glyph_row = row;
1225 }
1226 }
1227
1228 return line_top_y + line_height;
1229 }
1230
1231
1232 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1233 1 if POS is visible and the line containing POS is fully visible.
1234 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1235 and header-lines heights. */
1236
1237 int
1238 pos_visible_p (w, charpos, fully, x, y, exact_mode_line_heights_p)
1239 struct window *w;
1240 int charpos, *fully, *x, *y, exact_mode_line_heights_p;
1241 {
1242 struct it it;
1243 struct text_pos top;
1244 int visible_p;
1245 struct buffer *old_buffer = NULL;
1246
1247 if (XBUFFER (w->buffer) != current_buffer)
1248 {
1249 old_buffer = current_buffer;
1250 set_buffer_internal_1 (XBUFFER (w->buffer));
1251 }
1252
1253 *fully = visible_p = 0;
1254 SET_TEXT_POS_FROM_MARKER (top, w->start);
1255
1256 /* Compute exact mode line heights, if requested. */
1257 if (exact_mode_line_heights_p)
1258 {
1259 if (WINDOW_WANTS_MODELINE_P (w))
1260 current_mode_line_height
1261 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1262 current_buffer->mode_line_format);
1263
1264 if (WINDOW_WANTS_HEADER_LINE_P (w))
1265 current_header_line_height
1266 = display_mode_line (w, HEADER_LINE_FACE_ID,
1267 current_buffer->header_line_format);
1268 }
1269
1270 start_display (&it, w, top);
1271 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1272 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1273
1274 /* Note that we may overshoot because of invisible text. */
1275 if (IT_CHARPOS (it) >= charpos)
1276 {
1277 int top_y = it.current_y;
1278 int bottom_y = line_bottom_y (&it);
1279 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1280
1281 if (top_y < window_top_y)
1282 visible_p = bottom_y > window_top_y;
1283 else if (top_y < it.last_visible_y)
1284 {
1285 visible_p = 1;
1286 *fully = bottom_y <= it.last_visible_y;
1287 }
1288 if (visible_p && x)
1289 {
1290 *x = it.current_x;
1291 *y = max (top_y + it.max_ascent - it.ascent, window_top_y);
1292 }
1293 }
1294 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1295 {
1296 struct it it2;
1297
1298 it2 = it;
1299 move_it_by_lines (&it, 1, 0);
1300 if (charpos < IT_CHARPOS (it))
1301 {
1302 visible_p = 1;
1303 if (x)
1304 {
1305 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1306 *x = it2.current_x;
1307 *y = it2.current_y + it2.max_ascent - it2.ascent;
1308 }
1309 }
1310 }
1311
1312 if (old_buffer)
1313 set_buffer_internal_1 (old_buffer);
1314
1315 current_header_line_height = current_mode_line_height = -1;
1316
1317 return visible_p;
1318 }
1319
1320
1321 /* Return the next character from STR which is MAXLEN bytes long.
1322 Return in *LEN the length of the character. This is like
1323 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1324 we find one, we return a `?', but with the length of the invalid
1325 character. */
1326
1327 static INLINE int
1328 string_char_and_length (str, maxlen, len)
1329 const unsigned char *str;
1330 int maxlen, *len;
1331 {
1332 int c;
1333
1334 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1335 if (!CHAR_VALID_P (c, 1))
1336 /* We may not change the length here because other places in Emacs
1337 don't use this function, i.e. they silently accept invalid
1338 characters. */
1339 c = '?';
1340
1341 return c;
1342 }
1343
1344
1345
1346 /* Given a position POS containing a valid character and byte position
1347 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1348
1349 static struct text_pos
1350 string_pos_nchars_ahead (pos, string, nchars)
1351 struct text_pos pos;
1352 Lisp_Object string;
1353 int nchars;
1354 {
1355 xassert (STRINGP (string) && nchars >= 0);
1356
1357 if (STRING_MULTIBYTE (string))
1358 {
1359 int rest = SBYTES (string) - BYTEPOS (pos);
1360 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1361 int len;
1362
1363 while (nchars--)
1364 {
1365 string_char_and_length (p, rest, &len);
1366 p += len, rest -= len;
1367 xassert (rest >= 0);
1368 CHARPOS (pos) += 1;
1369 BYTEPOS (pos) += len;
1370 }
1371 }
1372 else
1373 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1374
1375 return pos;
1376 }
1377
1378
1379 /* Value is the text position, i.e. character and byte position,
1380 for character position CHARPOS in STRING. */
1381
1382 static INLINE struct text_pos
1383 string_pos (charpos, string)
1384 int charpos;
1385 Lisp_Object string;
1386 {
1387 struct text_pos pos;
1388 xassert (STRINGP (string));
1389 xassert (charpos >= 0);
1390 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1391 return pos;
1392 }
1393
1394
1395 /* Value is a text position, i.e. character and byte position, for
1396 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1397 means recognize multibyte characters. */
1398
1399 static struct text_pos
1400 c_string_pos (charpos, s, multibyte_p)
1401 int charpos;
1402 unsigned char *s;
1403 int multibyte_p;
1404 {
1405 struct text_pos pos;
1406
1407 xassert (s != NULL);
1408 xassert (charpos >= 0);
1409
1410 if (multibyte_p)
1411 {
1412 int rest = strlen (s), len;
1413
1414 SET_TEXT_POS (pos, 0, 0);
1415 while (charpos--)
1416 {
1417 string_char_and_length (s, rest, &len);
1418 s += len, rest -= len;
1419 xassert (rest >= 0);
1420 CHARPOS (pos) += 1;
1421 BYTEPOS (pos) += len;
1422 }
1423 }
1424 else
1425 SET_TEXT_POS (pos, charpos, charpos);
1426
1427 return pos;
1428 }
1429
1430
1431 /* Value is the number of characters in C string S. MULTIBYTE_P
1432 non-zero means recognize multibyte characters. */
1433
1434 static int
1435 number_of_chars (s, multibyte_p)
1436 unsigned char *s;
1437 int multibyte_p;
1438 {
1439 int nchars;
1440
1441 if (multibyte_p)
1442 {
1443 int rest = strlen (s), len;
1444 unsigned char *p = (unsigned char *) s;
1445
1446 for (nchars = 0; rest > 0; ++nchars)
1447 {
1448 string_char_and_length (p, rest, &len);
1449 rest -= len, p += len;
1450 }
1451 }
1452 else
1453 nchars = strlen (s);
1454
1455 return nchars;
1456 }
1457
1458
1459 /* Compute byte position NEWPOS->bytepos corresponding to
1460 NEWPOS->charpos. POS is a known position in string STRING.
1461 NEWPOS->charpos must be >= POS.charpos. */
1462
1463 static void
1464 compute_string_pos (newpos, pos, string)
1465 struct text_pos *newpos, pos;
1466 Lisp_Object string;
1467 {
1468 xassert (STRINGP (string));
1469 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1470
1471 if (STRING_MULTIBYTE (string))
1472 *newpos = string_pos_nchars_ahead (pos, string,
1473 CHARPOS (*newpos) - CHARPOS (pos));
1474 else
1475 BYTEPOS (*newpos) = CHARPOS (*newpos);
1476 }
1477
1478 /* EXPORT:
1479 Return an estimation of the pixel height of mode or top lines on
1480 frame F. FACE_ID specifies what line's height to estimate. */
1481
1482 int
1483 estimate_mode_line_height (f, face_id)
1484 struct frame *f;
1485 enum face_id face_id;
1486 {
1487 #ifdef HAVE_WINDOW_SYSTEM
1488 if (FRAME_WINDOW_P (f))
1489 {
1490 int height = FONT_HEIGHT (FRAME_FONT (f));
1491
1492 /* This function is called so early when Emacs starts that the face
1493 cache and mode line face are not yet initialized. */
1494 if (FRAME_FACE_CACHE (f))
1495 {
1496 struct face *face = FACE_FROM_ID (f, face_id);
1497 if (face)
1498 {
1499 if (face->font)
1500 height = FONT_HEIGHT (face->font);
1501 if (face->box_line_width > 0)
1502 height += 2 * face->box_line_width;
1503 }
1504 }
1505
1506 return height;
1507 }
1508 #endif
1509
1510 return 1;
1511 }
1512
1513 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1514 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1515 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1516 not force the value into range. */
1517
1518 void
1519 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1520 FRAME_PTR f;
1521 register int pix_x, pix_y;
1522 int *x, *y;
1523 NativeRectangle *bounds;
1524 int noclip;
1525 {
1526
1527 #ifdef HAVE_WINDOW_SYSTEM
1528 if (FRAME_WINDOW_P (f))
1529 {
1530 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1531 even for negative values. */
1532 if (pix_x < 0)
1533 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1534 if (pix_y < 0)
1535 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1536
1537 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1538 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1539
1540 if (bounds)
1541 STORE_NATIVE_RECT (*bounds,
1542 FRAME_COL_TO_PIXEL_X (f, pix_x),
1543 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1544 FRAME_COLUMN_WIDTH (f) - 1,
1545 FRAME_LINE_HEIGHT (f) - 1);
1546
1547 if (!noclip)
1548 {
1549 if (pix_x < 0)
1550 pix_x = 0;
1551 else if (pix_x > FRAME_TOTAL_COLS (f))
1552 pix_x = FRAME_TOTAL_COLS (f);
1553
1554 if (pix_y < 0)
1555 pix_y = 0;
1556 else if (pix_y > FRAME_LINES (f))
1557 pix_y = FRAME_LINES (f);
1558 }
1559 }
1560 #endif
1561
1562 *x = pix_x;
1563 *y = pix_y;
1564 }
1565
1566
1567 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1568 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1569 can't tell the positions because W's display is not up to date,
1570 return 0. */
1571
1572 int
1573 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1574 struct window *w;
1575 int hpos, vpos;
1576 int *frame_x, *frame_y;
1577 {
1578 #ifdef HAVE_WINDOW_SYSTEM
1579 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1580 {
1581 int success_p;
1582
1583 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1584 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1585
1586 if (display_completed)
1587 {
1588 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1589 struct glyph *glyph = row->glyphs[TEXT_AREA];
1590 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1591
1592 hpos = row->x;
1593 vpos = row->y;
1594 while (glyph < end)
1595 {
1596 hpos += glyph->pixel_width;
1597 ++glyph;
1598 }
1599
1600 /* If first glyph is partially visible, its first visible position is still 0. */
1601 if (hpos < 0)
1602 hpos = 0;
1603
1604 success_p = 1;
1605 }
1606 else
1607 {
1608 hpos = vpos = 0;
1609 success_p = 0;
1610 }
1611
1612 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1613 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1614 return success_p;
1615 }
1616 #endif
1617
1618 *frame_x = hpos;
1619 *frame_y = vpos;
1620 return 1;
1621 }
1622
1623
1624 #ifdef HAVE_WINDOW_SYSTEM
1625
1626 /* Find the glyph under window-relative coordinates X/Y in window W.
1627 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1628 strings. Return in *HPOS and *VPOS the row and column number of
1629 the glyph found. Return in *AREA the glyph area containing X.
1630 Value is a pointer to the glyph found or null if X/Y is not on
1631 text, or we can't tell because W's current matrix is not up to
1632 date. */
1633
1634 static struct glyph *
1635 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1636 struct window *w;
1637 int x, y;
1638 int *hpos, *vpos, *dx, *dy, *area;
1639 {
1640 struct glyph *glyph, *end;
1641 struct glyph_row *row = NULL;
1642 int x0, i;
1643
1644 /* Find row containing Y. Give up if some row is not enabled. */
1645 for (i = 0; i < w->current_matrix->nrows; ++i)
1646 {
1647 row = MATRIX_ROW (w->current_matrix, i);
1648 if (!row->enabled_p)
1649 return NULL;
1650 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1651 break;
1652 }
1653
1654 *vpos = i;
1655 *hpos = 0;
1656
1657 /* Give up if Y is not in the window. */
1658 if (i == w->current_matrix->nrows)
1659 return NULL;
1660
1661 /* Get the glyph area containing X. */
1662 if (w->pseudo_window_p)
1663 {
1664 *area = TEXT_AREA;
1665 x0 = 0;
1666 }
1667 else
1668 {
1669 if (x < window_box_left_offset (w, TEXT_AREA))
1670 {
1671 *area = LEFT_MARGIN_AREA;
1672 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1673 }
1674 else if (x < window_box_right_offset (w, TEXT_AREA))
1675 {
1676 *area = TEXT_AREA;
1677 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1678 }
1679 else
1680 {
1681 *area = RIGHT_MARGIN_AREA;
1682 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1683 }
1684 }
1685
1686 /* Find glyph containing X. */
1687 glyph = row->glyphs[*area];
1688 end = glyph + row->used[*area];
1689 x -= x0;
1690 while (glyph < end && x >= glyph->pixel_width)
1691 {
1692 x -= glyph->pixel_width;
1693 ++glyph;
1694 }
1695
1696 if (glyph == end)
1697 return NULL;
1698
1699 if (dx)
1700 {
1701 *dx = x;
1702 *dy = y - (row->y + row->ascent - glyph->ascent);
1703 }
1704
1705 *hpos = glyph - row->glyphs[*area];
1706 return glyph;
1707 }
1708
1709
1710 /* EXPORT:
1711 Convert frame-relative x/y to coordinates relative to window W.
1712 Takes pseudo-windows into account. */
1713
1714 void
1715 frame_to_window_pixel_xy (w, x, y)
1716 struct window *w;
1717 int *x, *y;
1718 {
1719 if (w->pseudo_window_p)
1720 {
1721 /* A pseudo-window is always full-width, and starts at the
1722 left edge of the frame, plus a frame border. */
1723 struct frame *f = XFRAME (w->frame);
1724 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1725 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1726 }
1727 else
1728 {
1729 *x -= WINDOW_LEFT_EDGE_X (w);
1730 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1731 }
1732 }
1733
1734 /* EXPORT:
1735 Return in *R the clipping rectangle for glyph string S. */
1736
1737 void
1738 get_glyph_string_clip_rect (s, nr)
1739 struct glyph_string *s;
1740 NativeRectangle *nr;
1741 {
1742 XRectangle r;
1743
1744 if (s->row->full_width_p)
1745 {
1746 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1747 r.x = WINDOW_LEFT_EDGE_X (s->w);
1748 r.width = WINDOW_TOTAL_WIDTH (s->w);
1749
1750 /* Unless displaying a mode or menu bar line, which are always
1751 fully visible, clip to the visible part of the row. */
1752 if (s->w->pseudo_window_p)
1753 r.height = s->row->visible_height;
1754 else
1755 r.height = s->height;
1756 }
1757 else
1758 {
1759 /* This is a text line that may be partially visible. */
1760 r.x = window_box_left (s->w, s->area);
1761 r.width = window_box_width (s->w, s->area);
1762 r.height = s->row->visible_height;
1763 }
1764
1765 /* If S draws overlapping rows, it's sufficient to use the top and
1766 bottom of the window for clipping because this glyph string
1767 intentionally draws over other lines. */
1768 if (s->for_overlaps_p)
1769 {
1770 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1771 r.height = window_text_bottom_y (s->w) - r.y;
1772 }
1773 else
1774 {
1775 /* Don't use S->y for clipping because it doesn't take partially
1776 visible lines into account. For example, it can be negative for
1777 partially visible lines at the top of a window. */
1778 if (!s->row->full_width_p
1779 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1780 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1781 else
1782 r.y = max (0, s->row->y);
1783
1784 /* If drawing a tool-bar window, draw it over the internal border
1785 at the top of the window. */
1786 if (s->w == XWINDOW (s->f->tool_bar_window))
1787 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1788 }
1789
1790 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1791
1792 /* If drawing the cursor, don't let glyph draw outside its
1793 advertised boundaries. Cleartype does this under some circumstances. */
1794 if (s->hl == DRAW_CURSOR)
1795 {
1796 struct glyph *glyph = s->first_glyph;
1797 int height;
1798
1799 if (s->x > r.x)
1800 {
1801 r.width -= s->x - r.x;
1802 r.x = s->x;
1803 }
1804 r.width = min (r.width, glyph->pixel_width);
1805
1806 /* Don't draw cursor glyph taller than our actual glyph. */
1807 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1808 if (height < r.height)
1809 {
1810 int max_y = r.y + r.height;
1811 r.y = min (max_y, s->ybase + glyph->descent - height);
1812 r.height = min (max_y - r.y, height);
1813 }
1814 }
1815
1816 #ifdef CONVERT_FROM_XRECT
1817 CONVERT_FROM_XRECT (r, *nr);
1818 #else
1819 *nr = r;
1820 #endif
1821 }
1822
1823 #endif /* HAVE_WINDOW_SYSTEM */
1824
1825 \f
1826 /***********************************************************************
1827 Lisp form evaluation
1828 ***********************************************************************/
1829
1830 /* Error handler for safe_eval and safe_call. */
1831
1832 static Lisp_Object
1833 safe_eval_handler (arg)
1834 Lisp_Object arg;
1835 {
1836 add_to_log ("Error during redisplay: %s", arg, Qnil);
1837 return Qnil;
1838 }
1839
1840
1841 /* Evaluate SEXPR and return the result, or nil if something went
1842 wrong. Prevent redisplay during the evaluation. */
1843
1844 Lisp_Object
1845 safe_eval (sexpr)
1846 Lisp_Object sexpr;
1847 {
1848 Lisp_Object val;
1849
1850 if (inhibit_eval_during_redisplay)
1851 val = Qnil;
1852 else
1853 {
1854 int count = SPECPDL_INDEX ();
1855 struct gcpro gcpro1;
1856
1857 GCPRO1 (sexpr);
1858 specbind (Qinhibit_redisplay, Qt);
1859 /* Use Qt to ensure debugger does not run,
1860 so there is no possibility of wanting to redisplay. */
1861 val = internal_condition_case_1 (Feval, sexpr, Qt,
1862 safe_eval_handler);
1863 UNGCPRO;
1864 val = unbind_to (count, val);
1865 }
1866
1867 return val;
1868 }
1869
1870
1871 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1872 Return the result, or nil if something went wrong. Prevent
1873 redisplay during the evaluation. */
1874
1875 Lisp_Object
1876 safe_call (nargs, args)
1877 int nargs;
1878 Lisp_Object *args;
1879 {
1880 Lisp_Object val;
1881
1882 if (inhibit_eval_during_redisplay)
1883 val = Qnil;
1884 else
1885 {
1886 int count = SPECPDL_INDEX ();
1887 struct gcpro gcpro1;
1888
1889 GCPRO1 (args[0]);
1890 gcpro1.nvars = nargs;
1891 specbind (Qinhibit_redisplay, Qt);
1892 /* Use Qt to ensure debugger does not run,
1893 so there is no possibility of wanting to redisplay. */
1894 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1895 safe_eval_handler);
1896 UNGCPRO;
1897 val = unbind_to (count, val);
1898 }
1899
1900 return val;
1901 }
1902
1903
1904 /* Call function FN with one argument ARG.
1905 Return the result, or nil if something went wrong. */
1906
1907 Lisp_Object
1908 safe_call1 (fn, arg)
1909 Lisp_Object fn, arg;
1910 {
1911 Lisp_Object args[2];
1912 args[0] = fn;
1913 args[1] = arg;
1914 return safe_call (2, args);
1915 }
1916
1917
1918 \f
1919 /***********************************************************************
1920 Debugging
1921 ***********************************************************************/
1922
1923 #if 0
1924
1925 /* Define CHECK_IT to perform sanity checks on iterators.
1926 This is for debugging. It is too slow to do unconditionally. */
1927
1928 static void
1929 check_it (it)
1930 struct it *it;
1931 {
1932 if (it->method == next_element_from_string)
1933 {
1934 xassert (STRINGP (it->string));
1935 xassert (IT_STRING_CHARPOS (*it) >= 0);
1936 }
1937 else
1938 {
1939 xassert (IT_STRING_CHARPOS (*it) < 0);
1940 if (it->method == next_element_from_buffer)
1941 {
1942 /* Check that character and byte positions agree. */
1943 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1944 }
1945 }
1946
1947 if (it->dpvec)
1948 xassert (it->current.dpvec_index >= 0);
1949 else
1950 xassert (it->current.dpvec_index < 0);
1951 }
1952
1953 #define CHECK_IT(IT) check_it ((IT))
1954
1955 #else /* not 0 */
1956
1957 #define CHECK_IT(IT) (void) 0
1958
1959 #endif /* not 0 */
1960
1961
1962 #if GLYPH_DEBUG
1963
1964 /* Check that the window end of window W is what we expect it
1965 to be---the last row in the current matrix displaying text. */
1966
1967 static void
1968 check_window_end (w)
1969 struct window *w;
1970 {
1971 if (!MINI_WINDOW_P (w)
1972 && !NILP (w->window_end_valid))
1973 {
1974 struct glyph_row *row;
1975 xassert ((row = MATRIX_ROW (w->current_matrix,
1976 XFASTINT (w->window_end_vpos)),
1977 !row->enabled_p
1978 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1979 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1980 }
1981 }
1982
1983 #define CHECK_WINDOW_END(W) check_window_end ((W))
1984
1985 #else /* not GLYPH_DEBUG */
1986
1987 #define CHECK_WINDOW_END(W) (void) 0
1988
1989 #endif /* not GLYPH_DEBUG */
1990
1991
1992 \f
1993 /***********************************************************************
1994 Iterator initialization
1995 ***********************************************************************/
1996
1997 /* Initialize IT for displaying current_buffer in window W, starting
1998 at character position CHARPOS. CHARPOS < 0 means that no buffer
1999 position is specified which is useful when the iterator is assigned
2000 a position later. BYTEPOS is the byte position corresponding to
2001 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2002
2003 If ROW is not null, calls to produce_glyphs with IT as parameter
2004 will produce glyphs in that row.
2005
2006 BASE_FACE_ID is the id of a base face to use. It must be one of
2007 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2008 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2009 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2010
2011 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2012 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2013 will be initialized to use the corresponding mode line glyph row of
2014 the desired matrix of W. */
2015
2016 void
2017 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2018 struct it *it;
2019 struct window *w;
2020 int charpos, bytepos;
2021 struct glyph_row *row;
2022 enum face_id base_face_id;
2023 {
2024 int highlight_region_p;
2025
2026 /* Some precondition checks. */
2027 xassert (w != NULL && it != NULL);
2028 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2029 && charpos <= ZV));
2030
2031 /* If face attributes have been changed since the last redisplay,
2032 free realized faces now because they depend on face definitions
2033 that might have changed. Don't free faces while there might be
2034 desired matrices pending which reference these faces. */
2035 if (face_change_count && !inhibit_free_realized_faces)
2036 {
2037 face_change_count = 0;
2038 free_all_realized_faces (Qnil);
2039 }
2040
2041 /* Use one of the mode line rows of W's desired matrix if
2042 appropriate. */
2043 if (row == NULL)
2044 {
2045 if (base_face_id == MODE_LINE_FACE_ID
2046 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2047 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2048 else if (base_face_id == HEADER_LINE_FACE_ID)
2049 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2050 }
2051
2052 /* Clear IT. */
2053 bzero (it, sizeof *it);
2054 it->current.overlay_string_index = -1;
2055 it->current.dpvec_index = -1;
2056 it->base_face_id = base_face_id;
2057 it->string = Qnil;
2058 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2059
2060 /* The window in which we iterate over current_buffer: */
2061 XSETWINDOW (it->window, w);
2062 it->w = w;
2063 it->f = XFRAME (w->frame);
2064
2065 /* Extra space between lines (on window systems only). */
2066 if (base_face_id == DEFAULT_FACE_ID
2067 && FRAME_WINDOW_P (it->f))
2068 {
2069 if (NATNUMP (current_buffer->extra_line_spacing))
2070 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2071 else if (FLOATP (current_buffer->extra_line_spacing))
2072 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2073 * FRAME_LINE_HEIGHT (it->f));
2074 else if (it->f->extra_line_spacing > 0)
2075 it->extra_line_spacing = it->f->extra_line_spacing;
2076 }
2077
2078 /* If realized faces have been removed, e.g. because of face
2079 attribute changes of named faces, recompute them. When running
2080 in batch mode, the face cache of Vterminal_frame is null. If
2081 we happen to get called, make a dummy face cache. */
2082 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2083 init_frame_faces (it->f);
2084 if (FRAME_FACE_CACHE (it->f)->used == 0)
2085 recompute_basic_faces (it->f);
2086
2087 /* Current value of the `slice', `space-width', and 'height' properties. */
2088 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2089 it->space_width = Qnil;
2090 it->font_height = Qnil;
2091 it->override_ascent = -1;
2092
2093 /* Are control characters displayed as `^C'? */
2094 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2095
2096 /* -1 means everything between a CR and the following line end
2097 is invisible. >0 means lines indented more than this value are
2098 invisible. */
2099 it->selective = (INTEGERP (current_buffer->selective_display)
2100 ? XFASTINT (current_buffer->selective_display)
2101 : (!NILP (current_buffer->selective_display)
2102 ? -1 : 0));
2103 it->selective_display_ellipsis_p
2104 = !NILP (current_buffer->selective_display_ellipses);
2105
2106 /* Display table to use. */
2107 it->dp = window_display_table (w);
2108
2109 /* Are multibyte characters enabled in current_buffer? */
2110 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2111
2112 /* Non-zero if we should highlight the region. */
2113 highlight_region_p
2114 = (!NILP (Vtransient_mark_mode)
2115 && !NILP (current_buffer->mark_active)
2116 && XMARKER (current_buffer->mark)->buffer != 0);
2117
2118 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2119 start and end of a visible region in window IT->w. Set both to
2120 -1 to indicate no region. */
2121 if (highlight_region_p
2122 /* Maybe highlight only in selected window. */
2123 && (/* Either show region everywhere. */
2124 highlight_nonselected_windows
2125 /* Or show region in the selected window. */
2126 || w == XWINDOW (selected_window)
2127 /* Or show the region if we are in the mini-buffer and W is
2128 the window the mini-buffer refers to. */
2129 || (MINI_WINDOW_P (XWINDOW (selected_window))
2130 && WINDOWP (minibuf_selected_window)
2131 && w == XWINDOW (minibuf_selected_window))))
2132 {
2133 int charpos = marker_position (current_buffer->mark);
2134 it->region_beg_charpos = min (PT, charpos);
2135 it->region_end_charpos = max (PT, charpos);
2136 }
2137 else
2138 it->region_beg_charpos = it->region_end_charpos = -1;
2139
2140 /* Get the position at which the redisplay_end_trigger hook should
2141 be run, if it is to be run at all. */
2142 if (MARKERP (w->redisplay_end_trigger)
2143 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2144 it->redisplay_end_trigger_charpos
2145 = marker_position (w->redisplay_end_trigger);
2146 else if (INTEGERP (w->redisplay_end_trigger))
2147 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2148
2149 /* Correct bogus values of tab_width. */
2150 it->tab_width = XINT (current_buffer->tab_width);
2151 if (it->tab_width <= 0 || it->tab_width > 1000)
2152 it->tab_width = 8;
2153
2154 /* Are lines in the display truncated? */
2155 it->truncate_lines_p
2156 = (base_face_id != DEFAULT_FACE_ID
2157 || XINT (it->w->hscroll)
2158 || (truncate_partial_width_windows
2159 && !WINDOW_FULL_WIDTH_P (it->w))
2160 || !NILP (current_buffer->truncate_lines));
2161
2162 /* Get dimensions of truncation and continuation glyphs. These are
2163 displayed as fringe bitmaps under X, so we don't need them for such
2164 frames. */
2165 if (!FRAME_WINDOW_P (it->f))
2166 {
2167 if (it->truncate_lines_p)
2168 {
2169 /* We will need the truncation glyph. */
2170 xassert (it->glyph_row == NULL);
2171 produce_special_glyphs (it, IT_TRUNCATION);
2172 it->truncation_pixel_width = it->pixel_width;
2173 }
2174 else
2175 {
2176 /* We will need the continuation glyph. */
2177 xassert (it->glyph_row == NULL);
2178 produce_special_glyphs (it, IT_CONTINUATION);
2179 it->continuation_pixel_width = it->pixel_width;
2180 }
2181
2182 /* Reset these values to zero because the produce_special_glyphs
2183 above has changed them. */
2184 it->pixel_width = it->ascent = it->descent = 0;
2185 it->phys_ascent = it->phys_descent = 0;
2186 }
2187
2188 /* Set this after getting the dimensions of truncation and
2189 continuation glyphs, so that we don't produce glyphs when calling
2190 produce_special_glyphs, above. */
2191 it->glyph_row = row;
2192 it->area = TEXT_AREA;
2193
2194 /* Get the dimensions of the display area. The display area
2195 consists of the visible window area plus a horizontally scrolled
2196 part to the left of the window. All x-values are relative to the
2197 start of this total display area. */
2198 if (base_face_id != DEFAULT_FACE_ID)
2199 {
2200 /* Mode lines, menu bar in terminal frames. */
2201 it->first_visible_x = 0;
2202 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2203 }
2204 else
2205 {
2206 it->first_visible_x
2207 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2208 it->last_visible_x = (it->first_visible_x
2209 + window_box_width (w, TEXT_AREA));
2210
2211 /* If we truncate lines, leave room for the truncator glyph(s) at
2212 the right margin. Otherwise, leave room for the continuation
2213 glyph(s). Truncation and continuation glyphs are not inserted
2214 for window-based redisplay. */
2215 if (!FRAME_WINDOW_P (it->f))
2216 {
2217 if (it->truncate_lines_p)
2218 it->last_visible_x -= it->truncation_pixel_width;
2219 else
2220 it->last_visible_x -= it->continuation_pixel_width;
2221 }
2222
2223 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2224 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2225 }
2226
2227 /* Leave room for a border glyph. */
2228 if (!FRAME_WINDOW_P (it->f)
2229 && !WINDOW_RIGHTMOST_P (it->w))
2230 it->last_visible_x -= 1;
2231
2232 it->last_visible_y = window_text_bottom_y (w);
2233
2234 /* For mode lines and alike, arrange for the first glyph having a
2235 left box line if the face specifies a box. */
2236 if (base_face_id != DEFAULT_FACE_ID)
2237 {
2238 struct face *face;
2239
2240 it->face_id = base_face_id;
2241
2242 /* If we have a boxed mode line, make the first character appear
2243 with a left box line. */
2244 face = FACE_FROM_ID (it->f, base_face_id);
2245 if (face->box != FACE_NO_BOX)
2246 it->start_of_box_run_p = 1;
2247 }
2248
2249 /* If a buffer position was specified, set the iterator there,
2250 getting overlays and face properties from that position. */
2251 if (charpos >= BUF_BEG (current_buffer))
2252 {
2253 it->end_charpos = ZV;
2254 it->face_id = -1;
2255 IT_CHARPOS (*it) = charpos;
2256
2257 /* Compute byte position if not specified. */
2258 if (bytepos < charpos)
2259 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2260 else
2261 IT_BYTEPOS (*it) = bytepos;
2262
2263 it->start = it->current;
2264
2265 /* Compute faces etc. */
2266 reseat (it, it->current.pos, 1);
2267 }
2268
2269 CHECK_IT (it);
2270 }
2271
2272
2273 /* Initialize IT for the display of window W with window start POS. */
2274
2275 void
2276 start_display (it, w, pos)
2277 struct it *it;
2278 struct window *w;
2279 struct text_pos pos;
2280 {
2281 struct glyph_row *row;
2282 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2283
2284 row = w->desired_matrix->rows + first_vpos;
2285 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2286 it->first_vpos = first_vpos;
2287
2288 if (!it->truncate_lines_p)
2289 {
2290 int start_at_line_beg_p;
2291 int first_y = it->current_y;
2292
2293 /* If window start is not at a line start, skip forward to POS to
2294 get the correct continuation lines width. */
2295 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2296 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2297 if (!start_at_line_beg_p)
2298 {
2299 int new_x;
2300
2301 reseat_at_previous_visible_line_start (it);
2302 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2303
2304 new_x = it->current_x + it->pixel_width;
2305
2306 /* If lines are continued, this line may end in the middle
2307 of a multi-glyph character (e.g. a control character
2308 displayed as \003, or in the middle of an overlay
2309 string). In this case move_it_to above will not have
2310 taken us to the start of the continuation line but to the
2311 end of the continued line. */
2312 if (it->current_x > 0
2313 && !it->truncate_lines_p /* Lines are continued. */
2314 && (/* And glyph doesn't fit on the line. */
2315 new_x > it->last_visible_x
2316 /* Or it fits exactly and we're on a window
2317 system frame. */
2318 || (new_x == it->last_visible_x
2319 && FRAME_WINDOW_P (it->f))))
2320 {
2321 if (it->current.dpvec_index >= 0
2322 || it->current.overlay_string_index >= 0)
2323 {
2324 set_iterator_to_next (it, 1);
2325 move_it_in_display_line_to (it, -1, -1, 0);
2326 }
2327
2328 it->continuation_lines_width += it->current_x;
2329 }
2330
2331 /* We're starting a new display line, not affected by the
2332 height of the continued line, so clear the appropriate
2333 fields in the iterator structure. */
2334 it->max_ascent = it->max_descent = 0;
2335 it->max_phys_ascent = it->max_phys_descent = 0;
2336
2337 it->current_y = first_y;
2338 it->vpos = 0;
2339 it->current_x = it->hpos = 0;
2340 }
2341 }
2342
2343 #if 0 /* Don't assert the following because start_display is sometimes
2344 called intentionally with a window start that is not at a
2345 line start. Please leave this code in as a comment. */
2346
2347 /* Window start should be on a line start, now. */
2348 xassert (it->continuation_lines_width
2349 || IT_CHARPOS (it) == BEGV
2350 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2351 #endif /* 0 */
2352 }
2353
2354
2355 /* Return 1 if POS is a position in ellipses displayed for invisible
2356 text. W is the window we display, for text property lookup. */
2357
2358 static int
2359 in_ellipses_for_invisible_text_p (pos, w)
2360 struct display_pos *pos;
2361 struct window *w;
2362 {
2363 Lisp_Object prop, window;
2364 int ellipses_p = 0;
2365 int charpos = CHARPOS (pos->pos);
2366
2367 /* If POS specifies a position in a display vector, this might
2368 be for an ellipsis displayed for invisible text. We won't
2369 get the iterator set up for delivering that ellipsis unless
2370 we make sure that it gets aware of the invisible text. */
2371 if (pos->dpvec_index >= 0
2372 && pos->overlay_string_index < 0
2373 && CHARPOS (pos->string_pos) < 0
2374 && charpos > BEGV
2375 && (XSETWINDOW (window, w),
2376 prop = Fget_char_property (make_number (charpos),
2377 Qinvisible, window),
2378 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2379 {
2380 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2381 window);
2382 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2383 }
2384
2385 return ellipses_p;
2386 }
2387
2388
2389 /* Initialize IT for stepping through current_buffer in window W,
2390 starting at position POS that includes overlay string and display
2391 vector/ control character translation position information. Value
2392 is zero if there are overlay strings with newlines at POS. */
2393
2394 static int
2395 init_from_display_pos (it, w, pos)
2396 struct it *it;
2397 struct window *w;
2398 struct display_pos *pos;
2399 {
2400 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2401 int i, overlay_strings_with_newlines = 0;
2402
2403 /* If POS specifies a position in a display vector, this might
2404 be for an ellipsis displayed for invisible text. We won't
2405 get the iterator set up for delivering that ellipsis unless
2406 we make sure that it gets aware of the invisible text. */
2407 if (in_ellipses_for_invisible_text_p (pos, w))
2408 {
2409 --charpos;
2410 bytepos = 0;
2411 }
2412
2413 /* Keep in mind: the call to reseat in init_iterator skips invisible
2414 text, so we might end up at a position different from POS. This
2415 is only a problem when POS is a row start after a newline and an
2416 overlay starts there with an after-string, and the overlay has an
2417 invisible property. Since we don't skip invisible text in
2418 display_line and elsewhere immediately after consuming the
2419 newline before the row start, such a POS will not be in a string,
2420 but the call to init_iterator below will move us to the
2421 after-string. */
2422 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2423
2424 for (i = 0; i < it->n_overlay_strings; ++i)
2425 {
2426 const char *s = SDATA (it->overlay_strings[i]);
2427 const char *e = s + SBYTES (it->overlay_strings[i]);
2428
2429 while (s < e && *s != '\n')
2430 ++s;
2431
2432 if (s < e)
2433 {
2434 overlay_strings_with_newlines = 1;
2435 break;
2436 }
2437 }
2438
2439 /* If position is within an overlay string, set up IT to the right
2440 overlay string. */
2441 if (pos->overlay_string_index >= 0)
2442 {
2443 int relative_index;
2444
2445 /* If the first overlay string happens to have a `display'
2446 property for an image, the iterator will be set up for that
2447 image, and we have to undo that setup first before we can
2448 correct the overlay string index. */
2449 if (it->method == next_element_from_image)
2450 pop_it (it);
2451
2452 /* We already have the first chunk of overlay strings in
2453 IT->overlay_strings. Load more until the one for
2454 pos->overlay_string_index is in IT->overlay_strings. */
2455 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2456 {
2457 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2458 it->current.overlay_string_index = 0;
2459 while (n--)
2460 {
2461 load_overlay_strings (it, 0);
2462 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2463 }
2464 }
2465
2466 it->current.overlay_string_index = pos->overlay_string_index;
2467 relative_index = (it->current.overlay_string_index
2468 % OVERLAY_STRING_CHUNK_SIZE);
2469 it->string = it->overlay_strings[relative_index];
2470 xassert (STRINGP (it->string));
2471 it->current.string_pos = pos->string_pos;
2472 it->method = next_element_from_string;
2473 }
2474
2475 #if 0 /* This is bogus because POS not having an overlay string
2476 position does not mean it's after the string. Example: A
2477 line starting with a before-string and initialization of IT
2478 to the previous row's end position. */
2479 else if (it->current.overlay_string_index >= 0)
2480 {
2481 /* If POS says we're already after an overlay string ending at
2482 POS, make sure to pop the iterator because it will be in
2483 front of that overlay string. When POS is ZV, we've thereby
2484 also ``processed'' overlay strings at ZV. */
2485 while (it->sp)
2486 pop_it (it);
2487 it->current.overlay_string_index = -1;
2488 it->method = next_element_from_buffer;
2489 if (CHARPOS (pos->pos) == ZV)
2490 it->overlay_strings_at_end_processed_p = 1;
2491 }
2492 #endif /* 0 */
2493
2494 if (CHARPOS (pos->string_pos) >= 0)
2495 {
2496 /* Recorded position is not in an overlay string, but in another
2497 string. This can only be a string from a `display' property.
2498 IT should already be filled with that string. */
2499 it->current.string_pos = pos->string_pos;
2500 xassert (STRINGP (it->string));
2501 }
2502
2503 /* Restore position in display vector translations, control
2504 character translations or ellipses. */
2505 if (pos->dpvec_index >= 0)
2506 {
2507 if (it->dpvec == NULL)
2508 get_next_display_element (it);
2509 xassert (it->dpvec && it->current.dpvec_index == 0);
2510 it->current.dpvec_index = pos->dpvec_index;
2511 }
2512
2513 CHECK_IT (it);
2514 return !overlay_strings_with_newlines;
2515 }
2516
2517
2518 /* Initialize IT for stepping through current_buffer in window W
2519 starting at ROW->start. */
2520
2521 static void
2522 init_to_row_start (it, w, row)
2523 struct it *it;
2524 struct window *w;
2525 struct glyph_row *row;
2526 {
2527 init_from_display_pos (it, w, &row->start);
2528 it->start = row->start;
2529 it->continuation_lines_width = row->continuation_lines_width;
2530 CHECK_IT (it);
2531 }
2532
2533
2534 /* Initialize IT for stepping through current_buffer in window W
2535 starting in the line following ROW, i.e. starting at ROW->end.
2536 Value is zero if there are overlay strings with newlines at ROW's
2537 end position. */
2538
2539 static int
2540 init_to_row_end (it, w, row)
2541 struct it *it;
2542 struct window *w;
2543 struct glyph_row *row;
2544 {
2545 int success = 0;
2546
2547 if (init_from_display_pos (it, w, &row->end))
2548 {
2549 if (row->continued_p)
2550 it->continuation_lines_width
2551 = row->continuation_lines_width + row->pixel_width;
2552 CHECK_IT (it);
2553 success = 1;
2554 }
2555
2556 return success;
2557 }
2558
2559
2560
2561 \f
2562 /***********************************************************************
2563 Text properties
2564 ***********************************************************************/
2565
2566 /* Called when IT reaches IT->stop_charpos. Handle text property and
2567 overlay changes. Set IT->stop_charpos to the next position where
2568 to stop. */
2569
2570 static void
2571 handle_stop (it)
2572 struct it *it;
2573 {
2574 enum prop_handled handled;
2575 int handle_overlay_change_p = 1;
2576 struct props *p;
2577
2578 it->dpvec = NULL;
2579 it->current.dpvec_index = -1;
2580
2581 do
2582 {
2583 handled = HANDLED_NORMALLY;
2584
2585 /* Call text property handlers. */
2586 for (p = it_props; p->handler; ++p)
2587 {
2588 handled = p->handler (it);
2589
2590 if (handled == HANDLED_RECOMPUTE_PROPS)
2591 break;
2592 else if (handled == HANDLED_RETURN)
2593 return;
2594 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2595 handle_overlay_change_p = 0;
2596 }
2597
2598 if (handled != HANDLED_RECOMPUTE_PROPS)
2599 {
2600 /* Don't check for overlay strings below when set to deliver
2601 characters from a display vector. */
2602 if (it->method == next_element_from_display_vector)
2603 handle_overlay_change_p = 0;
2604
2605 /* Handle overlay changes. */
2606 if (handle_overlay_change_p)
2607 handled = handle_overlay_change (it);
2608
2609 /* Determine where to stop next. */
2610 if (handled == HANDLED_NORMALLY)
2611 compute_stop_pos (it);
2612 }
2613 }
2614 while (handled == HANDLED_RECOMPUTE_PROPS);
2615 }
2616
2617
2618 /* Compute IT->stop_charpos from text property and overlay change
2619 information for IT's current position. */
2620
2621 static void
2622 compute_stop_pos (it)
2623 struct it *it;
2624 {
2625 register INTERVAL iv, next_iv;
2626 Lisp_Object object, limit, position;
2627
2628 /* If nowhere else, stop at the end. */
2629 it->stop_charpos = it->end_charpos;
2630
2631 if (STRINGP (it->string))
2632 {
2633 /* Strings are usually short, so don't limit the search for
2634 properties. */
2635 object = it->string;
2636 limit = Qnil;
2637 position = make_number (IT_STRING_CHARPOS (*it));
2638 }
2639 else
2640 {
2641 int charpos;
2642
2643 /* If next overlay change is in front of the current stop pos
2644 (which is IT->end_charpos), stop there. Note: value of
2645 next_overlay_change is point-max if no overlay change
2646 follows. */
2647 charpos = next_overlay_change (IT_CHARPOS (*it));
2648 if (charpos < it->stop_charpos)
2649 it->stop_charpos = charpos;
2650
2651 /* If showing the region, we have to stop at the region
2652 start or end because the face might change there. */
2653 if (it->region_beg_charpos > 0)
2654 {
2655 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2656 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2657 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2658 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2659 }
2660
2661 /* Set up variables for computing the stop position from text
2662 property changes. */
2663 XSETBUFFER (object, current_buffer);
2664 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2665 position = make_number (IT_CHARPOS (*it));
2666
2667 }
2668
2669 /* Get the interval containing IT's position. Value is a null
2670 interval if there isn't such an interval. */
2671 iv = validate_interval_range (object, &position, &position, 0);
2672 if (!NULL_INTERVAL_P (iv))
2673 {
2674 Lisp_Object values_here[LAST_PROP_IDX];
2675 struct props *p;
2676
2677 /* Get properties here. */
2678 for (p = it_props; p->handler; ++p)
2679 values_here[p->idx] = textget (iv->plist, *p->name);
2680
2681 /* Look for an interval following iv that has different
2682 properties. */
2683 for (next_iv = next_interval (iv);
2684 (!NULL_INTERVAL_P (next_iv)
2685 && (NILP (limit)
2686 || XFASTINT (limit) > next_iv->position));
2687 next_iv = next_interval (next_iv))
2688 {
2689 for (p = it_props; p->handler; ++p)
2690 {
2691 Lisp_Object new_value;
2692
2693 new_value = textget (next_iv->plist, *p->name);
2694 if (!EQ (values_here[p->idx], new_value))
2695 break;
2696 }
2697
2698 if (p->handler)
2699 break;
2700 }
2701
2702 if (!NULL_INTERVAL_P (next_iv))
2703 {
2704 if (INTEGERP (limit)
2705 && next_iv->position >= XFASTINT (limit))
2706 /* No text property change up to limit. */
2707 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2708 else
2709 /* Text properties change in next_iv. */
2710 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2711 }
2712 }
2713
2714 xassert (STRINGP (it->string)
2715 || (it->stop_charpos >= BEGV
2716 && it->stop_charpos >= IT_CHARPOS (*it)));
2717 }
2718
2719
2720 /* Return the position of the next overlay change after POS in
2721 current_buffer. Value is point-max if no overlay change
2722 follows. This is like `next-overlay-change' but doesn't use
2723 xmalloc. */
2724
2725 static int
2726 next_overlay_change (pos)
2727 int pos;
2728 {
2729 int noverlays;
2730 int endpos;
2731 Lisp_Object *overlays;
2732 int i;
2733
2734 /* Get all overlays at the given position. */
2735 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2736
2737 /* If any of these overlays ends before endpos,
2738 use its ending point instead. */
2739 for (i = 0; i < noverlays; ++i)
2740 {
2741 Lisp_Object oend;
2742 int oendpos;
2743
2744 oend = OVERLAY_END (overlays[i]);
2745 oendpos = OVERLAY_POSITION (oend);
2746 endpos = min (endpos, oendpos);
2747 }
2748
2749 return endpos;
2750 }
2751
2752
2753 \f
2754 /***********************************************************************
2755 Fontification
2756 ***********************************************************************/
2757
2758 /* Handle changes in the `fontified' property of the current buffer by
2759 calling hook functions from Qfontification_functions to fontify
2760 regions of text. */
2761
2762 static enum prop_handled
2763 handle_fontified_prop (it)
2764 struct it *it;
2765 {
2766 Lisp_Object prop, pos;
2767 enum prop_handled handled = HANDLED_NORMALLY;
2768
2769 /* Get the value of the `fontified' property at IT's current buffer
2770 position. (The `fontified' property doesn't have a special
2771 meaning in strings.) If the value is nil, call functions from
2772 Qfontification_functions. */
2773 if (!STRINGP (it->string)
2774 && it->s == NULL
2775 && !NILP (Vfontification_functions)
2776 && !NILP (Vrun_hooks)
2777 && (pos = make_number (IT_CHARPOS (*it)),
2778 prop = Fget_char_property (pos, Qfontified, Qnil),
2779 NILP (prop)))
2780 {
2781 int count = SPECPDL_INDEX ();
2782 Lisp_Object val;
2783
2784 val = Vfontification_functions;
2785 specbind (Qfontification_functions, Qnil);
2786
2787 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2788 safe_call1 (val, pos);
2789 else
2790 {
2791 Lisp_Object globals, fn;
2792 struct gcpro gcpro1, gcpro2;
2793
2794 globals = Qnil;
2795 GCPRO2 (val, globals);
2796
2797 for (; CONSP (val); val = XCDR (val))
2798 {
2799 fn = XCAR (val);
2800
2801 if (EQ (fn, Qt))
2802 {
2803 /* A value of t indicates this hook has a local
2804 binding; it means to run the global binding too.
2805 In a global value, t should not occur. If it
2806 does, we must ignore it to avoid an endless
2807 loop. */
2808 for (globals = Fdefault_value (Qfontification_functions);
2809 CONSP (globals);
2810 globals = XCDR (globals))
2811 {
2812 fn = XCAR (globals);
2813 if (!EQ (fn, Qt))
2814 safe_call1 (fn, pos);
2815 }
2816 }
2817 else
2818 safe_call1 (fn, pos);
2819 }
2820
2821 UNGCPRO;
2822 }
2823
2824 unbind_to (count, Qnil);
2825
2826 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2827 something. This avoids an endless loop if they failed to
2828 fontify the text for which reason ever. */
2829 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2830 handled = HANDLED_RECOMPUTE_PROPS;
2831 }
2832
2833 return handled;
2834 }
2835
2836
2837 \f
2838 /***********************************************************************
2839 Faces
2840 ***********************************************************************/
2841
2842 /* Set up iterator IT from face properties at its current position.
2843 Called from handle_stop. */
2844
2845 static enum prop_handled
2846 handle_face_prop (it)
2847 struct it *it;
2848 {
2849 int new_face_id, next_stop;
2850
2851 if (!STRINGP (it->string))
2852 {
2853 new_face_id
2854 = face_at_buffer_position (it->w,
2855 IT_CHARPOS (*it),
2856 it->region_beg_charpos,
2857 it->region_end_charpos,
2858 &next_stop,
2859 (IT_CHARPOS (*it)
2860 + TEXT_PROP_DISTANCE_LIMIT),
2861 0);
2862
2863 /* Is this a start of a run of characters with box face?
2864 Caveat: this can be called for a freshly initialized
2865 iterator; face_id is -1 in this case. We know that the new
2866 face will not change until limit, i.e. if the new face has a
2867 box, all characters up to limit will have one. But, as
2868 usual, we don't know whether limit is really the end. */
2869 if (new_face_id != it->face_id)
2870 {
2871 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2872
2873 /* If new face has a box but old face has not, this is
2874 the start of a run of characters with box, i.e. it has
2875 a shadow on the left side. The value of face_id of the
2876 iterator will be -1 if this is the initial call that gets
2877 the face. In this case, we have to look in front of IT's
2878 position and see whether there is a face != new_face_id. */
2879 it->start_of_box_run_p
2880 = (new_face->box != FACE_NO_BOX
2881 && (it->face_id >= 0
2882 || IT_CHARPOS (*it) == BEG
2883 || new_face_id != face_before_it_pos (it)));
2884 it->face_box_p = new_face->box != FACE_NO_BOX;
2885 }
2886 }
2887 else
2888 {
2889 int base_face_id, bufpos;
2890
2891 if (it->current.overlay_string_index >= 0)
2892 bufpos = IT_CHARPOS (*it);
2893 else
2894 bufpos = 0;
2895
2896 /* For strings from a buffer, i.e. overlay strings or strings
2897 from a `display' property, use the face at IT's current
2898 buffer position as the base face to merge with, so that
2899 overlay strings appear in the same face as surrounding
2900 text, unless they specify their own faces. */
2901 base_face_id = underlying_face_id (it);
2902
2903 new_face_id = face_at_string_position (it->w,
2904 it->string,
2905 IT_STRING_CHARPOS (*it),
2906 bufpos,
2907 it->region_beg_charpos,
2908 it->region_end_charpos,
2909 &next_stop,
2910 base_face_id, 0);
2911
2912 #if 0 /* This shouldn't be neccessary. Let's check it. */
2913 /* If IT is used to display a mode line we would really like to
2914 use the mode line face instead of the frame's default face. */
2915 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2916 && new_face_id == DEFAULT_FACE_ID)
2917 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2918 #endif
2919
2920 /* Is this a start of a run of characters with box? Caveat:
2921 this can be called for a freshly allocated iterator; face_id
2922 is -1 is this case. We know that the new face will not
2923 change until the next check pos, i.e. if the new face has a
2924 box, all characters up to that position will have a
2925 box. But, as usual, we don't know whether that position
2926 is really the end. */
2927 if (new_face_id != it->face_id)
2928 {
2929 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2930 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2931
2932 /* If new face has a box but old face hasn't, this is the
2933 start of a run of characters with box, i.e. it has a
2934 shadow on the left side. */
2935 it->start_of_box_run_p
2936 = new_face->box && (old_face == NULL || !old_face->box);
2937 it->face_box_p = new_face->box != FACE_NO_BOX;
2938 }
2939 }
2940
2941 it->face_id = new_face_id;
2942 return HANDLED_NORMALLY;
2943 }
2944
2945
2946 /* Return the ID of the face ``underlying'' IT's current position,
2947 which is in a string. If the iterator is associated with a
2948 buffer, return the face at IT's current buffer position.
2949 Otherwise, use the iterator's base_face_id. */
2950
2951 static int
2952 underlying_face_id (it)
2953 struct it *it;
2954 {
2955 int face_id = it->base_face_id, i;
2956
2957 xassert (STRINGP (it->string));
2958
2959 for (i = it->sp - 1; i >= 0; --i)
2960 if (NILP (it->stack[i].string))
2961 face_id = it->stack[i].face_id;
2962
2963 return face_id;
2964 }
2965
2966
2967 /* Compute the face one character before or after the current position
2968 of IT. BEFORE_P non-zero means get the face in front of IT's
2969 position. Value is the id of the face. */
2970
2971 static int
2972 face_before_or_after_it_pos (it, before_p)
2973 struct it *it;
2974 int before_p;
2975 {
2976 int face_id, limit;
2977 int next_check_charpos;
2978 struct text_pos pos;
2979
2980 xassert (it->s == NULL);
2981
2982 if (STRINGP (it->string))
2983 {
2984 int bufpos, base_face_id;
2985
2986 /* No face change past the end of the string (for the case
2987 we are padding with spaces). No face change before the
2988 string start. */
2989 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2990 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2991 return it->face_id;
2992
2993 /* Set pos to the position before or after IT's current position. */
2994 if (before_p)
2995 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2996 else
2997 /* For composition, we must check the character after the
2998 composition. */
2999 pos = (it->what == IT_COMPOSITION
3000 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3001 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3002
3003 if (it->current.overlay_string_index >= 0)
3004 bufpos = IT_CHARPOS (*it);
3005 else
3006 bufpos = 0;
3007
3008 base_face_id = underlying_face_id (it);
3009
3010 /* Get the face for ASCII, or unibyte. */
3011 face_id = face_at_string_position (it->w,
3012 it->string,
3013 CHARPOS (pos),
3014 bufpos,
3015 it->region_beg_charpos,
3016 it->region_end_charpos,
3017 &next_check_charpos,
3018 base_face_id, 0);
3019
3020 /* Correct the face for charsets different from ASCII. Do it
3021 for the multibyte case only. The face returned above is
3022 suitable for unibyte text if IT->string is unibyte. */
3023 if (STRING_MULTIBYTE (it->string))
3024 {
3025 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3026 int rest = SBYTES (it->string) - BYTEPOS (pos);
3027 int c, len;
3028 struct face *face = FACE_FROM_ID (it->f, face_id);
3029
3030 c = string_char_and_length (p, rest, &len);
3031 face_id = FACE_FOR_CHAR (it->f, face, c);
3032 }
3033 }
3034 else
3035 {
3036 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3037 || (IT_CHARPOS (*it) <= BEGV && before_p))
3038 return it->face_id;
3039
3040 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3041 pos = it->current.pos;
3042
3043 if (before_p)
3044 DEC_TEXT_POS (pos, it->multibyte_p);
3045 else
3046 {
3047 if (it->what == IT_COMPOSITION)
3048 /* For composition, we must check the position after the
3049 composition. */
3050 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3051 else
3052 INC_TEXT_POS (pos, it->multibyte_p);
3053 }
3054
3055 /* Determine face for CHARSET_ASCII, or unibyte. */
3056 face_id = face_at_buffer_position (it->w,
3057 CHARPOS (pos),
3058 it->region_beg_charpos,
3059 it->region_end_charpos,
3060 &next_check_charpos,
3061 limit, 0);
3062
3063 /* Correct the face for charsets different from ASCII. Do it
3064 for the multibyte case only. The face returned above is
3065 suitable for unibyte text if current_buffer is unibyte. */
3066 if (it->multibyte_p)
3067 {
3068 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3069 struct face *face = FACE_FROM_ID (it->f, face_id);
3070 face_id = FACE_FOR_CHAR (it->f, face, c);
3071 }
3072 }
3073
3074 return face_id;
3075 }
3076
3077
3078 \f
3079 /***********************************************************************
3080 Invisible text
3081 ***********************************************************************/
3082
3083 /* Set up iterator IT from invisible properties at its current
3084 position. Called from handle_stop. */
3085
3086 static enum prop_handled
3087 handle_invisible_prop (it)
3088 struct it *it;
3089 {
3090 enum prop_handled handled = HANDLED_NORMALLY;
3091
3092 if (STRINGP (it->string))
3093 {
3094 extern Lisp_Object Qinvisible;
3095 Lisp_Object prop, end_charpos, limit, charpos;
3096
3097 /* Get the value of the invisible text property at the
3098 current position. Value will be nil if there is no such
3099 property. */
3100 charpos = make_number (IT_STRING_CHARPOS (*it));
3101 prop = Fget_text_property (charpos, Qinvisible, it->string);
3102
3103 if (!NILP (prop)
3104 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3105 {
3106 handled = HANDLED_RECOMPUTE_PROPS;
3107
3108 /* Get the position at which the next change of the
3109 invisible text property can be found in IT->string.
3110 Value will be nil if the property value is the same for
3111 all the rest of IT->string. */
3112 XSETINT (limit, SCHARS (it->string));
3113 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3114 it->string, limit);
3115
3116 /* Text at current position is invisible. The next
3117 change in the property is at position end_charpos.
3118 Move IT's current position to that position. */
3119 if (INTEGERP (end_charpos)
3120 && XFASTINT (end_charpos) < XFASTINT (limit))
3121 {
3122 struct text_pos old;
3123 old = it->current.string_pos;
3124 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3125 compute_string_pos (&it->current.string_pos, old, it->string);
3126 }
3127 else
3128 {
3129 /* The rest of the string is invisible. If this is an
3130 overlay string, proceed with the next overlay string
3131 or whatever comes and return a character from there. */
3132 if (it->current.overlay_string_index >= 0)
3133 {
3134 next_overlay_string (it);
3135 /* Don't check for overlay strings when we just
3136 finished processing them. */
3137 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3138 }
3139 else
3140 {
3141 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3142 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3143 }
3144 }
3145 }
3146 }
3147 else
3148 {
3149 int invis_p, newpos, next_stop, start_charpos;
3150 Lisp_Object pos, prop, overlay;
3151
3152 /* First of all, is there invisible text at this position? */
3153 start_charpos = IT_CHARPOS (*it);
3154 pos = make_number (IT_CHARPOS (*it));
3155 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3156 &overlay);
3157 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3158
3159 /* If we are on invisible text, skip over it. */
3160 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3161 {
3162 /* Record whether we have to display an ellipsis for the
3163 invisible text. */
3164 int display_ellipsis_p = invis_p == 2;
3165
3166 handled = HANDLED_RECOMPUTE_PROPS;
3167
3168 /* Loop skipping over invisible text. The loop is left at
3169 ZV or with IT on the first char being visible again. */
3170 do
3171 {
3172 /* Try to skip some invisible text. Return value is the
3173 position reached which can be equal to IT's position
3174 if there is nothing invisible here. This skips both
3175 over invisible text properties and overlays with
3176 invisible property. */
3177 newpos = skip_invisible (IT_CHARPOS (*it),
3178 &next_stop, ZV, it->window);
3179
3180 /* If we skipped nothing at all we weren't at invisible
3181 text in the first place. If everything to the end of
3182 the buffer was skipped, end the loop. */
3183 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3184 invis_p = 0;
3185 else
3186 {
3187 /* We skipped some characters but not necessarily
3188 all there are. Check if we ended up on visible
3189 text. Fget_char_property returns the property of
3190 the char before the given position, i.e. if we
3191 get invis_p = 0, this means that the char at
3192 newpos is visible. */
3193 pos = make_number (newpos);
3194 prop = Fget_char_property (pos, Qinvisible, it->window);
3195 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3196 }
3197
3198 /* If we ended up on invisible text, proceed to
3199 skip starting with next_stop. */
3200 if (invis_p)
3201 IT_CHARPOS (*it) = next_stop;
3202 }
3203 while (invis_p);
3204
3205 /* The position newpos is now either ZV or on visible text. */
3206 IT_CHARPOS (*it) = newpos;
3207 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3208
3209 /* If there are before-strings at the start of invisible
3210 text, and the text is invisible because of a text
3211 property, arrange to show before-strings because 20.x did
3212 it that way. (If the text is invisible because of an
3213 overlay property instead of a text property, this is
3214 already handled in the overlay code.) */
3215 if (NILP (overlay)
3216 && get_overlay_strings (it, start_charpos))
3217 {
3218 handled = HANDLED_RECOMPUTE_PROPS;
3219 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3220 }
3221 else if (display_ellipsis_p)
3222 setup_for_ellipsis (it);
3223 }
3224 }
3225
3226 return handled;
3227 }
3228
3229
3230 /* Make iterator IT return `...' next. */
3231
3232 static void
3233 setup_for_ellipsis (it)
3234 struct it *it;
3235 {
3236 if (it->dp
3237 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3238 {
3239 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3240 it->dpvec = v->contents;
3241 it->dpend = v->contents + v->size;
3242 }
3243 else
3244 {
3245 /* Default `...'. */
3246 it->dpvec = default_invis_vector;
3247 it->dpend = default_invis_vector + 3;
3248 }
3249
3250 /* The ellipsis display does not replace the display of the
3251 character at the new position. Indicate this by setting
3252 IT->dpvec_char_len to zero. */
3253 it->dpvec_char_len = 0;
3254
3255 it->current.dpvec_index = 0;
3256 it->method = next_element_from_display_vector;
3257 }
3258
3259
3260 \f
3261 /***********************************************************************
3262 'display' property
3263 ***********************************************************************/
3264
3265 /* Set up iterator IT from `display' property at its current position.
3266 Called from handle_stop. */
3267
3268 static enum prop_handled
3269 handle_display_prop (it)
3270 struct it *it;
3271 {
3272 Lisp_Object prop, object;
3273 struct text_pos *position;
3274 int display_replaced_p = 0;
3275
3276 if (STRINGP (it->string))
3277 {
3278 object = it->string;
3279 position = &it->current.string_pos;
3280 }
3281 else
3282 {
3283 object = it->w->buffer;
3284 position = &it->current.pos;
3285 }
3286
3287 /* Reset those iterator values set from display property values. */
3288 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3289 it->space_width = Qnil;
3290 it->font_height = Qnil;
3291 it->voffset = 0;
3292
3293 /* We don't support recursive `display' properties, i.e. string
3294 values that have a string `display' property, that have a string
3295 `display' property etc. */
3296 if (!it->string_from_display_prop_p)
3297 it->area = TEXT_AREA;
3298
3299 prop = Fget_char_property (make_number (position->charpos),
3300 Qdisplay, object);
3301 if (NILP (prop))
3302 return HANDLED_NORMALLY;
3303
3304 if (CONSP (prop)
3305 /* Simple properties. */
3306 && !EQ (XCAR (prop), Qimage)
3307 && !EQ (XCAR (prop), Qspace)
3308 && !EQ (XCAR (prop), Qwhen)
3309 && !EQ (XCAR (prop), Qslice)
3310 && !EQ (XCAR (prop), Qspace_width)
3311 && !EQ (XCAR (prop), Qheight)
3312 && !EQ (XCAR (prop), Qraise)
3313 /* Marginal area specifications. */
3314 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3315 && !EQ (XCAR (prop), Qleft_fringe)
3316 && !EQ (XCAR (prop), Qright_fringe)
3317 && !NILP (XCAR (prop)))
3318 {
3319 for (; CONSP (prop); prop = XCDR (prop))
3320 {
3321 if (handle_single_display_prop (it, XCAR (prop), object,
3322 position, display_replaced_p))
3323 display_replaced_p = 1;
3324 }
3325 }
3326 else if (VECTORP (prop))
3327 {
3328 int i;
3329 for (i = 0; i < ASIZE (prop); ++i)
3330 if (handle_single_display_prop (it, AREF (prop, i), object,
3331 position, display_replaced_p))
3332 display_replaced_p = 1;
3333 }
3334 else
3335 {
3336 if (handle_single_display_prop (it, prop, object, position, 0))
3337 display_replaced_p = 1;
3338 }
3339
3340 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3341 }
3342
3343
3344 /* Value is the position of the end of the `display' property starting
3345 at START_POS in OBJECT. */
3346
3347 static struct text_pos
3348 display_prop_end (it, object, start_pos)
3349 struct it *it;
3350 Lisp_Object object;
3351 struct text_pos start_pos;
3352 {
3353 Lisp_Object end;
3354 struct text_pos end_pos;
3355
3356 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3357 Qdisplay, object, Qnil);
3358 CHARPOS (end_pos) = XFASTINT (end);
3359 if (STRINGP (object))
3360 compute_string_pos (&end_pos, start_pos, it->string);
3361 else
3362 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3363
3364 return end_pos;
3365 }
3366
3367
3368 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3369 is the object in which the `display' property was found. *POSITION
3370 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3371 means that we previously saw a display sub-property which already
3372 replaced text display with something else, for example an image;
3373 ignore such properties after the first one has been processed.
3374
3375 If PROP is a `space' or `image' sub-property, set *POSITION to the
3376 end position of the `display' property.
3377
3378 Value is non-zero if something was found which replaces the display
3379 of buffer or string text. */
3380
3381 static int
3382 handle_single_display_prop (it, prop, object, position,
3383 display_replaced_before_p)
3384 struct it *it;
3385 Lisp_Object prop;
3386 Lisp_Object object;
3387 struct text_pos *position;
3388 int display_replaced_before_p;
3389 {
3390 Lisp_Object value;
3391 int replaces_text_display_p = 0;
3392 Lisp_Object form;
3393
3394 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3395 evaluated. If the result is nil, VALUE is ignored. */
3396 form = Qt;
3397 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3398 {
3399 prop = XCDR (prop);
3400 if (!CONSP (prop))
3401 return 0;
3402 form = XCAR (prop);
3403 prop = XCDR (prop);
3404 }
3405
3406 if (!NILP (form) && !EQ (form, Qt))
3407 {
3408 int count = SPECPDL_INDEX ();
3409 struct gcpro gcpro1;
3410
3411 /* Bind `object' to the object having the `display' property, a
3412 buffer or string. Bind `position' to the position in the
3413 object where the property was found, and `buffer-position'
3414 to the current position in the buffer. */
3415 specbind (Qobject, object);
3416 specbind (Qposition, make_number (CHARPOS (*position)));
3417 specbind (Qbuffer_position,
3418 make_number (STRINGP (object)
3419 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3420 GCPRO1 (form);
3421 form = safe_eval (form);
3422 UNGCPRO;
3423 unbind_to (count, Qnil);
3424 }
3425
3426 if (NILP (form))
3427 return 0;
3428
3429 if (CONSP (prop)
3430 && EQ (XCAR (prop), Qheight)
3431 && CONSP (XCDR (prop)))
3432 {
3433 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3434 return 0;
3435
3436 /* `(height HEIGHT)'. */
3437 it->font_height = XCAR (XCDR (prop));
3438 if (!NILP (it->font_height))
3439 {
3440 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3441 int new_height = -1;
3442
3443 if (CONSP (it->font_height)
3444 && (EQ (XCAR (it->font_height), Qplus)
3445 || EQ (XCAR (it->font_height), Qminus))
3446 && CONSP (XCDR (it->font_height))
3447 && INTEGERP (XCAR (XCDR (it->font_height))))
3448 {
3449 /* `(+ N)' or `(- N)' where N is an integer. */
3450 int steps = XINT (XCAR (XCDR (it->font_height)));
3451 if (EQ (XCAR (it->font_height), Qplus))
3452 steps = - steps;
3453 it->face_id = smaller_face (it->f, it->face_id, steps);
3454 }
3455 else if (FUNCTIONP (it->font_height))
3456 {
3457 /* Call function with current height as argument.
3458 Value is the new height. */
3459 Lisp_Object height;
3460 height = safe_call1 (it->font_height,
3461 face->lface[LFACE_HEIGHT_INDEX]);
3462 if (NUMBERP (height))
3463 new_height = XFLOATINT (height);
3464 }
3465 else if (NUMBERP (it->font_height))
3466 {
3467 /* Value is a multiple of the canonical char height. */
3468 struct face *face;
3469
3470 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3471 new_height = (XFLOATINT (it->font_height)
3472 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3473 }
3474 else
3475 {
3476 /* Evaluate IT->font_height with `height' bound to the
3477 current specified height to get the new height. */
3478 Lisp_Object value;
3479 int count = SPECPDL_INDEX ();
3480
3481 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3482 value = safe_eval (it->font_height);
3483 unbind_to (count, Qnil);
3484
3485 if (NUMBERP (value))
3486 new_height = XFLOATINT (value);
3487 }
3488
3489 if (new_height > 0)
3490 it->face_id = face_with_height (it->f, it->face_id, new_height);
3491 }
3492 }
3493 else if (CONSP (prop)
3494 && EQ (XCAR (prop), Qspace_width)
3495 && CONSP (XCDR (prop)))
3496 {
3497 /* `(space_width WIDTH)'. */
3498 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3499 return 0;
3500
3501 value = XCAR (XCDR (prop));
3502 if (NUMBERP (value) && XFLOATINT (value) > 0)
3503 it->space_width = value;
3504 }
3505 else if (CONSP (prop)
3506 && EQ (XCAR (prop), Qslice))
3507 {
3508 /* `(slice X Y WIDTH HEIGHT)'. */
3509 Lisp_Object tem;
3510
3511 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3512 return 0;
3513
3514 if (tem = XCDR (prop), CONSP (tem))
3515 {
3516 it->slice.x = XCAR (tem);
3517 if (tem = XCDR (tem), CONSP (tem))
3518 {
3519 it->slice.y = XCAR (tem);
3520 if (tem = XCDR (tem), CONSP (tem))
3521 {
3522 it->slice.width = XCAR (tem);
3523 if (tem = XCDR (tem), CONSP (tem))
3524 it->slice.height = XCAR (tem);
3525 }
3526 }
3527 }
3528 }
3529 else if (CONSP (prop)
3530 && EQ (XCAR (prop), Qraise)
3531 && CONSP (XCDR (prop)))
3532 {
3533 /* `(raise FACTOR)'. */
3534 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3535 return 0;
3536
3537 #ifdef HAVE_WINDOW_SYSTEM
3538 value = XCAR (XCDR (prop));
3539 if (NUMBERP (value))
3540 {
3541 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3542 it->voffset = - (XFLOATINT (value)
3543 * (FONT_HEIGHT (face->font)));
3544 }
3545 #endif /* HAVE_WINDOW_SYSTEM */
3546 }
3547 else if (!it->string_from_display_prop_p)
3548 {
3549 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3550 VALUE) or `((margin nil) VALUE)' or VALUE. */
3551 Lisp_Object location, value;
3552 struct text_pos start_pos;
3553 int valid_p;
3554
3555 /* Characters having this form of property are not displayed, so
3556 we have to find the end of the property. */
3557 start_pos = *position;
3558 *position = display_prop_end (it, object, start_pos);
3559 value = Qnil;
3560
3561 /* Let's stop at the new position and assume that all
3562 text properties change there. */
3563 it->stop_charpos = position->charpos;
3564
3565 if (CONSP (prop)
3566 && (EQ (XCAR (prop), Qleft_fringe)
3567 || EQ (XCAR (prop), Qright_fringe))
3568 && CONSP (XCDR (prop)))
3569 {
3570 unsigned face_id = DEFAULT_FACE_ID;
3571
3572 /* Save current settings of IT so that we can restore them
3573 when we are finished with the glyph property value. */
3574
3575 /* `(left-fringe BITMAP FACE)'. */
3576 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3577 return 0;
3578
3579 #ifdef HAVE_WINDOW_SYSTEM
3580 value = XCAR (XCDR (prop));
3581 if (!NUMBERP (value)
3582 || !valid_fringe_bitmap_id_p (XINT (value)))
3583 return 0;
3584
3585 if (CONSP (XCDR (XCDR (prop))))
3586 {
3587 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3588
3589 face_id = lookup_named_face (it->f, face_name, 'A');
3590 if (face_id < 0)
3591 return 0;
3592 }
3593
3594 push_it (it);
3595
3596 it->area = TEXT_AREA;
3597 it->what = IT_IMAGE;
3598 it->image_id = -1; /* no image */
3599 it->position = start_pos;
3600 it->object = NILP (object) ? it->w->buffer : object;
3601 it->method = next_element_from_image;
3602 it->face_id = face_id;
3603
3604 /* Say that we haven't consumed the characters with
3605 `display' property yet. The call to pop_it in
3606 set_iterator_to_next will clean this up. */
3607 *position = start_pos;
3608
3609 if (EQ (XCAR (prop), Qleft_fringe))
3610 {
3611 it->left_user_fringe_bitmap = XINT (value);
3612 it->left_user_fringe_face_id = face_id;
3613 }
3614 else
3615 {
3616 it->right_user_fringe_bitmap = XINT (value);
3617 it->right_user_fringe_face_id = face_id;
3618 }
3619 #endif /* HAVE_WINDOW_SYSTEM */
3620 return 1;
3621 }
3622
3623 location = Qunbound;
3624 if (CONSP (prop) && CONSP (XCAR (prop)))
3625 {
3626 Lisp_Object tem;
3627
3628 value = XCDR (prop);
3629 if (CONSP (value))
3630 value = XCAR (value);
3631
3632 tem = XCAR (prop);
3633 if (EQ (XCAR (tem), Qmargin)
3634 && (tem = XCDR (tem),
3635 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3636 (NILP (tem)
3637 || EQ (tem, Qleft_margin)
3638 || EQ (tem, Qright_margin))))
3639 location = tem;
3640 }
3641
3642 if (EQ (location, Qunbound))
3643 {
3644 location = Qnil;
3645 value = prop;
3646 }
3647
3648 valid_p = (STRINGP (value)
3649 #ifdef HAVE_WINDOW_SYSTEM
3650 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3651 #endif /* not HAVE_WINDOW_SYSTEM */
3652 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3653
3654 if ((EQ (location, Qleft_margin)
3655 || EQ (location, Qright_margin)
3656 || NILP (location))
3657 && valid_p
3658 && !display_replaced_before_p)
3659 {
3660 replaces_text_display_p = 1;
3661
3662 /* Save current settings of IT so that we can restore them
3663 when we are finished with the glyph property value. */
3664 push_it (it);
3665
3666 if (NILP (location))
3667 it->area = TEXT_AREA;
3668 else if (EQ (location, Qleft_margin))
3669 it->area = LEFT_MARGIN_AREA;
3670 else
3671 it->area = RIGHT_MARGIN_AREA;
3672
3673 if (STRINGP (value))
3674 {
3675 it->string = value;
3676 it->multibyte_p = STRING_MULTIBYTE (it->string);
3677 it->current.overlay_string_index = -1;
3678 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3679 it->end_charpos = it->string_nchars = SCHARS (it->string);
3680 it->method = next_element_from_string;
3681 it->stop_charpos = 0;
3682 it->string_from_display_prop_p = 1;
3683 /* Say that we haven't consumed the characters with
3684 `display' property yet. The call to pop_it in
3685 set_iterator_to_next will clean this up. */
3686 *position = start_pos;
3687 }
3688 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3689 {
3690 it->method = next_element_from_stretch;
3691 it->object = value;
3692 it->current.pos = it->position = start_pos;
3693 }
3694 #ifdef HAVE_WINDOW_SYSTEM
3695 else
3696 {
3697 it->what = IT_IMAGE;
3698 it->image_id = lookup_image (it->f, value);
3699 it->position = start_pos;
3700 it->object = NILP (object) ? it->w->buffer : object;
3701 it->method = next_element_from_image;
3702
3703 /* Say that we haven't consumed the characters with
3704 `display' property yet. The call to pop_it in
3705 set_iterator_to_next will clean this up. */
3706 *position = start_pos;
3707 }
3708 #endif /* HAVE_WINDOW_SYSTEM */
3709 }
3710 else
3711 /* Invalid property or property not supported. Restore
3712 the position to what it was before. */
3713 *position = start_pos;
3714 }
3715
3716 return replaces_text_display_p;
3717 }
3718
3719
3720 /* Check if PROP is a display sub-property value whose text should be
3721 treated as intangible. */
3722
3723 static int
3724 single_display_prop_intangible_p (prop)
3725 Lisp_Object prop;
3726 {
3727 /* Skip over `when FORM'. */
3728 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3729 {
3730 prop = XCDR (prop);
3731 if (!CONSP (prop))
3732 return 0;
3733 prop = XCDR (prop);
3734 }
3735
3736 if (STRINGP (prop))
3737 return 1;
3738
3739 if (!CONSP (prop))
3740 return 0;
3741
3742 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3743 we don't need to treat text as intangible. */
3744 if (EQ (XCAR (prop), Qmargin))
3745 {
3746 prop = XCDR (prop);
3747 if (!CONSP (prop))
3748 return 0;
3749
3750 prop = XCDR (prop);
3751 if (!CONSP (prop)
3752 || EQ (XCAR (prop), Qleft_margin)
3753 || EQ (XCAR (prop), Qright_margin))
3754 return 0;
3755 }
3756
3757 return (CONSP (prop)
3758 && (EQ (XCAR (prop), Qimage)
3759 || EQ (XCAR (prop), Qspace)));
3760 }
3761
3762
3763 /* Check if PROP is a display property value whose text should be
3764 treated as intangible. */
3765
3766 int
3767 display_prop_intangible_p (prop)
3768 Lisp_Object prop;
3769 {
3770 if (CONSP (prop)
3771 && CONSP (XCAR (prop))
3772 && !EQ (Qmargin, XCAR (XCAR (prop))))
3773 {
3774 /* A list of sub-properties. */
3775 while (CONSP (prop))
3776 {
3777 if (single_display_prop_intangible_p (XCAR (prop)))
3778 return 1;
3779 prop = XCDR (prop);
3780 }
3781 }
3782 else if (VECTORP (prop))
3783 {
3784 /* A vector of sub-properties. */
3785 int i;
3786 for (i = 0; i < ASIZE (prop); ++i)
3787 if (single_display_prop_intangible_p (AREF (prop, i)))
3788 return 1;
3789 }
3790 else
3791 return single_display_prop_intangible_p (prop);
3792
3793 return 0;
3794 }
3795
3796
3797 /* Return 1 if PROP is a display sub-property value containing STRING. */
3798
3799 static int
3800 single_display_prop_string_p (prop, string)
3801 Lisp_Object prop, string;
3802 {
3803 if (EQ (string, prop))
3804 return 1;
3805
3806 /* Skip over `when FORM'. */
3807 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3808 {
3809 prop = XCDR (prop);
3810 if (!CONSP (prop))
3811 return 0;
3812 prop = XCDR (prop);
3813 }
3814
3815 if (CONSP (prop))
3816 /* Skip over `margin LOCATION'. */
3817 if (EQ (XCAR (prop), Qmargin))
3818 {
3819 prop = XCDR (prop);
3820 if (!CONSP (prop))
3821 return 0;
3822
3823 prop = XCDR (prop);
3824 if (!CONSP (prop))
3825 return 0;
3826 }
3827
3828 return CONSP (prop) && EQ (XCAR (prop), string);
3829 }
3830
3831
3832 /* Return 1 if STRING appears in the `display' property PROP. */
3833
3834 static int
3835 display_prop_string_p (prop, string)
3836 Lisp_Object prop, string;
3837 {
3838 if (CONSP (prop)
3839 && CONSP (XCAR (prop))
3840 && !EQ (Qmargin, XCAR (XCAR (prop))))
3841 {
3842 /* A list of sub-properties. */
3843 while (CONSP (prop))
3844 {
3845 if (single_display_prop_string_p (XCAR (prop), string))
3846 return 1;
3847 prop = XCDR (prop);
3848 }
3849 }
3850 else if (VECTORP (prop))
3851 {
3852 /* A vector of sub-properties. */
3853 int i;
3854 for (i = 0; i < ASIZE (prop); ++i)
3855 if (single_display_prop_string_p (AREF (prop, i), string))
3856 return 1;
3857 }
3858 else
3859 return single_display_prop_string_p (prop, string);
3860
3861 return 0;
3862 }
3863
3864
3865 /* Determine from which buffer position in W's buffer STRING comes
3866 from. AROUND_CHARPOS is an approximate position where it could
3867 be from. Value is the buffer position or 0 if it couldn't be
3868 determined.
3869
3870 W's buffer must be current.
3871
3872 This function is necessary because we don't record buffer positions
3873 in glyphs generated from strings (to keep struct glyph small).
3874 This function may only use code that doesn't eval because it is
3875 called asynchronously from note_mouse_highlight. */
3876
3877 int
3878 string_buffer_position (w, string, around_charpos)
3879 struct window *w;
3880 Lisp_Object string;
3881 int around_charpos;
3882 {
3883 Lisp_Object limit, prop, pos;
3884 const int MAX_DISTANCE = 1000;
3885 int found = 0;
3886
3887 pos = make_number (around_charpos);
3888 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3889 while (!found && !EQ (pos, limit))
3890 {
3891 prop = Fget_char_property (pos, Qdisplay, Qnil);
3892 if (!NILP (prop) && display_prop_string_p (prop, string))
3893 found = 1;
3894 else
3895 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3896 }
3897
3898 if (!found)
3899 {
3900 pos = make_number (around_charpos);
3901 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3902 while (!found && !EQ (pos, limit))
3903 {
3904 prop = Fget_char_property (pos, Qdisplay, Qnil);
3905 if (!NILP (prop) && display_prop_string_p (prop, string))
3906 found = 1;
3907 else
3908 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3909 limit);
3910 }
3911 }
3912
3913 return found ? XINT (pos) : 0;
3914 }
3915
3916
3917 \f
3918 /***********************************************************************
3919 `composition' property
3920 ***********************************************************************/
3921
3922 /* Set up iterator IT from `composition' property at its current
3923 position. Called from handle_stop. */
3924
3925 static enum prop_handled
3926 handle_composition_prop (it)
3927 struct it *it;
3928 {
3929 Lisp_Object prop, string;
3930 int pos, pos_byte, end;
3931 enum prop_handled handled = HANDLED_NORMALLY;
3932
3933 if (STRINGP (it->string))
3934 {
3935 pos = IT_STRING_CHARPOS (*it);
3936 pos_byte = IT_STRING_BYTEPOS (*it);
3937 string = it->string;
3938 }
3939 else
3940 {
3941 pos = IT_CHARPOS (*it);
3942 pos_byte = IT_BYTEPOS (*it);
3943 string = Qnil;
3944 }
3945
3946 /* If there's a valid composition and point is not inside of the
3947 composition (in the case that the composition is from the current
3948 buffer), draw a glyph composed from the composition components. */
3949 if (find_composition (pos, -1, &pos, &end, &prop, string)
3950 && COMPOSITION_VALID_P (pos, end, prop)
3951 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3952 {
3953 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3954
3955 if (id >= 0)
3956 {
3957 it->method = next_element_from_composition;
3958 it->cmp_id = id;
3959 it->cmp_len = COMPOSITION_LENGTH (prop);
3960 /* For a terminal, draw only the first character of the
3961 components. */
3962 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3963 it->len = (STRINGP (it->string)
3964 ? string_char_to_byte (it->string, end)
3965 : CHAR_TO_BYTE (end)) - pos_byte;
3966 it->stop_charpos = end;
3967 handled = HANDLED_RETURN;
3968 }
3969 }
3970
3971 return handled;
3972 }
3973
3974
3975 \f
3976 /***********************************************************************
3977 Overlay strings
3978 ***********************************************************************/
3979
3980 /* The following structure is used to record overlay strings for
3981 later sorting in load_overlay_strings. */
3982
3983 struct overlay_entry
3984 {
3985 Lisp_Object overlay;
3986 Lisp_Object string;
3987 int priority;
3988 int after_string_p;
3989 };
3990
3991
3992 /* Set up iterator IT from overlay strings at its current position.
3993 Called from handle_stop. */
3994
3995 static enum prop_handled
3996 handle_overlay_change (it)
3997 struct it *it;
3998 {
3999 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4000 return HANDLED_RECOMPUTE_PROPS;
4001 else
4002 return HANDLED_NORMALLY;
4003 }
4004
4005
4006 /* Set up the next overlay string for delivery by IT, if there is an
4007 overlay string to deliver. Called by set_iterator_to_next when the
4008 end of the current overlay string is reached. If there are more
4009 overlay strings to display, IT->string and
4010 IT->current.overlay_string_index are set appropriately here.
4011 Otherwise IT->string is set to nil. */
4012
4013 static void
4014 next_overlay_string (it)
4015 struct it *it;
4016 {
4017 ++it->current.overlay_string_index;
4018 if (it->current.overlay_string_index == it->n_overlay_strings)
4019 {
4020 /* No more overlay strings. Restore IT's settings to what
4021 they were before overlay strings were processed, and
4022 continue to deliver from current_buffer. */
4023 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4024
4025 pop_it (it);
4026 xassert (it->stop_charpos >= BEGV
4027 && it->stop_charpos <= it->end_charpos);
4028 it->string = Qnil;
4029 it->current.overlay_string_index = -1;
4030 SET_TEXT_POS (it->current.string_pos, -1, -1);
4031 it->n_overlay_strings = 0;
4032 it->method = next_element_from_buffer;
4033
4034 /* If we're at the end of the buffer, record that we have
4035 processed the overlay strings there already, so that
4036 next_element_from_buffer doesn't try it again. */
4037 if (IT_CHARPOS (*it) >= it->end_charpos)
4038 it->overlay_strings_at_end_processed_p = 1;
4039
4040 /* If we have to display `...' for invisible text, set
4041 the iterator up for that. */
4042 if (display_ellipsis_p)
4043 setup_for_ellipsis (it);
4044 }
4045 else
4046 {
4047 /* There are more overlay strings to process. If
4048 IT->current.overlay_string_index has advanced to a position
4049 where we must load IT->overlay_strings with more strings, do
4050 it. */
4051 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4052
4053 if (it->current.overlay_string_index && i == 0)
4054 load_overlay_strings (it, 0);
4055
4056 /* Initialize IT to deliver display elements from the overlay
4057 string. */
4058 it->string = it->overlay_strings[i];
4059 it->multibyte_p = STRING_MULTIBYTE (it->string);
4060 SET_TEXT_POS (it->current.string_pos, 0, 0);
4061 it->method = next_element_from_string;
4062 it->stop_charpos = 0;
4063 }
4064
4065 CHECK_IT (it);
4066 }
4067
4068
4069 /* Compare two overlay_entry structures E1 and E2. Used as a
4070 comparison function for qsort in load_overlay_strings. Overlay
4071 strings for the same position are sorted so that
4072
4073 1. All after-strings come in front of before-strings, except
4074 when they come from the same overlay.
4075
4076 2. Within after-strings, strings are sorted so that overlay strings
4077 from overlays with higher priorities come first.
4078
4079 2. Within before-strings, strings are sorted so that overlay
4080 strings from overlays with higher priorities come last.
4081
4082 Value is analogous to strcmp. */
4083
4084
4085 static int
4086 compare_overlay_entries (e1, e2)
4087 void *e1, *e2;
4088 {
4089 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4090 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4091 int result;
4092
4093 if (entry1->after_string_p != entry2->after_string_p)
4094 {
4095 /* Let after-strings appear in front of before-strings if
4096 they come from different overlays. */
4097 if (EQ (entry1->overlay, entry2->overlay))
4098 result = entry1->after_string_p ? 1 : -1;
4099 else
4100 result = entry1->after_string_p ? -1 : 1;
4101 }
4102 else if (entry1->after_string_p)
4103 /* After-strings sorted in order of decreasing priority. */
4104 result = entry2->priority - entry1->priority;
4105 else
4106 /* Before-strings sorted in order of increasing priority. */
4107 result = entry1->priority - entry2->priority;
4108
4109 return result;
4110 }
4111
4112
4113 /* Load the vector IT->overlay_strings with overlay strings from IT's
4114 current buffer position, or from CHARPOS if that is > 0. Set
4115 IT->n_overlays to the total number of overlay strings found.
4116
4117 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4118 a time. On entry into load_overlay_strings,
4119 IT->current.overlay_string_index gives the number of overlay
4120 strings that have already been loaded by previous calls to this
4121 function.
4122
4123 IT->add_overlay_start contains an additional overlay start
4124 position to consider for taking overlay strings from, if non-zero.
4125 This position comes into play when the overlay has an `invisible'
4126 property, and both before and after-strings. When we've skipped to
4127 the end of the overlay, because of its `invisible' property, we
4128 nevertheless want its before-string to appear.
4129 IT->add_overlay_start will contain the overlay start position
4130 in this case.
4131
4132 Overlay strings are sorted so that after-string strings come in
4133 front of before-string strings. Within before and after-strings,
4134 strings are sorted by overlay priority. See also function
4135 compare_overlay_entries. */
4136
4137 static void
4138 load_overlay_strings (it, charpos)
4139 struct it *it;
4140 int charpos;
4141 {
4142 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4143 Lisp_Object overlay, window, str, invisible;
4144 struct Lisp_Overlay *ov;
4145 int start, end;
4146 int size = 20;
4147 int n = 0, i, j, invis_p;
4148 struct overlay_entry *entries
4149 = (struct overlay_entry *) alloca (size * sizeof *entries);
4150
4151 if (charpos <= 0)
4152 charpos = IT_CHARPOS (*it);
4153
4154 /* Append the overlay string STRING of overlay OVERLAY to vector
4155 `entries' which has size `size' and currently contains `n'
4156 elements. AFTER_P non-zero means STRING is an after-string of
4157 OVERLAY. */
4158 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4159 do \
4160 { \
4161 Lisp_Object priority; \
4162 \
4163 if (n == size) \
4164 { \
4165 int new_size = 2 * size; \
4166 struct overlay_entry *old = entries; \
4167 entries = \
4168 (struct overlay_entry *) alloca (new_size \
4169 * sizeof *entries); \
4170 bcopy (old, entries, size * sizeof *entries); \
4171 size = new_size; \
4172 } \
4173 \
4174 entries[n].string = (STRING); \
4175 entries[n].overlay = (OVERLAY); \
4176 priority = Foverlay_get ((OVERLAY), Qpriority); \
4177 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4178 entries[n].after_string_p = (AFTER_P); \
4179 ++n; \
4180 } \
4181 while (0)
4182
4183 /* Process overlay before the overlay center. */
4184 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4185 {
4186 XSETMISC (overlay, ov);
4187 xassert (OVERLAYP (overlay));
4188 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4189 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4190
4191 if (end < charpos)
4192 break;
4193
4194 /* Skip this overlay if it doesn't start or end at IT's current
4195 position. */
4196 if (end != charpos && start != charpos)
4197 continue;
4198
4199 /* Skip this overlay if it doesn't apply to IT->w. */
4200 window = Foverlay_get (overlay, Qwindow);
4201 if (WINDOWP (window) && XWINDOW (window) != it->w)
4202 continue;
4203
4204 /* If the text ``under'' the overlay is invisible, both before-
4205 and after-strings from this overlay are visible; start and
4206 end position are indistinguishable. */
4207 invisible = Foverlay_get (overlay, Qinvisible);
4208 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4209
4210 /* If overlay has a non-empty before-string, record it. */
4211 if ((start == charpos || (end == charpos && invis_p))
4212 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4213 && SCHARS (str))
4214 RECORD_OVERLAY_STRING (overlay, str, 0);
4215
4216 /* If overlay has a non-empty after-string, record it. */
4217 if ((end == charpos || (start == charpos && invis_p))
4218 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4219 && SCHARS (str))
4220 RECORD_OVERLAY_STRING (overlay, str, 1);
4221 }
4222
4223 /* Process overlays after the overlay center. */
4224 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4225 {
4226 XSETMISC (overlay, ov);
4227 xassert (OVERLAYP (overlay));
4228 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4229 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4230
4231 if (start > charpos)
4232 break;
4233
4234 /* Skip this overlay if it doesn't start or end at IT's current
4235 position. */
4236 if (end != charpos && start != charpos)
4237 continue;
4238
4239 /* Skip this overlay if it doesn't apply to IT->w. */
4240 window = Foverlay_get (overlay, Qwindow);
4241 if (WINDOWP (window) && XWINDOW (window) != it->w)
4242 continue;
4243
4244 /* If the text ``under'' the overlay is invisible, it has a zero
4245 dimension, and both before- and after-strings apply. */
4246 invisible = Foverlay_get (overlay, Qinvisible);
4247 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4248
4249 /* If overlay has a non-empty before-string, record it. */
4250 if ((start == charpos || (end == charpos && invis_p))
4251 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4252 && SCHARS (str))
4253 RECORD_OVERLAY_STRING (overlay, str, 0);
4254
4255 /* If overlay has a non-empty after-string, record it. */
4256 if ((end == charpos || (start == charpos && invis_p))
4257 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4258 && SCHARS (str))
4259 RECORD_OVERLAY_STRING (overlay, str, 1);
4260 }
4261
4262 #undef RECORD_OVERLAY_STRING
4263
4264 /* Sort entries. */
4265 if (n > 1)
4266 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4267
4268 /* Record the total number of strings to process. */
4269 it->n_overlay_strings = n;
4270
4271 /* IT->current.overlay_string_index is the number of overlay strings
4272 that have already been consumed by IT. Copy some of the
4273 remaining overlay strings to IT->overlay_strings. */
4274 i = 0;
4275 j = it->current.overlay_string_index;
4276 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4277 it->overlay_strings[i++] = entries[j++].string;
4278
4279 CHECK_IT (it);
4280 }
4281
4282
4283 /* Get the first chunk of overlay strings at IT's current buffer
4284 position, or at CHARPOS if that is > 0. Value is non-zero if at
4285 least one overlay string was found. */
4286
4287 static int
4288 get_overlay_strings (it, charpos)
4289 struct it *it;
4290 int charpos;
4291 {
4292 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4293 process. This fills IT->overlay_strings with strings, and sets
4294 IT->n_overlay_strings to the total number of strings to process.
4295 IT->pos.overlay_string_index has to be set temporarily to zero
4296 because load_overlay_strings needs this; it must be set to -1
4297 when no overlay strings are found because a zero value would
4298 indicate a position in the first overlay string. */
4299 it->current.overlay_string_index = 0;
4300 load_overlay_strings (it, charpos);
4301
4302 /* If we found overlay strings, set up IT to deliver display
4303 elements from the first one. Otherwise set up IT to deliver
4304 from current_buffer. */
4305 if (it->n_overlay_strings)
4306 {
4307 /* Make sure we know settings in current_buffer, so that we can
4308 restore meaningful values when we're done with the overlay
4309 strings. */
4310 compute_stop_pos (it);
4311 xassert (it->face_id >= 0);
4312
4313 /* Save IT's settings. They are restored after all overlay
4314 strings have been processed. */
4315 xassert (it->sp == 0);
4316 push_it (it);
4317
4318 /* Set up IT to deliver display elements from the first overlay
4319 string. */
4320 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4321 it->string = it->overlay_strings[0];
4322 it->stop_charpos = 0;
4323 xassert (STRINGP (it->string));
4324 it->end_charpos = SCHARS (it->string);
4325 it->multibyte_p = STRING_MULTIBYTE (it->string);
4326 it->method = next_element_from_string;
4327 }
4328 else
4329 {
4330 it->string = Qnil;
4331 it->current.overlay_string_index = -1;
4332 it->method = next_element_from_buffer;
4333 }
4334
4335 CHECK_IT (it);
4336
4337 /* Value is non-zero if we found at least one overlay string. */
4338 return STRINGP (it->string);
4339 }
4340
4341
4342 \f
4343 /***********************************************************************
4344 Saving and restoring state
4345 ***********************************************************************/
4346
4347 /* Save current settings of IT on IT->stack. Called, for example,
4348 before setting up IT for an overlay string, to be able to restore
4349 IT's settings to what they were after the overlay string has been
4350 processed. */
4351
4352 static void
4353 push_it (it)
4354 struct it *it;
4355 {
4356 struct iterator_stack_entry *p;
4357
4358 xassert (it->sp < 2);
4359 p = it->stack + it->sp;
4360
4361 p->stop_charpos = it->stop_charpos;
4362 xassert (it->face_id >= 0);
4363 p->face_id = it->face_id;
4364 p->string = it->string;
4365 p->pos = it->current;
4366 p->end_charpos = it->end_charpos;
4367 p->string_nchars = it->string_nchars;
4368 p->area = it->area;
4369 p->multibyte_p = it->multibyte_p;
4370 p->slice = it->slice;
4371 p->space_width = it->space_width;
4372 p->font_height = it->font_height;
4373 p->voffset = it->voffset;
4374 p->string_from_display_prop_p = it->string_from_display_prop_p;
4375 p->display_ellipsis_p = 0;
4376 ++it->sp;
4377 }
4378
4379
4380 /* Restore IT's settings from IT->stack. Called, for example, when no
4381 more overlay strings must be processed, and we return to delivering
4382 display elements from a buffer, or when the end of a string from a
4383 `display' property is reached and we return to delivering display
4384 elements from an overlay string, or from a buffer. */
4385
4386 static void
4387 pop_it (it)
4388 struct it *it;
4389 {
4390 struct iterator_stack_entry *p;
4391
4392 xassert (it->sp > 0);
4393 --it->sp;
4394 p = it->stack + it->sp;
4395 it->stop_charpos = p->stop_charpos;
4396 it->face_id = p->face_id;
4397 it->string = p->string;
4398 it->current = p->pos;
4399 it->end_charpos = p->end_charpos;
4400 it->string_nchars = p->string_nchars;
4401 it->area = p->area;
4402 it->multibyte_p = p->multibyte_p;
4403 it->slice = p->slice;
4404 it->space_width = p->space_width;
4405 it->font_height = p->font_height;
4406 it->voffset = p->voffset;
4407 it->string_from_display_prop_p = p->string_from_display_prop_p;
4408 }
4409
4410
4411 \f
4412 /***********************************************************************
4413 Moving over lines
4414 ***********************************************************************/
4415
4416 /* Set IT's current position to the previous line start. */
4417
4418 static void
4419 back_to_previous_line_start (it)
4420 struct it *it;
4421 {
4422 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4423 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4424 }
4425
4426
4427 /* Move IT to the next line start.
4428
4429 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4430 we skipped over part of the text (as opposed to moving the iterator
4431 continuously over the text). Otherwise, don't change the value
4432 of *SKIPPED_P.
4433
4434 Newlines may come from buffer text, overlay strings, or strings
4435 displayed via the `display' property. That's the reason we can't
4436 simply use find_next_newline_no_quit.
4437
4438 Note that this function may not skip over invisible text that is so
4439 because of text properties and immediately follows a newline. If
4440 it would, function reseat_at_next_visible_line_start, when called
4441 from set_iterator_to_next, would effectively make invisible
4442 characters following a newline part of the wrong glyph row, which
4443 leads to wrong cursor motion. */
4444
4445 static int
4446 forward_to_next_line_start (it, skipped_p)
4447 struct it *it;
4448 int *skipped_p;
4449 {
4450 int old_selective, newline_found_p, n;
4451 const int MAX_NEWLINE_DISTANCE = 500;
4452
4453 /* If already on a newline, just consume it to avoid unintended
4454 skipping over invisible text below. */
4455 if (it->what == IT_CHARACTER
4456 && it->c == '\n'
4457 && CHARPOS (it->position) == IT_CHARPOS (*it))
4458 {
4459 set_iterator_to_next (it, 0);
4460 it->c = 0;
4461 return 1;
4462 }
4463
4464 /* Don't handle selective display in the following. It's (a)
4465 unnecessary because it's done by the caller, and (b) leads to an
4466 infinite recursion because next_element_from_ellipsis indirectly
4467 calls this function. */
4468 old_selective = it->selective;
4469 it->selective = 0;
4470
4471 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4472 from buffer text. */
4473 for (n = newline_found_p = 0;
4474 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4475 n += STRINGP (it->string) ? 0 : 1)
4476 {
4477 if (!get_next_display_element (it))
4478 return 0;
4479 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4480 set_iterator_to_next (it, 0);
4481 }
4482
4483 /* If we didn't find a newline near enough, see if we can use a
4484 short-cut. */
4485 if (!newline_found_p)
4486 {
4487 int start = IT_CHARPOS (*it);
4488 int limit = find_next_newline_no_quit (start, 1);
4489 Lisp_Object pos;
4490
4491 xassert (!STRINGP (it->string));
4492
4493 /* If there isn't any `display' property in sight, and no
4494 overlays, we can just use the position of the newline in
4495 buffer text. */
4496 if (it->stop_charpos >= limit
4497 || ((pos = Fnext_single_property_change (make_number (start),
4498 Qdisplay,
4499 Qnil, make_number (limit)),
4500 NILP (pos))
4501 && next_overlay_change (start) == ZV))
4502 {
4503 IT_CHARPOS (*it) = limit;
4504 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4505 *skipped_p = newline_found_p = 1;
4506 }
4507 else
4508 {
4509 while (get_next_display_element (it)
4510 && !newline_found_p)
4511 {
4512 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4513 set_iterator_to_next (it, 0);
4514 }
4515 }
4516 }
4517
4518 it->selective = old_selective;
4519 return newline_found_p;
4520 }
4521
4522
4523 /* Set IT's current position to the previous visible line start. Skip
4524 invisible text that is so either due to text properties or due to
4525 selective display. Caution: this does not change IT->current_x and
4526 IT->hpos. */
4527
4528 static void
4529 back_to_previous_visible_line_start (it)
4530 struct it *it;
4531 {
4532 int visible_p = 0;
4533
4534 /* Go back one newline if not on BEGV already. */
4535 if (IT_CHARPOS (*it) > BEGV)
4536 back_to_previous_line_start (it);
4537
4538 /* Move over lines that are invisible because of selective display
4539 or text properties. */
4540 while (IT_CHARPOS (*it) > BEGV
4541 && !visible_p)
4542 {
4543 visible_p = 1;
4544
4545 /* If selective > 0, then lines indented more than that values
4546 are invisible. */
4547 if (it->selective > 0
4548 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4549 (double) it->selective)) /* iftc */
4550 visible_p = 0;
4551 else
4552 {
4553 Lisp_Object prop;
4554
4555 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4556 Qinvisible, it->window);
4557 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4558 visible_p = 0;
4559 }
4560
4561 if (visible_p)
4562 {
4563 struct it it2 = *it;
4564
4565 if (handle_display_prop (&it2) == HANDLED_RETURN)
4566 visible_p = 0;
4567 }
4568
4569 /* Back one more newline if the current one is invisible. */
4570 if (!visible_p)
4571 back_to_previous_line_start (it);
4572 }
4573
4574 xassert (IT_CHARPOS (*it) >= BEGV);
4575 xassert (IT_CHARPOS (*it) == BEGV
4576 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4577 CHECK_IT (it);
4578 }
4579
4580
4581 /* Reseat iterator IT at the previous visible line start. Skip
4582 invisible text that is so either due to text properties or due to
4583 selective display. At the end, update IT's overlay information,
4584 face information etc. */
4585
4586 static void
4587 reseat_at_previous_visible_line_start (it)
4588 struct it *it;
4589 {
4590 back_to_previous_visible_line_start (it);
4591 reseat (it, it->current.pos, 1);
4592 CHECK_IT (it);
4593 }
4594
4595
4596 /* Reseat iterator IT on the next visible line start in the current
4597 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4598 preceding the line start. Skip over invisible text that is so
4599 because of selective display. Compute faces, overlays etc at the
4600 new position. Note that this function does not skip over text that
4601 is invisible because of text properties. */
4602
4603 static void
4604 reseat_at_next_visible_line_start (it, on_newline_p)
4605 struct it *it;
4606 int on_newline_p;
4607 {
4608 int newline_found_p, skipped_p = 0;
4609
4610 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4611
4612 /* Skip over lines that are invisible because they are indented
4613 more than the value of IT->selective. */
4614 if (it->selective > 0)
4615 while (IT_CHARPOS (*it) < ZV
4616 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4617 (double) it->selective)) /* iftc */
4618 {
4619 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4620 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4621 }
4622
4623 /* Position on the newline if that's what's requested. */
4624 if (on_newline_p && newline_found_p)
4625 {
4626 if (STRINGP (it->string))
4627 {
4628 if (IT_STRING_CHARPOS (*it) > 0)
4629 {
4630 --IT_STRING_CHARPOS (*it);
4631 --IT_STRING_BYTEPOS (*it);
4632 }
4633 }
4634 else if (IT_CHARPOS (*it) > BEGV)
4635 {
4636 --IT_CHARPOS (*it);
4637 --IT_BYTEPOS (*it);
4638 reseat (it, it->current.pos, 0);
4639 }
4640 }
4641 else if (skipped_p)
4642 reseat (it, it->current.pos, 0);
4643
4644 CHECK_IT (it);
4645 }
4646
4647
4648 \f
4649 /***********************************************************************
4650 Changing an iterator's position
4651 ***********************************************************************/
4652
4653 /* Change IT's current position to POS in current_buffer. If FORCE_P
4654 is non-zero, always check for text properties at the new position.
4655 Otherwise, text properties are only looked up if POS >=
4656 IT->check_charpos of a property. */
4657
4658 static void
4659 reseat (it, pos, force_p)
4660 struct it *it;
4661 struct text_pos pos;
4662 int force_p;
4663 {
4664 int original_pos = IT_CHARPOS (*it);
4665
4666 reseat_1 (it, pos, 0);
4667
4668 /* Determine where to check text properties. Avoid doing it
4669 where possible because text property lookup is very expensive. */
4670 if (force_p
4671 || CHARPOS (pos) > it->stop_charpos
4672 || CHARPOS (pos) < original_pos)
4673 handle_stop (it);
4674
4675 CHECK_IT (it);
4676 }
4677
4678
4679 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4680 IT->stop_pos to POS, also. */
4681
4682 static void
4683 reseat_1 (it, pos, set_stop_p)
4684 struct it *it;
4685 struct text_pos pos;
4686 int set_stop_p;
4687 {
4688 /* Don't call this function when scanning a C string. */
4689 xassert (it->s == NULL);
4690
4691 /* POS must be a reasonable value. */
4692 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4693
4694 it->current.pos = it->position = pos;
4695 XSETBUFFER (it->object, current_buffer);
4696 it->end_charpos = ZV;
4697 it->dpvec = NULL;
4698 it->current.dpvec_index = -1;
4699 it->current.overlay_string_index = -1;
4700 IT_STRING_CHARPOS (*it) = -1;
4701 IT_STRING_BYTEPOS (*it) = -1;
4702 it->string = Qnil;
4703 it->method = next_element_from_buffer;
4704 /* RMS: I added this to fix a bug in move_it_vertically_backward
4705 where it->area continued to relate to the starting point
4706 for the backward motion. Bug report from
4707 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4708 However, I am not sure whether reseat still does the right thing
4709 in general after this change. */
4710 it->area = TEXT_AREA;
4711 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4712 it->sp = 0;
4713 it->face_before_selective_p = 0;
4714
4715 if (set_stop_p)
4716 it->stop_charpos = CHARPOS (pos);
4717 }
4718
4719
4720 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4721 If S is non-null, it is a C string to iterate over. Otherwise,
4722 STRING gives a Lisp string to iterate over.
4723
4724 If PRECISION > 0, don't return more then PRECISION number of
4725 characters from the string.
4726
4727 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4728 characters have been returned. FIELD_WIDTH < 0 means an infinite
4729 field width.
4730
4731 MULTIBYTE = 0 means disable processing of multibyte characters,
4732 MULTIBYTE > 0 means enable it,
4733 MULTIBYTE < 0 means use IT->multibyte_p.
4734
4735 IT must be initialized via a prior call to init_iterator before
4736 calling this function. */
4737
4738 static void
4739 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4740 struct it *it;
4741 unsigned char *s;
4742 Lisp_Object string;
4743 int charpos;
4744 int precision, field_width, multibyte;
4745 {
4746 /* No region in strings. */
4747 it->region_beg_charpos = it->region_end_charpos = -1;
4748
4749 /* No text property checks performed by default, but see below. */
4750 it->stop_charpos = -1;
4751
4752 /* Set iterator position and end position. */
4753 bzero (&it->current, sizeof it->current);
4754 it->current.overlay_string_index = -1;
4755 it->current.dpvec_index = -1;
4756 xassert (charpos >= 0);
4757
4758 /* If STRING is specified, use its multibyteness, otherwise use the
4759 setting of MULTIBYTE, if specified. */
4760 if (multibyte >= 0)
4761 it->multibyte_p = multibyte > 0;
4762
4763 if (s == NULL)
4764 {
4765 xassert (STRINGP (string));
4766 it->string = string;
4767 it->s = NULL;
4768 it->end_charpos = it->string_nchars = SCHARS (string);
4769 it->method = next_element_from_string;
4770 it->current.string_pos = string_pos (charpos, string);
4771 }
4772 else
4773 {
4774 it->s = s;
4775 it->string = Qnil;
4776
4777 /* Note that we use IT->current.pos, not it->current.string_pos,
4778 for displaying C strings. */
4779 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4780 if (it->multibyte_p)
4781 {
4782 it->current.pos = c_string_pos (charpos, s, 1);
4783 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4784 }
4785 else
4786 {
4787 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4788 it->end_charpos = it->string_nchars = strlen (s);
4789 }
4790
4791 it->method = next_element_from_c_string;
4792 }
4793
4794 /* PRECISION > 0 means don't return more than PRECISION characters
4795 from the string. */
4796 if (precision > 0 && it->end_charpos - charpos > precision)
4797 it->end_charpos = it->string_nchars = charpos + precision;
4798
4799 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4800 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4801 FIELD_WIDTH < 0 means infinite field width. This is useful for
4802 padding with `-' at the end of a mode line. */
4803 if (field_width < 0)
4804 field_width = INFINITY;
4805 if (field_width > it->end_charpos - charpos)
4806 it->end_charpos = charpos + field_width;
4807
4808 /* Use the standard display table for displaying strings. */
4809 if (DISP_TABLE_P (Vstandard_display_table))
4810 it->dp = XCHAR_TABLE (Vstandard_display_table);
4811
4812 it->stop_charpos = charpos;
4813 CHECK_IT (it);
4814 }
4815
4816
4817 \f
4818 /***********************************************************************
4819 Iteration
4820 ***********************************************************************/
4821
4822 /* Load IT's display element fields with information about the next
4823 display element from the current position of IT. Value is zero if
4824 end of buffer (or C string) is reached. */
4825
4826 int
4827 get_next_display_element (it)
4828 struct it *it;
4829 {
4830 /* Non-zero means that we found a display element. Zero means that
4831 we hit the end of what we iterate over. Performance note: the
4832 function pointer `method' used here turns out to be faster than
4833 using a sequence of if-statements. */
4834 int success_p = (*it->method) (it);
4835
4836 if (it->what == IT_CHARACTER)
4837 {
4838 /* Map via display table or translate control characters.
4839 IT->c, IT->len etc. have been set to the next character by
4840 the function call above. If we have a display table, and it
4841 contains an entry for IT->c, translate it. Don't do this if
4842 IT->c itself comes from a display table, otherwise we could
4843 end up in an infinite recursion. (An alternative could be to
4844 count the recursion depth of this function and signal an
4845 error when a certain maximum depth is reached.) Is it worth
4846 it? */
4847 if (success_p && it->dpvec == NULL)
4848 {
4849 Lisp_Object dv;
4850
4851 if (it->dp
4852 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4853 VECTORP (dv)))
4854 {
4855 struct Lisp_Vector *v = XVECTOR (dv);
4856
4857 /* Return the first character from the display table
4858 entry, if not empty. If empty, don't display the
4859 current character. */
4860 if (v->size)
4861 {
4862 it->dpvec_char_len = it->len;
4863 it->dpvec = v->contents;
4864 it->dpend = v->contents + v->size;
4865 it->current.dpvec_index = 0;
4866 it->method = next_element_from_display_vector;
4867 success_p = get_next_display_element (it);
4868 }
4869 else
4870 {
4871 set_iterator_to_next (it, 0);
4872 success_p = get_next_display_element (it);
4873 }
4874 }
4875
4876 /* Translate control characters into `\003' or `^C' form.
4877 Control characters coming from a display table entry are
4878 currently not translated because we use IT->dpvec to hold
4879 the translation. This could easily be changed but I
4880 don't believe that it is worth doing.
4881
4882 If it->multibyte_p is nonzero, eight-bit characters and
4883 non-printable multibyte characters are also translated to
4884 octal form.
4885
4886 If it->multibyte_p is zero, eight-bit characters that
4887 don't have corresponding multibyte char code are also
4888 translated to octal form. */
4889 else if ((it->c < ' '
4890 && (it->area != TEXT_AREA
4891 || (it->c != '\n' && it->c != '\t')))
4892 || (it->multibyte_p
4893 ? ((it->c >= 127
4894 && it->len == 1)
4895 || !CHAR_PRINTABLE_P (it->c))
4896 : (it->c >= 127
4897 && it->c == unibyte_char_to_multibyte (it->c))))
4898 {
4899 /* IT->c is a control character which must be displayed
4900 either as '\003' or as `^C' where the '\\' and '^'
4901 can be defined in the display table. Fill
4902 IT->ctl_chars with glyphs for what we have to
4903 display. Then, set IT->dpvec to these glyphs. */
4904 GLYPH g;
4905
4906 if (it->c < 128 && it->ctl_arrow_p)
4907 {
4908 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4909 if (it->dp
4910 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4911 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4912 g = XINT (DISP_CTRL_GLYPH (it->dp));
4913 else
4914 g = FAST_MAKE_GLYPH ('^', 0);
4915 XSETINT (it->ctl_chars[0], g);
4916
4917 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4918 XSETINT (it->ctl_chars[1], g);
4919
4920 /* Set up IT->dpvec and return first character from it. */
4921 it->dpvec_char_len = it->len;
4922 it->dpvec = it->ctl_chars;
4923 it->dpend = it->dpvec + 2;
4924 it->current.dpvec_index = 0;
4925 it->method = next_element_from_display_vector;
4926 get_next_display_element (it);
4927 }
4928 else
4929 {
4930 unsigned char str[MAX_MULTIBYTE_LENGTH];
4931 int len;
4932 int i;
4933 GLYPH escape_glyph;
4934
4935 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4936 if (it->dp
4937 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4938 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4939 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4940 else
4941 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4942
4943 if (SINGLE_BYTE_CHAR_P (it->c))
4944 str[0] = it->c, len = 1;
4945 else
4946 {
4947 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4948 if (len < 0)
4949 {
4950 /* It's an invalid character, which
4951 shouldn't happen actually, but due to
4952 bugs it may happen. Let's print the char
4953 as is, there's not much meaningful we can
4954 do with it. */
4955 str[0] = it->c;
4956 str[1] = it->c >> 8;
4957 str[2] = it->c >> 16;
4958 str[3] = it->c >> 24;
4959 len = 4;
4960 }
4961 }
4962
4963 for (i = 0; i < len; i++)
4964 {
4965 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4966 /* Insert three more glyphs into IT->ctl_chars for
4967 the octal display of the character. */
4968 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4969 XSETINT (it->ctl_chars[i * 4 + 1], g);
4970 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4971 XSETINT (it->ctl_chars[i * 4 + 2], g);
4972 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4973 XSETINT (it->ctl_chars[i * 4 + 3], g);
4974 }
4975
4976 /* Set up IT->dpvec and return the first character
4977 from it. */
4978 it->dpvec_char_len = it->len;
4979 it->dpvec = it->ctl_chars;
4980 it->dpend = it->dpvec + len * 4;
4981 it->current.dpvec_index = 0;
4982 it->method = next_element_from_display_vector;
4983 get_next_display_element (it);
4984 }
4985 }
4986 }
4987
4988 /* Adjust face id for a multibyte character. There are no
4989 multibyte character in unibyte text. */
4990 if (it->multibyte_p
4991 && success_p
4992 && FRAME_WINDOW_P (it->f))
4993 {
4994 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4995 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4996 }
4997 }
4998
4999 /* Is this character the last one of a run of characters with
5000 box? If yes, set IT->end_of_box_run_p to 1. */
5001 if (it->face_box_p
5002 && it->s == NULL)
5003 {
5004 int face_id;
5005 struct face *face;
5006
5007 it->end_of_box_run_p
5008 = ((face_id = face_after_it_pos (it),
5009 face_id != it->face_id)
5010 && (face = FACE_FROM_ID (it->f, face_id),
5011 face->box == FACE_NO_BOX));
5012 }
5013
5014 /* Value is 0 if end of buffer or string reached. */
5015 return success_p;
5016 }
5017
5018
5019 /* Move IT to the next display element.
5020
5021 RESEAT_P non-zero means if called on a newline in buffer text,
5022 skip to the next visible line start.
5023
5024 Functions get_next_display_element and set_iterator_to_next are
5025 separate because I find this arrangement easier to handle than a
5026 get_next_display_element function that also increments IT's
5027 position. The way it is we can first look at an iterator's current
5028 display element, decide whether it fits on a line, and if it does,
5029 increment the iterator position. The other way around we probably
5030 would either need a flag indicating whether the iterator has to be
5031 incremented the next time, or we would have to implement a
5032 decrement position function which would not be easy to write. */
5033
5034 void
5035 set_iterator_to_next (it, reseat_p)
5036 struct it *it;
5037 int reseat_p;
5038 {
5039 /* Reset flags indicating start and end of a sequence of characters
5040 with box. Reset them at the start of this function because
5041 moving the iterator to a new position might set them. */
5042 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5043
5044 if (it->method == next_element_from_buffer)
5045 {
5046 /* The current display element of IT is a character from
5047 current_buffer. Advance in the buffer, and maybe skip over
5048 invisible lines that are so because of selective display. */
5049 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5050 reseat_at_next_visible_line_start (it, 0);
5051 else
5052 {
5053 xassert (it->len != 0);
5054 IT_BYTEPOS (*it) += it->len;
5055 IT_CHARPOS (*it) += 1;
5056 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5057 }
5058 }
5059 else if (it->method == next_element_from_composition)
5060 {
5061 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5062 if (STRINGP (it->string))
5063 {
5064 IT_STRING_BYTEPOS (*it) += it->len;
5065 IT_STRING_CHARPOS (*it) += it->cmp_len;
5066 it->method = next_element_from_string;
5067 goto consider_string_end;
5068 }
5069 else
5070 {
5071 IT_BYTEPOS (*it) += it->len;
5072 IT_CHARPOS (*it) += it->cmp_len;
5073 it->method = next_element_from_buffer;
5074 }
5075 }
5076 else if (it->method == next_element_from_c_string)
5077 {
5078 /* Current display element of IT is from a C string. */
5079 IT_BYTEPOS (*it) += it->len;
5080 IT_CHARPOS (*it) += 1;
5081 }
5082 else if (it->method == next_element_from_display_vector)
5083 {
5084 /* Current display element of IT is from a display table entry.
5085 Advance in the display table definition. Reset it to null if
5086 end reached, and continue with characters from buffers/
5087 strings. */
5088 ++it->current.dpvec_index;
5089
5090 /* Restore face of the iterator to what they were before the
5091 display vector entry (these entries may contain faces). */
5092 it->face_id = it->saved_face_id;
5093
5094 if (it->dpvec + it->current.dpvec_index == it->dpend)
5095 {
5096 if (it->s)
5097 it->method = next_element_from_c_string;
5098 else if (STRINGP (it->string))
5099 it->method = next_element_from_string;
5100 else
5101 it->method = next_element_from_buffer;
5102
5103 it->dpvec = NULL;
5104 it->current.dpvec_index = -1;
5105
5106 /* Skip over characters which were displayed via IT->dpvec. */
5107 if (it->dpvec_char_len < 0)
5108 reseat_at_next_visible_line_start (it, 1);
5109 else if (it->dpvec_char_len > 0)
5110 {
5111 it->len = it->dpvec_char_len;
5112 set_iterator_to_next (it, reseat_p);
5113 }
5114 }
5115 }
5116 else if (it->method == next_element_from_string)
5117 {
5118 /* Current display element is a character from a Lisp string. */
5119 xassert (it->s == NULL && STRINGP (it->string));
5120 IT_STRING_BYTEPOS (*it) += it->len;
5121 IT_STRING_CHARPOS (*it) += 1;
5122
5123 consider_string_end:
5124
5125 if (it->current.overlay_string_index >= 0)
5126 {
5127 /* IT->string is an overlay string. Advance to the
5128 next, if there is one. */
5129 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5130 next_overlay_string (it);
5131 }
5132 else
5133 {
5134 /* IT->string is not an overlay string. If we reached
5135 its end, and there is something on IT->stack, proceed
5136 with what is on the stack. This can be either another
5137 string, this time an overlay string, or a buffer. */
5138 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5139 && it->sp > 0)
5140 {
5141 pop_it (it);
5142 if (!STRINGP (it->string))
5143 it->method = next_element_from_buffer;
5144 else
5145 goto consider_string_end;
5146 }
5147 }
5148 }
5149 else if (it->method == next_element_from_image
5150 || it->method == next_element_from_stretch)
5151 {
5152 /* The position etc with which we have to proceed are on
5153 the stack. The position may be at the end of a string,
5154 if the `display' property takes up the whole string. */
5155 pop_it (it);
5156 it->image_id = 0;
5157 if (STRINGP (it->string))
5158 {
5159 it->method = next_element_from_string;
5160 goto consider_string_end;
5161 }
5162 else
5163 it->method = next_element_from_buffer;
5164 }
5165 else
5166 /* There are no other methods defined, so this should be a bug. */
5167 abort ();
5168
5169 xassert (it->method != next_element_from_string
5170 || (STRINGP (it->string)
5171 && IT_STRING_CHARPOS (*it) >= 0));
5172 }
5173
5174
5175 /* Load IT's display element fields with information about the next
5176 display element which comes from a display table entry or from the
5177 result of translating a control character to one of the forms `^C'
5178 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5179
5180 static int
5181 next_element_from_display_vector (it)
5182 struct it *it;
5183 {
5184 /* Precondition. */
5185 xassert (it->dpvec && it->current.dpvec_index >= 0);
5186
5187 /* Remember the current face id in case glyphs specify faces.
5188 IT's face is restored in set_iterator_to_next. */
5189 it->saved_face_id = it->face_id;
5190
5191 if (INTEGERP (*it->dpvec)
5192 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5193 {
5194 int lface_id;
5195 GLYPH g;
5196
5197 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5198 it->c = FAST_GLYPH_CHAR (g);
5199 it->len = CHAR_BYTES (it->c);
5200
5201 /* The entry may contain a face id to use. Such a face id is
5202 the id of a Lisp face, not a realized face. A face id of
5203 zero means no face is specified. */
5204 lface_id = FAST_GLYPH_FACE (g);
5205 if (lface_id)
5206 {
5207 /* The function returns -1 if lface_id is invalid. */
5208 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5209 if (face_id >= 0)
5210 it->face_id = face_id;
5211 }
5212 }
5213 else
5214 /* Display table entry is invalid. Return a space. */
5215 it->c = ' ', it->len = 1;
5216
5217 /* Don't change position and object of the iterator here. They are
5218 still the values of the character that had this display table
5219 entry or was translated, and that's what we want. */
5220 it->what = IT_CHARACTER;
5221 return 1;
5222 }
5223
5224
5225 /* Load IT with the next display element from Lisp string IT->string.
5226 IT->current.string_pos is the current position within the string.
5227 If IT->current.overlay_string_index >= 0, the Lisp string is an
5228 overlay string. */
5229
5230 static int
5231 next_element_from_string (it)
5232 struct it *it;
5233 {
5234 struct text_pos position;
5235
5236 xassert (STRINGP (it->string));
5237 xassert (IT_STRING_CHARPOS (*it) >= 0);
5238 position = it->current.string_pos;
5239
5240 /* Time to check for invisible text? */
5241 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5242 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5243 {
5244 handle_stop (it);
5245
5246 /* Since a handler may have changed IT->method, we must
5247 recurse here. */
5248 return get_next_display_element (it);
5249 }
5250
5251 if (it->current.overlay_string_index >= 0)
5252 {
5253 /* Get the next character from an overlay string. In overlay
5254 strings, There is no field width or padding with spaces to
5255 do. */
5256 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5257 {
5258 it->what = IT_EOB;
5259 return 0;
5260 }
5261 else if (STRING_MULTIBYTE (it->string))
5262 {
5263 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5264 const unsigned char *s = (SDATA (it->string)
5265 + IT_STRING_BYTEPOS (*it));
5266 it->c = string_char_and_length (s, remaining, &it->len);
5267 }
5268 else
5269 {
5270 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5271 it->len = 1;
5272 }
5273 }
5274 else
5275 {
5276 /* Get the next character from a Lisp string that is not an
5277 overlay string. Such strings come from the mode line, for
5278 example. We may have to pad with spaces, or truncate the
5279 string. See also next_element_from_c_string. */
5280 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5281 {
5282 it->what = IT_EOB;
5283 return 0;
5284 }
5285 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5286 {
5287 /* Pad with spaces. */
5288 it->c = ' ', it->len = 1;
5289 CHARPOS (position) = BYTEPOS (position) = -1;
5290 }
5291 else if (STRING_MULTIBYTE (it->string))
5292 {
5293 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5294 const unsigned char *s = (SDATA (it->string)
5295 + IT_STRING_BYTEPOS (*it));
5296 it->c = string_char_and_length (s, maxlen, &it->len);
5297 }
5298 else
5299 {
5300 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5301 it->len = 1;
5302 }
5303 }
5304
5305 /* Record what we have and where it came from. Note that we store a
5306 buffer position in IT->position although it could arguably be a
5307 string position. */
5308 it->what = IT_CHARACTER;
5309 it->object = it->string;
5310 it->position = position;
5311 return 1;
5312 }
5313
5314
5315 /* Load IT with next display element from C string IT->s.
5316 IT->string_nchars is the maximum number of characters to return
5317 from the string. IT->end_charpos may be greater than
5318 IT->string_nchars when this function is called, in which case we
5319 may have to return padding spaces. Value is zero if end of string
5320 reached, including padding spaces. */
5321
5322 static int
5323 next_element_from_c_string (it)
5324 struct it *it;
5325 {
5326 int success_p = 1;
5327
5328 xassert (it->s);
5329 it->what = IT_CHARACTER;
5330 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5331 it->object = Qnil;
5332
5333 /* IT's position can be greater IT->string_nchars in case a field
5334 width or precision has been specified when the iterator was
5335 initialized. */
5336 if (IT_CHARPOS (*it) >= it->end_charpos)
5337 {
5338 /* End of the game. */
5339 it->what = IT_EOB;
5340 success_p = 0;
5341 }
5342 else if (IT_CHARPOS (*it) >= it->string_nchars)
5343 {
5344 /* Pad with spaces. */
5345 it->c = ' ', it->len = 1;
5346 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5347 }
5348 else if (it->multibyte_p)
5349 {
5350 /* Implementation note: The calls to strlen apparently aren't a
5351 performance problem because there is no noticeable performance
5352 difference between Emacs running in unibyte or multibyte mode. */
5353 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5354 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5355 maxlen, &it->len);
5356 }
5357 else
5358 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5359
5360 return success_p;
5361 }
5362
5363
5364 /* Set up IT to return characters from an ellipsis, if appropriate.
5365 The definition of the ellipsis glyphs may come from a display table
5366 entry. This function Fills IT with the first glyph from the
5367 ellipsis if an ellipsis is to be displayed. */
5368
5369 static int
5370 next_element_from_ellipsis (it)
5371 struct it *it;
5372 {
5373 if (it->selective_display_ellipsis_p)
5374 {
5375 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5376 {
5377 /* Use the display table definition for `...'. Invalid glyphs
5378 will be handled by the method returning elements from dpvec. */
5379 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5380 it->dpvec_char_len = it->len;
5381 it->dpvec = v->contents;
5382 it->dpend = v->contents + v->size;
5383 it->current.dpvec_index = 0;
5384 it->method = next_element_from_display_vector;
5385 }
5386 else
5387 {
5388 /* Use default `...' which is stored in default_invis_vector. */
5389 it->dpvec_char_len = it->len;
5390 it->dpvec = default_invis_vector;
5391 it->dpend = default_invis_vector + 3;
5392 it->current.dpvec_index = 0;
5393 it->method = next_element_from_display_vector;
5394 }
5395 }
5396 else
5397 {
5398 /* The face at the current position may be different from the
5399 face we find after the invisible text. Remember what it
5400 was in IT->saved_face_id, and signal that it's there by
5401 setting face_before_selective_p. */
5402 it->saved_face_id = it->face_id;
5403 it->method = next_element_from_buffer;
5404 reseat_at_next_visible_line_start (it, 1);
5405 it->face_before_selective_p = 1;
5406 }
5407
5408 return get_next_display_element (it);
5409 }
5410
5411
5412 /* Deliver an image display element. The iterator IT is already
5413 filled with image information (done in handle_display_prop). Value
5414 is always 1. */
5415
5416
5417 static int
5418 next_element_from_image (it)
5419 struct it *it;
5420 {
5421 it->what = IT_IMAGE;
5422 return 1;
5423 }
5424
5425
5426 /* Fill iterator IT with next display element from a stretch glyph
5427 property. IT->object is the value of the text property. Value is
5428 always 1. */
5429
5430 static int
5431 next_element_from_stretch (it)
5432 struct it *it;
5433 {
5434 it->what = IT_STRETCH;
5435 return 1;
5436 }
5437
5438
5439 /* Load IT with the next display element from current_buffer. Value
5440 is zero if end of buffer reached. IT->stop_charpos is the next
5441 position at which to stop and check for text properties or buffer
5442 end. */
5443
5444 static int
5445 next_element_from_buffer (it)
5446 struct it *it;
5447 {
5448 int success_p = 1;
5449
5450 /* Check this assumption, otherwise, we would never enter the
5451 if-statement, below. */
5452 xassert (IT_CHARPOS (*it) >= BEGV
5453 && IT_CHARPOS (*it) <= it->stop_charpos);
5454
5455 if (IT_CHARPOS (*it) >= it->stop_charpos)
5456 {
5457 if (IT_CHARPOS (*it) >= it->end_charpos)
5458 {
5459 int overlay_strings_follow_p;
5460
5461 /* End of the game, except when overlay strings follow that
5462 haven't been returned yet. */
5463 if (it->overlay_strings_at_end_processed_p)
5464 overlay_strings_follow_p = 0;
5465 else
5466 {
5467 it->overlay_strings_at_end_processed_p = 1;
5468 overlay_strings_follow_p = get_overlay_strings (it, 0);
5469 }
5470
5471 if (overlay_strings_follow_p)
5472 success_p = get_next_display_element (it);
5473 else
5474 {
5475 it->what = IT_EOB;
5476 it->position = it->current.pos;
5477 success_p = 0;
5478 }
5479 }
5480 else
5481 {
5482 handle_stop (it);
5483 return get_next_display_element (it);
5484 }
5485 }
5486 else
5487 {
5488 /* No face changes, overlays etc. in sight, so just return a
5489 character from current_buffer. */
5490 unsigned char *p;
5491
5492 /* Maybe run the redisplay end trigger hook. Performance note:
5493 This doesn't seem to cost measurable time. */
5494 if (it->redisplay_end_trigger_charpos
5495 && it->glyph_row
5496 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5497 run_redisplay_end_trigger_hook (it);
5498
5499 /* Get the next character, maybe multibyte. */
5500 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5501 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5502 {
5503 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5504 - IT_BYTEPOS (*it));
5505 it->c = string_char_and_length (p, maxlen, &it->len);
5506 }
5507 else
5508 it->c = *p, it->len = 1;
5509
5510 /* Record what we have and where it came from. */
5511 it->what = IT_CHARACTER;;
5512 it->object = it->w->buffer;
5513 it->position = it->current.pos;
5514
5515 /* Normally we return the character found above, except when we
5516 really want to return an ellipsis for selective display. */
5517 if (it->selective)
5518 {
5519 if (it->c == '\n')
5520 {
5521 /* A value of selective > 0 means hide lines indented more
5522 than that number of columns. */
5523 if (it->selective > 0
5524 && IT_CHARPOS (*it) + 1 < ZV
5525 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5526 IT_BYTEPOS (*it) + 1,
5527 (double) it->selective)) /* iftc */
5528 {
5529 success_p = next_element_from_ellipsis (it);
5530 it->dpvec_char_len = -1;
5531 }
5532 }
5533 else if (it->c == '\r' && it->selective == -1)
5534 {
5535 /* A value of selective == -1 means that everything from the
5536 CR to the end of the line is invisible, with maybe an
5537 ellipsis displayed for it. */
5538 success_p = next_element_from_ellipsis (it);
5539 it->dpvec_char_len = -1;
5540 }
5541 }
5542 }
5543
5544 /* Value is zero if end of buffer reached. */
5545 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5546 return success_p;
5547 }
5548
5549
5550 /* Run the redisplay end trigger hook for IT. */
5551
5552 static void
5553 run_redisplay_end_trigger_hook (it)
5554 struct it *it;
5555 {
5556 Lisp_Object args[3];
5557
5558 /* IT->glyph_row should be non-null, i.e. we should be actually
5559 displaying something, or otherwise we should not run the hook. */
5560 xassert (it->glyph_row);
5561
5562 /* Set up hook arguments. */
5563 args[0] = Qredisplay_end_trigger_functions;
5564 args[1] = it->window;
5565 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5566 it->redisplay_end_trigger_charpos = 0;
5567
5568 /* Since we are *trying* to run these functions, don't try to run
5569 them again, even if they get an error. */
5570 it->w->redisplay_end_trigger = Qnil;
5571 Frun_hook_with_args (3, args);
5572
5573 /* Notice if it changed the face of the character we are on. */
5574 handle_face_prop (it);
5575 }
5576
5577
5578 /* Deliver a composition display element. The iterator IT is already
5579 filled with composition information (done in
5580 handle_composition_prop). Value is always 1. */
5581
5582 static int
5583 next_element_from_composition (it)
5584 struct it *it;
5585 {
5586 it->what = IT_COMPOSITION;
5587 it->position = (STRINGP (it->string)
5588 ? it->current.string_pos
5589 : it->current.pos);
5590 return 1;
5591 }
5592
5593
5594 \f
5595 /***********************************************************************
5596 Moving an iterator without producing glyphs
5597 ***********************************************************************/
5598
5599 /* Move iterator IT to a specified buffer or X position within one
5600 line on the display without producing glyphs.
5601
5602 OP should be a bit mask including some or all of these bits:
5603 MOVE_TO_X: Stop on reaching x-position TO_X.
5604 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5605 Regardless of OP's value, stop in reaching the end of the display line.
5606
5607 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5608 This means, in particular, that TO_X includes window's horizontal
5609 scroll amount.
5610
5611 The return value has several possible values that
5612 say what condition caused the scan to stop:
5613
5614 MOVE_POS_MATCH_OR_ZV
5615 - when TO_POS or ZV was reached.
5616
5617 MOVE_X_REACHED
5618 -when TO_X was reached before TO_POS or ZV were reached.
5619
5620 MOVE_LINE_CONTINUED
5621 - when we reached the end of the display area and the line must
5622 be continued.
5623
5624 MOVE_LINE_TRUNCATED
5625 - when we reached the end of the display area and the line is
5626 truncated.
5627
5628 MOVE_NEWLINE_OR_CR
5629 - when we stopped at a line end, i.e. a newline or a CR and selective
5630 display is on. */
5631
5632 static enum move_it_result
5633 move_it_in_display_line_to (it, to_charpos, to_x, op)
5634 struct it *it;
5635 int to_charpos, to_x, op;
5636 {
5637 enum move_it_result result = MOVE_UNDEFINED;
5638 struct glyph_row *saved_glyph_row;
5639
5640 /* Don't produce glyphs in produce_glyphs. */
5641 saved_glyph_row = it->glyph_row;
5642 it->glyph_row = NULL;
5643
5644 #define BUFFER_POS_REACHED_P() \
5645 ((op & MOVE_TO_POS) != 0 \
5646 && BUFFERP (it->object) \
5647 && IT_CHARPOS (*it) >= to_charpos)
5648
5649 while (1)
5650 {
5651 int x, i, ascent = 0, descent = 0;
5652
5653 /* Stop when ZV reached.
5654 We used to stop here when TO_CHARPOS reached as well, but that is
5655 too soon if this glyph does not fit on this line. So we handle it
5656 explicitly below. */
5657 if (!get_next_display_element (it)
5658 || (it->truncate_lines_p
5659 && BUFFER_POS_REACHED_P ()))
5660 {
5661 result = MOVE_POS_MATCH_OR_ZV;
5662 break;
5663 }
5664
5665 /* The call to produce_glyphs will get the metrics of the
5666 display element IT is loaded with. We record in x the
5667 x-position before this display element in case it does not
5668 fit on the line. */
5669 x = it->current_x;
5670
5671 /* Remember the line height so far in case the next element doesn't
5672 fit on the line. */
5673 if (!it->truncate_lines_p)
5674 {
5675 ascent = it->max_ascent;
5676 descent = it->max_descent;
5677 }
5678
5679 PRODUCE_GLYPHS (it);
5680
5681 if (it->area != TEXT_AREA)
5682 {
5683 set_iterator_to_next (it, 1);
5684 continue;
5685 }
5686
5687 /* The number of glyphs we get back in IT->nglyphs will normally
5688 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5689 character on a terminal frame, or (iii) a line end. For the
5690 second case, IT->nglyphs - 1 padding glyphs will be present
5691 (on X frames, there is only one glyph produced for a
5692 composite character.
5693
5694 The behavior implemented below means, for continuation lines,
5695 that as many spaces of a TAB as fit on the current line are
5696 displayed there. For terminal frames, as many glyphs of a
5697 multi-glyph character are displayed in the current line, too.
5698 This is what the old redisplay code did, and we keep it that
5699 way. Under X, the whole shape of a complex character must
5700 fit on the line or it will be completely displayed in the
5701 next line.
5702
5703 Note that both for tabs and padding glyphs, all glyphs have
5704 the same width. */
5705 if (it->nglyphs)
5706 {
5707 /* More than one glyph or glyph doesn't fit on line. All
5708 glyphs have the same width. */
5709 int single_glyph_width = it->pixel_width / it->nglyphs;
5710 int new_x;
5711
5712 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5713 {
5714 new_x = x + single_glyph_width;
5715
5716 /* We want to leave anything reaching TO_X to the caller. */
5717 if ((op & MOVE_TO_X) && new_x > to_x)
5718 {
5719 if (BUFFER_POS_REACHED_P ())
5720 goto buffer_pos_reached;
5721 it->current_x = x;
5722 result = MOVE_X_REACHED;
5723 break;
5724 }
5725 else if (/* Lines are continued. */
5726 !it->truncate_lines_p
5727 && (/* And glyph doesn't fit on the line. */
5728 new_x > it->last_visible_x
5729 /* Or it fits exactly and we're on a window
5730 system frame. */
5731 || (new_x == it->last_visible_x
5732 && FRAME_WINDOW_P (it->f))))
5733 {
5734 if (/* IT->hpos == 0 means the very first glyph
5735 doesn't fit on the line, e.g. a wide image. */
5736 it->hpos == 0
5737 || (new_x == it->last_visible_x
5738 && FRAME_WINDOW_P (it->f)))
5739 {
5740 ++it->hpos;
5741 it->current_x = new_x;
5742 if (i == it->nglyphs - 1)
5743 {
5744 set_iterator_to_next (it, 1);
5745 #ifdef HAVE_WINDOW_SYSTEM
5746 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5747 {
5748 if (!get_next_display_element (it))
5749 {
5750 result = MOVE_POS_MATCH_OR_ZV;
5751 break;
5752 }
5753 if (BUFFER_POS_REACHED_P ())
5754 {
5755 if (ITERATOR_AT_END_OF_LINE_P (it))
5756 result = MOVE_POS_MATCH_OR_ZV;
5757 else
5758 result = MOVE_LINE_CONTINUED;
5759 break;
5760 }
5761 if (ITERATOR_AT_END_OF_LINE_P (it))
5762 {
5763 result = MOVE_NEWLINE_OR_CR;
5764 break;
5765 }
5766 }
5767 #endif /* HAVE_WINDOW_SYSTEM */
5768 }
5769 }
5770 else
5771 {
5772 it->current_x = x;
5773 it->max_ascent = ascent;
5774 it->max_descent = descent;
5775 }
5776
5777 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5778 IT_CHARPOS (*it)));
5779 result = MOVE_LINE_CONTINUED;
5780 break;
5781 }
5782 else if (BUFFER_POS_REACHED_P ())
5783 goto buffer_pos_reached;
5784 else if (new_x > it->first_visible_x)
5785 {
5786 /* Glyph is visible. Increment number of glyphs that
5787 would be displayed. */
5788 ++it->hpos;
5789 }
5790 else
5791 {
5792 /* Glyph is completely off the left margin of the display
5793 area. Nothing to do. */
5794 }
5795 }
5796
5797 if (result != MOVE_UNDEFINED)
5798 break;
5799 }
5800 else if (BUFFER_POS_REACHED_P ())
5801 {
5802 buffer_pos_reached:
5803 it->current_x = x;
5804 it->max_ascent = ascent;
5805 it->max_descent = descent;
5806 result = MOVE_POS_MATCH_OR_ZV;
5807 break;
5808 }
5809 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5810 {
5811 /* Stop when TO_X specified and reached. This check is
5812 necessary here because of lines consisting of a line end,
5813 only. The line end will not produce any glyphs and we
5814 would never get MOVE_X_REACHED. */
5815 xassert (it->nglyphs == 0);
5816 result = MOVE_X_REACHED;
5817 break;
5818 }
5819
5820 /* Is this a line end? If yes, we're done. */
5821 if (ITERATOR_AT_END_OF_LINE_P (it))
5822 {
5823 result = MOVE_NEWLINE_OR_CR;
5824 break;
5825 }
5826
5827 /* The current display element has been consumed. Advance
5828 to the next. */
5829 set_iterator_to_next (it, 1);
5830
5831 /* Stop if lines are truncated and IT's current x-position is
5832 past the right edge of the window now. */
5833 if (it->truncate_lines_p
5834 && it->current_x >= it->last_visible_x)
5835 {
5836 #ifdef HAVE_WINDOW_SYSTEM
5837 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5838 {
5839 if (!get_next_display_element (it)
5840 || BUFFER_POS_REACHED_P ())
5841 {
5842 result = MOVE_POS_MATCH_OR_ZV;
5843 break;
5844 }
5845 if (ITERATOR_AT_END_OF_LINE_P (it))
5846 {
5847 result = MOVE_NEWLINE_OR_CR;
5848 break;
5849 }
5850 }
5851 #endif /* HAVE_WINDOW_SYSTEM */
5852 result = MOVE_LINE_TRUNCATED;
5853 break;
5854 }
5855 }
5856
5857 #undef BUFFER_POS_REACHED_P
5858
5859 /* Restore the iterator settings altered at the beginning of this
5860 function. */
5861 it->glyph_row = saved_glyph_row;
5862 return result;
5863 }
5864
5865
5866 /* Move IT forward until it satisfies one or more of the criteria in
5867 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5868
5869 OP is a bit-mask that specifies where to stop, and in particular,
5870 which of those four position arguments makes a difference. See the
5871 description of enum move_operation_enum.
5872
5873 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5874 screen line, this function will set IT to the next position >
5875 TO_CHARPOS. */
5876
5877 void
5878 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5879 struct it *it;
5880 int to_charpos, to_x, to_y, to_vpos;
5881 int op;
5882 {
5883 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5884 int line_height;
5885 int reached = 0;
5886
5887 for (;;)
5888 {
5889 if (op & MOVE_TO_VPOS)
5890 {
5891 /* If no TO_CHARPOS and no TO_X specified, stop at the
5892 start of the line TO_VPOS. */
5893 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5894 {
5895 if (it->vpos == to_vpos)
5896 {
5897 reached = 1;
5898 break;
5899 }
5900 else
5901 skip = move_it_in_display_line_to (it, -1, -1, 0);
5902 }
5903 else
5904 {
5905 /* TO_VPOS >= 0 means stop at TO_X in the line at
5906 TO_VPOS, or at TO_POS, whichever comes first. */
5907 if (it->vpos == to_vpos)
5908 {
5909 reached = 2;
5910 break;
5911 }
5912
5913 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5914
5915 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5916 {
5917 reached = 3;
5918 break;
5919 }
5920 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5921 {
5922 /* We have reached TO_X but not in the line we want. */
5923 skip = move_it_in_display_line_to (it, to_charpos,
5924 -1, MOVE_TO_POS);
5925 if (skip == MOVE_POS_MATCH_OR_ZV)
5926 {
5927 reached = 4;
5928 break;
5929 }
5930 }
5931 }
5932 }
5933 else if (op & MOVE_TO_Y)
5934 {
5935 struct it it_backup;
5936
5937 /* TO_Y specified means stop at TO_X in the line containing
5938 TO_Y---or at TO_CHARPOS if this is reached first. The
5939 problem is that we can't really tell whether the line
5940 contains TO_Y before we have completely scanned it, and
5941 this may skip past TO_X. What we do is to first scan to
5942 TO_X.
5943
5944 If TO_X is not specified, use a TO_X of zero. The reason
5945 is to make the outcome of this function more predictable.
5946 If we didn't use TO_X == 0, we would stop at the end of
5947 the line which is probably not what a caller would expect
5948 to happen. */
5949 skip = move_it_in_display_line_to (it, to_charpos,
5950 ((op & MOVE_TO_X)
5951 ? to_x : 0),
5952 (MOVE_TO_X
5953 | (op & MOVE_TO_POS)));
5954
5955 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5956 if (skip == MOVE_POS_MATCH_OR_ZV)
5957 {
5958 reached = 5;
5959 break;
5960 }
5961
5962 /* If TO_X was reached, we would like to know whether TO_Y
5963 is in the line. This can only be said if we know the
5964 total line height which requires us to scan the rest of
5965 the line. */
5966 if (skip == MOVE_X_REACHED)
5967 {
5968 it_backup = *it;
5969 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5970 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5971 op & MOVE_TO_POS);
5972 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5973 }
5974
5975 /* Now, decide whether TO_Y is in this line. */
5976 line_height = it->max_ascent + it->max_descent;
5977 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5978
5979 if (to_y >= it->current_y
5980 && to_y < it->current_y + line_height)
5981 {
5982 if (skip == MOVE_X_REACHED)
5983 /* If TO_Y is in this line and TO_X was reached above,
5984 we scanned too far. We have to restore IT's settings
5985 to the ones before skipping. */
5986 *it = it_backup;
5987 reached = 6;
5988 }
5989 else if (skip == MOVE_X_REACHED)
5990 {
5991 skip = skip2;
5992 if (skip == MOVE_POS_MATCH_OR_ZV)
5993 reached = 7;
5994 }
5995
5996 if (reached)
5997 break;
5998 }
5999 else
6000 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6001
6002 switch (skip)
6003 {
6004 case MOVE_POS_MATCH_OR_ZV:
6005 reached = 8;
6006 goto out;
6007
6008 case MOVE_NEWLINE_OR_CR:
6009 set_iterator_to_next (it, 1);
6010 it->continuation_lines_width = 0;
6011 break;
6012
6013 case MOVE_LINE_TRUNCATED:
6014 it->continuation_lines_width = 0;
6015 reseat_at_next_visible_line_start (it, 0);
6016 if ((op & MOVE_TO_POS) != 0
6017 && IT_CHARPOS (*it) > to_charpos)
6018 {
6019 reached = 9;
6020 goto out;
6021 }
6022 break;
6023
6024 case MOVE_LINE_CONTINUED:
6025 it->continuation_lines_width += it->current_x;
6026 break;
6027
6028 default:
6029 abort ();
6030 }
6031
6032 /* Reset/increment for the next run. */
6033 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6034 it->current_x = it->hpos = 0;
6035 it->current_y += it->max_ascent + it->max_descent;
6036 ++it->vpos;
6037 last_height = it->max_ascent + it->max_descent;
6038 last_max_ascent = it->max_ascent;
6039 it->max_ascent = it->max_descent = 0;
6040 }
6041
6042 out:
6043
6044 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6045 }
6046
6047
6048 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6049
6050 If DY > 0, move IT backward at least that many pixels. DY = 0
6051 means move IT backward to the preceding line start or BEGV. This
6052 function may move over more than DY pixels if IT->current_y - DY
6053 ends up in the middle of a line; in this case IT->current_y will be
6054 set to the top of the line moved to. */
6055
6056 void
6057 move_it_vertically_backward (it, dy)
6058 struct it *it;
6059 int dy;
6060 {
6061 int nlines, h;
6062 struct it it2, it3;
6063 int start_pos = IT_CHARPOS (*it);
6064
6065 xassert (dy >= 0);
6066
6067 /* Estimate how many newlines we must move back. */
6068 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6069
6070 /* Set the iterator's position that many lines back. */
6071 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6072 back_to_previous_visible_line_start (it);
6073
6074 /* Reseat the iterator here. When moving backward, we don't want
6075 reseat to skip forward over invisible text, set up the iterator
6076 to deliver from overlay strings at the new position etc. So,
6077 use reseat_1 here. */
6078 reseat_1 (it, it->current.pos, 1);
6079
6080 /* We are now surely at a line start. */
6081 it->current_x = it->hpos = 0;
6082 it->continuation_lines_width = 0;
6083
6084 /* Move forward and see what y-distance we moved. First move to the
6085 start of the next line so that we get its height. We need this
6086 height to be able to tell whether we reached the specified
6087 y-distance. */
6088 it2 = *it;
6089 it2.max_ascent = it2.max_descent = 0;
6090 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6091 MOVE_TO_POS | MOVE_TO_VPOS);
6092 xassert (IT_CHARPOS (*it) >= BEGV);
6093 it3 = it2;
6094
6095 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6096 xassert (IT_CHARPOS (*it) >= BEGV);
6097 /* H is the actual vertical distance from the position in *IT
6098 and the starting position. */
6099 h = it2.current_y - it->current_y;
6100 /* NLINES is the distance in number of lines. */
6101 nlines = it2.vpos - it->vpos;
6102
6103 /* Correct IT's y and vpos position
6104 so that they are relative to the starting point. */
6105 it->vpos -= nlines;
6106 it->current_y -= h;
6107
6108 if (dy == 0)
6109 {
6110 /* DY == 0 means move to the start of the screen line. The
6111 value of nlines is > 0 if continuation lines were involved. */
6112 if (nlines > 0)
6113 move_it_by_lines (it, nlines, 1);
6114 xassert (IT_CHARPOS (*it) <= start_pos);
6115 }
6116 else
6117 {
6118 /* The y-position we try to reach, relative to *IT.
6119 Note that H has been subtracted in front of the if-statement. */
6120 int target_y = it->current_y + h - dy;
6121 int y0 = it3.current_y;
6122 int y1 = line_bottom_y (&it3);
6123 int line_height = y1 - y0;
6124
6125 /* If we did not reach target_y, try to move further backward if
6126 we can. If we moved too far backward, try to move forward. */
6127 if (target_y < it->current_y
6128 /* This is heuristic. In a window that's 3 lines high, with
6129 a line height of 13 pixels each, recentering with point
6130 on the bottom line will try to move -39/2 = 19 pixels
6131 backward. Try to avoid moving into the first line. */
6132 && it->current_y - target_y > line_height / 3 * 2
6133 && IT_CHARPOS (*it) > BEGV)
6134 {
6135 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6136 target_y - it->current_y));
6137 move_it_vertically (it, target_y - it->current_y);
6138 xassert (IT_CHARPOS (*it) >= BEGV);
6139 }
6140 else if (target_y >= it->current_y + line_height
6141 && IT_CHARPOS (*it) < ZV)
6142 {
6143 /* Should move forward by at least one line, maybe more.
6144
6145 Note: Calling move_it_by_lines can be expensive on
6146 terminal frames, where compute_motion is used (via
6147 vmotion) to do the job, when there are very long lines
6148 and truncate-lines is nil. That's the reason for
6149 treating terminal frames specially here. */
6150
6151 if (!FRAME_WINDOW_P (it->f))
6152 move_it_vertically (it, target_y - (it->current_y + line_height));
6153 else
6154 {
6155 do
6156 {
6157 move_it_by_lines (it, 1, 1);
6158 }
6159 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6160 }
6161
6162 xassert (IT_CHARPOS (*it) >= BEGV);
6163 }
6164 }
6165 }
6166
6167
6168 /* Move IT by a specified amount of pixel lines DY. DY negative means
6169 move backwards. DY = 0 means move to start of screen line. At the
6170 end, IT will be on the start of a screen line. */
6171
6172 void
6173 move_it_vertically (it, dy)
6174 struct it *it;
6175 int dy;
6176 {
6177 if (dy <= 0)
6178 move_it_vertically_backward (it, -dy);
6179 else if (dy > 0)
6180 {
6181 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6182 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6183 MOVE_TO_POS | MOVE_TO_Y);
6184 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6185
6186 /* If buffer ends in ZV without a newline, move to the start of
6187 the line to satisfy the post-condition. */
6188 if (IT_CHARPOS (*it) == ZV
6189 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6190 move_it_by_lines (it, 0, 0);
6191 }
6192 }
6193
6194
6195 /* Move iterator IT past the end of the text line it is in. */
6196
6197 void
6198 move_it_past_eol (it)
6199 struct it *it;
6200 {
6201 enum move_it_result rc;
6202
6203 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6204 if (rc == MOVE_NEWLINE_OR_CR)
6205 set_iterator_to_next (it, 0);
6206 }
6207
6208
6209 #if 0 /* Currently not used. */
6210
6211 /* Return non-zero if some text between buffer positions START_CHARPOS
6212 and END_CHARPOS is invisible. IT->window is the window for text
6213 property lookup. */
6214
6215 static int
6216 invisible_text_between_p (it, start_charpos, end_charpos)
6217 struct it *it;
6218 int start_charpos, end_charpos;
6219 {
6220 Lisp_Object prop, limit;
6221 int invisible_found_p;
6222
6223 xassert (it != NULL && start_charpos <= end_charpos);
6224
6225 /* Is text at START invisible? */
6226 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6227 it->window);
6228 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6229 invisible_found_p = 1;
6230 else
6231 {
6232 limit = Fnext_single_char_property_change (make_number (start_charpos),
6233 Qinvisible, Qnil,
6234 make_number (end_charpos));
6235 invisible_found_p = XFASTINT (limit) < end_charpos;
6236 }
6237
6238 return invisible_found_p;
6239 }
6240
6241 #endif /* 0 */
6242
6243
6244 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6245 negative means move up. DVPOS == 0 means move to the start of the
6246 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6247 NEED_Y_P is zero, IT->current_y will be left unchanged.
6248
6249 Further optimization ideas: If we would know that IT->f doesn't use
6250 a face with proportional font, we could be faster for
6251 truncate-lines nil. */
6252
6253 void
6254 move_it_by_lines (it, dvpos, need_y_p)
6255 struct it *it;
6256 int dvpos, need_y_p;
6257 {
6258 struct position pos;
6259
6260 if (!FRAME_WINDOW_P (it->f))
6261 {
6262 struct text_pos textpos;
6263
6264 /* We can use vmotion on frames without proportional fonts. */
6265 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6266 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6267 reseat (it, textpos, 1);
6268 it->vpos += pos.vpos;
6269 it->current_y += pos.vpos;
6270 }
6271 else if (dvpos == 0)
6272 {
6273 /* DVPOS == 0 means move to the start of the screen line. */
6274 move_it_vertically_backward (it, 0);
6275 xassert (it->current_x == 0 && it->hpos == 0);
6276 }
6277 else if (dvpos > 0)
6278 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6279 else
6280 {
6281 struct it it2;
6282 int start_charpos, i;
6283
6284 /* Start at the beginning of the screen line containing IT's
6285 position. */
6286 move_it_vertically_backward (it, 0);
6287
6288 /* Go back -DVPOS visible lines and reseat the iterator there. */
6289 start_charpos = IT_CHARPOS (*it);
6290 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6291 back_to_previous_visible_line_start (it);
6292 reseat (it, it->current.pos, 1);
6293 it->current_x = it->hpos = 0;
6294
6295 /* Above call may have moved too far if continuation lines
6296 are involved. Scan forward and see if it did. */
6297 it2 = *it;
6298 it2.vpos = it2.current_y = 0;
6299 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6300 it->vpos -= it2.vpos;
6301 it->current_y -= it2.current_y;
6302 it->current_x = it->hpos = 0;
6303
6304 /* If we moved too far, move IT some lines forward. */
6305 if (it2.vpos > -dvpos)
6306 {
6307 int delta = it2.vpos + dvpos;
6308 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6309 }
6310 }
6311 }
6312
6313 /* Return 1 if IT points into the middle of a display vector. */
6314
6315 int
6316 in_display_vector_p (it)
6317 struct it *it;
6318 {
6319 return (it->method == next_element_from_display_vector
6320 && it->current.dpvec_index > 0
6321 && it->dpvec + it->current.dpvec_index != it->dpend);
6322 }
6323
6324 \f
6325 /***********************************************************************
6326 Messages
6327 ***********************************************************************/
6328
6329
6330 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6331 to *Messages*. */
6332
6333 void
6334 add_to_log (format, arg1, arg2)
6335 char *format;
6336 Lisp_Object arg1, arg2;
6337 {
6338 Lisp_Object args[3];
6339 Lisp_Object msg, fmt;
6340 char *buffer;
6341 int len;
6342 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6343 USE_SAFE_ALLOCA;
6344
6345 /* Do nothing if called asynchronously. Inserting text into
6346 a buffer may call after-change-functions and alike and
6347 that would means running Lisp asynchronously. */
6348 if (handling_signal)
6349 return;
6350
6351 fmt = msg = Qnil;
6352 GCPRO4 (fmt, msg, arg1, arg2);
6353
6354 args[0] = fmt = build_string (format);
6355 args[1] = arg1;
6356 args[2] = arg2;
6357 msg = Fformat (3, args);
6358
6359 len = SBYTES (msg) + 1;
6360 SAFE_ALLOCA (buffer, char *, len);
6361 bcopy (SDATA (msg), buffer, len);
6362
6363 message_dolog (buffer, len - 1, 1, 0);
6364 SAFE_FREE (len);
6365
6366 UNGCPRO;
6367 }
6368
6369
6370 /* Output a newline in the *Messages* buffer if "needs" one. */
6371
6372 void
6373 message_log_maybe_newline ()
6374 {
6375 if (message_log_need_newline)
6376 message_dolog ("", 0, 1, 0);
6377 }
6378
6379
6380 /* Add a string M of length NBYTES to the message log, optionally
6381 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6382 nonzero, means interpret the contents of M as multibyte. This
6383 function calls low-level routines in order to bypass text property
6384 hooks, etc. which might not be safe to run. */
6385
6386 void
6387 message_dolog (m, nbytes, nlflag, multibyte)
6388 const char *m;
6389 int nbytes, nlflag, multibyte;
6390 {
6391 if (!NILP (Vmemory_full))
6392 return;
6393
6394 if (!NILP (Vmessage_log_max))
6395 {
6396 struct buffer *oldbuf;
6397 Lisp_Object oldpoint, oldbegv, oldzv;
6398 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6399 int point_at_end = 0;
6400 int zv_at_end = 0;
6401 Lisp_Object old_deactivate_mark, tem;
6402 struct gcpro gcpro1;
6403
6404 old_deactivate_mark = Vdeactivate_mark;
6405 oldbuf = current_buffer;
6406 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6407 current_buffer->undo_list = Qt;
6408
6409 oldpoint = message_dolog_marker1;
6410 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6411 oldbegv = message_dolog_marker2;
6412 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6413 oldzv = message_dolog_marker3;
6414 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6415 GCPRO1 (old_deactivate_mark);
6416
6417 if (PT == Z)
6418 point_at_end = 1;
6419 if (ZV == Z)
6420 zv_at_end = 1;
6421
6422 BEGV = BEG;
6423 BEGV_BYTE = BEG_BYTE;
6424 ZV = Z;
6425 ZV_BYTE = Z_BYTE;
6426 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6427
6428 /* Insert the string--maybe converting multibyte to single byte
6429 or vice versa, so that all the text fits the buffer. */
6430 if (multibyte
6431 && NILP (current_buffer->enable_multibyte_characters))
6432 {
6433 int i, c, char_bytes;
6434 unsigned char work[1];
6435
6436 /* Convert a multibyte string to single-byte
6437 for the *Message* buffer. */
6438 for (i = 0; i < nbytes; i += char_bytes)
6439 {
6440 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6441 work[0] = (SINGLE_BYTE_CHAR_P (c)
6442 ? c
6443 : multibyte_char_to_unibyte (c, Qnil));
6444 insert_1_both (work, 1, 1, 1, 0, 0);
6445 }
6446 }
6447 else if (! multibyte
6448 && ! NILP (current_buffer->enable_multibyte_characters))
6449 {
6450 int i, c, char_bytes;
6451 unsigned char *msg = (unsigned char *) m;
6452 unsigned char str[MAX_MULTIBYTE_LENGTH];
6453 /* Convert a single-byte string to multibyte
6454 for the *Message* buffer. */
6455 for (i = 0; i < nbytes; i++)
6456 {
6457 c = unibyte_char_to_multibyte (msg[i]);
6458 char_bytes = CHAR_STRING (c, str);
6459 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6460 }
6461 }
6462 else if (nbytes)
6463 insert_1 (m, nbytes, 1, 0, 0);
6464
6465 if (nlflag)
6466 {
6467 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6468 insert_1 ("\n", 1, 1, 0, 0);
6469
6470 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6471 this_bol = PT;
6472 this_bol_byte = PT_BYTE;
6473
6474 /* See if this line duplicates the previous one.
6475 If so, combine duplicates. */
6476 if (this_bol > BEG)
6477 {
6478 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6479 prev_bol = PT;
6480 prev_bol_byte = PT_BYTE;
6481
6482 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6483 this_bol, this_bol_byte);
6484 if (dup)
6485 {
6486 del_range_both (prev_bol, prev_bol_byte,
6487 this_bol, this_bol_byte, 0);
6488 if (dup > 1)
6489 {
6490 char dupstr[40];
6491 int duplen;
6492
6493 /* If you change this format, don't forget to also
6494 change message_log_check_duplicate. */
6495 sprintf (dupstr, " [%d times]", dup);
6496 duplen = strlen (dupstr);
6497 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6498 insert_1 (dupstr, duplen, 1, 0, 1);
6499 }
6500 }
6501 }
6502
6503 /* If we have more than the desired maximum number of lines
6504 in the *Messages* buffer now, delete the oldest ones.
6505 This is safe because we don't have undo in this buffer. */
6506
6507 if (NATNUMP (Vmessage_log_max))
6508 {
6509 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6510 -XFASTINT (Vmessage_log_max) - 1, 0);
6511 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6512 }
6513 }
6514 BEGV = XMARKER (oldbegv)->charpos;
6515 BEGV_BYTE = marker_byte_position (oldbegv);
6516
6517 if (zv_at_end)
6518 {
6519 ZV = Z;
6520 ZV_BYTE = Z_BYTE;
6521 }
6522 else
6523 {
6524 ZV = XMARKER (oldzv)->charpos;
6525 ZV_BYTE = marker_byte_position (oldzv);
6526 }
6527
6528 if (point_at_end)
6529 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6530 else
6531 /* We can't do Fgoto_char (oldpoint) because it will run some
6532 Lisp code. */
6533 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6534 XMARKER (oldpoint)->bytepos);
6535
6536 UNGCPRO;
6537 unchain_marker (XMARKER (oldpoint));
6538 unchain_marker (XMARKER (oldbegv));
6539 unchain_marker (XMARKER (oldzv));
6540
6541 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6542 set_buffer_internal (oldbuf);
6543 if (NILP (tem))
6544 windows_or_buffers_changed = old_windows_or_buffers_changed;
6545 message_log_need_newline = !nlflag;
6546 Vdeactivate_mark = old_deactivate_mark;
6547 }
6548 }
6549
6550
6551 /* We are at the end of the buffer after just having inserted a newline.
6552 (Note: We depend on the fact we won't be crossing the gap.)
6553 Check to see if the most recent message looks a lot like the previous one.
6554 Return 0 if different, 1 if the new one should just replace it, or a
6555 value N > 1 if we should also append " [N times]". */
6556
6557 static int
6558 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6559 int prev_bol, this_bol;
6560 int prev_bol_byte, this_bol_byte;
6561 {
6562 int i;
6563 int len = Z_BYTE - 1 - this_bol_byte;
6564 int seen_dots = 0;
6565 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6566 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6567
6568 for (i = 0; i < len; i++)
6569 {
6570 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6571 seen_dots = 1;
6572 if (p1[i] != p2[i])
6573 return seen_dots;
6574 }
6575 p1 += len;
6576 if (*p1 == '\n')
6577 return 2;
6578 if (*p1++ == ' ' && *p1++ == '[')
6579 {
6580 int n = 0;
6581 while (*p1 >= '0' && *p1 <= '9')
6582 n = n * 10 + *p1++ - '0';
6583 if (strncmp (p1, " times]\n", 8) == 0)
6584 return n+1;
6585 }
6586 return 0;
6587 }
6588
6589
6590 /* Display an echo area message M with a specified length of NBYTES
6591 bytes. The string may include null characters. If M is 0, clear
6592 out any existing message, and let the mini-buffer text show
6593 through.
6594
6595 The buffer M must continue to exist until after the echo area gets
6596 cleared or some other message gets displayed there. This means do
6597 not pass text that is stored in a Lisp string; do not pass text in
6598 a buffer that was alloca'd. */
6599
6600 void
6601 message2 (m, nbytes, multibyte)
6602 const char *m;
6603 int nbytes;
6604 int multibyte;
6605 {
6606 /* First flush out any partial line written with print. */
6607 message_log_maybe_newline ();
6608 if (m)
6609 message_dolog (m, nbytes, 1, multibyte);
6610 message2_nolog (m, nbytes, multibyte);
6611 }
6612
6613
6614 /* The non-logging counterpart of message2. */
6615
6616 void
6617 message2_nolog (m, nbytes, multibyte)
6618 const char *m;
6619 int nbytes, multibyte;
6620 {
6621 struct frame *sf = SELECTED_FRAME ();
6622 message_enable_multibyte = multibyte;
6623
6624 if (noninteractive)
6625 {
6626 if (noninteractive_need_newline)
6627 putc ('\n', stderr);
6628 noninteractive_need_newline = 0;
6629 if (m)
6630 fwrite (m, nbytes, 1, stderr);
6631 if (cursor_in_echo_area == 0)
6632 fprintf (stderr, "\n");
6633 fflush (stderr);
6634 }
6635 /* A null message buffer means that the frame hasn't really been
6636 initialized yet. Error messages get reported properly by
6637 cmd_error, so this must be just an informative message; toss it. */
6638 else if (INTERACTIVE
6639 && sf->glyphs_initialized_p
6640 && FRAME_MESSAGE_BUF (sf))
6641 {
6642 Lisp_Object mini_window;
6643 struct frame *f;
6644
6645 /* Get the frame containing the mini-buffer
6646 that the selected frame is using. */
6647 mini_window = FRAME_MINIBUF_WINDOW (sf);
6648 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6649
6650 FRAME_SAMPLE_VISIBILITY (f);
6651 if (FRAME_VISIBLE_P (sf)
6652 && ! FRAME_VISIBLE_P (f))
6653 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6654
6655 if (m)
6656 {
6657 set_message (m, Qnil, nbytes, multibyte);
6658 if (minibuffer_auto_raise)
6659 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6660 }
6661 else
6662 clear_message (1, 1);
6663
6664 do_pending_window_change (0);
6665 echo_area_display (1);
6666 do_pending_window_change (0);
6667 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6668 (*frame_up_to_date_hook) (f);
6669 }
6670 }
6671
6672
6673 /* Display an echo area message M with a specified length of NBYTES
6674 bytes. The string may include null characters. If M is not a
6675 string, clear out any existing message, and let the mini-buffer
6676 text show through. */
6677
6678 void
6679 message3 (m, nbytes, multibyte)
6680 Lisp_Object m;
6681 int nbytes;
6682 int multibyte;
6683 {
6684 struct gcpro gcpro1;
6685
6686 GCPRO1 (m);
6687
6688 /* First flush out any partial line written with print. */
6689 message_log_maybe_newline ();
6690 if (STRINGP (m))
6691 message_dolog (SDATA (m), nbytes, 1, multibyte);
6692 message3_nolog (m, nbytes, multibyte);
6693
6694 UNGCPRO;
6695 }
6696
6697
6698 /* The non-logging version of message3. */
6699
6700 void
6701 message3_nolog (m, nbytes, multibyte)
6702 Lisp_Object m;
6703 int nbytes, multibyte;
6704 {
6705 struct frame *sf = SELECTED_FRAME ();
6706 message_enable_multibyte = multibyte;
6707
6708 if (noninteractive)
6709 {
6710 if (noninteractive_need_newline)
6711 putc ('\n', stderr);
6712 noninteractive_need_newline = 0;
6713 if (STRINGP (m))
6714 fwrite (SDATA (m), nbytes, 1, stderr);
6715 if (cursor_in_echo_area == 0)
6716 fprintf (stderr, "\n");
6717 fflush (stderr);
6718 }
6719 /* A null message buffer means that the frame hasn't really been
6720 initialized yet. Error messages get reported properly by
6721 cmd_error, so this must be just an informative message; toss it. */
6722 else if (INTERACTIVE
6723 && sf->glyphs_initialized_p
6724 && FRAME_MESSAGE_BUF (sf))
6725 {
6726 Lisp_Object mini_window;
6727 Lisp_Object frame;
6728 struct frame *f;
6729
6730 /* Get the frame containing the mini-buffer
6731 that the selected frame is using. */
6732 mini_window = FRAME_MINIBUF_WINDOW (sf);
6733 frame = XWINDOW (mini_window)->frame;
6734 f = XFRAME (frame);
6735
6736 FRAME_SAMPLE_VISIBILITY (f);
6737 if (FRAME_VISIBLE_P (sf)
6738 && !FRAME_VISIBLE_P (f))
6739 Fmake_frame_visible (frame);
6740
6741 if (STRINGP (m) && SCHARS (m) > 0)
6742 {
6743 set_message (NULL, m, nbytes, multibyte);
6744 if (minibuffer_auto_raise)
6745 Fraise_frame (frame);
6746 }
6747 else
6748 clear_message (1, 1);
6749
6750 do_pending_window_change (0);
6751 echo_area_display (1);
6752 do_pending_window_change (0);
6753 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6754 (*frame_up_to_date_hook) (f);
6755 }
6756 }
6757
6758
6759 /* Display a null-terminated echo area message M. If M is 0, clear
6760 out any existing message, and let the mini-buffer text show through.
6761
6762 The buffer M must continue to exist until after the echo area gets
6763 cleared or some other message gets displayed there. Do not pass
6764 text that is stored in a Lisp string. Do not pass text in a buffer
6765 that was alloca'd. */
6766
6767 void
6768 message1 (m)
6769 char *m;
6770 {
6771 message2 (m, (m ? strlen (m) : 0), 0);
6772 }
6773
6774
6775 /* The non-logging counterpart of message1. */
6776
6777 void
6778 message1_nolog (m)
6779 char *m;
6780 {
6781 message2_nolog (m, (m ? strlen (m) : 0), 0);
6782 }
6783
6784 /* Display a message M which contains a single %s
6785 which gets replaced with STRING. */
6786
6787 void
6788 message_with_string (m, string, log)
6789 char *m;
6790 Lisp_Object string;
6791 int log;
6792 {
6793 CHECK_STRING (string);
6794
6795 if (noninteractive)
6796 {
6797 if (m)
6798 {
6799 if (noninteractive_need_newline)
6800 putc ('\n', stderr);
6801 noninteractive_need_newline = 0;
6802 fprintf (stderr, m, SDATA (string));
6803 if (cursor_in_echo_area == 0)
6804 fprintf (stderr, "\n");
6805 fflush (stderr);
6806 }
6807 }
6808 else if (INTERACTIVE)
6809 {
6810 /* The frame whose minibuffer we're going to display the message on.
6811 It may be larger than the selected frame, so we need
6812 to use its buffer, not the selected frame's buffer. */
6813 Lisp_Object mini_window;
6814 struct frame *f, *sf = SELECTED_FRAME ();
6815
6816 /* Get the frame containing the minibuffer
6817 that the selected frame is using. */
6818 mini_window = FRAME_MINIBUF_WINDOW (sf);
6819 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6820
6821 /* A null message buffer means that the frame hasn't really been
6822 initialized yet. Error messages get reported properly by
6823 cmd_error, so this must be just an informative message; toss it. */
6824 if (FRAME_MESSAGE_BUF (f))
6825 {
6826 Lisp_Object args[2], message;
6827 struct gcpro gcpro1, gcpro2;
6828
6829 args[0] = build_string (m);
6830 args[1] = message = string;
6831 GCPRO2 (args[0], message);
6832 gcpro1.nvars = 2;
6833
6834 message = Fformat (2, args);
6835
6836 if (log)
6837 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6838 else
6839 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6840
6841 UNGCPRO;
6842
6843 /* Print should start at the beginning of the message
6844 buffer next time. */
6845 message_buf_print = 0;
6846 }
6847 }
6848 }
6849
6850
6851 /* Dump an informative message to the minibuf. If M is 0, clear out
6852 any existing message, and let the mini-buffer text show through. */
6853
6854 /* VARARGS 1 */
6855 void
6856 message (m, a1, a2, a3)
6857 char *m;
6858 EMACS_INT a1, a2, a3;
6859 {
6860 if (noninteractive)
6861 {
6862 if (m)
6863 {
6864 if (noninteractive_need_newline)
6865 putc ('\n', stderr);
6866 noninteractive_need_newline = 0;
6867 fprintf (stderr, m, a1, a2, a3);
6868 if (cursor_in_echo_area == 0)
6869 fprintf (stderr, "\n");
6870 fflush (stderr);
6871 }
6872 }
6873 else if (INTERACTIVE)
6874 {
6875 /* The frame whose mini-buffer we're going to display the message
6876 on. It may be larger than the selected frame, so we need to
6877 use its buffer, not the selected frame's buffer. */
6878 Lisp_Object mini_window;
6879 struct frame *f, *sf = SELECTED_FRAME ();
6880
6881 /* Get the frame containing the mini-buffer
6882 that the selected frame is using. */
6883 mini_window = FRAME_MINIBUF_WINDOW (sf);
6884 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6885
6886 /* A null message buffer means that the frame hasn't really been
6887 initialized yet. Error messages get reported properly by
6888 cmd_error, so this must be just an informative message; toss
6889 it. */
6890 if (FRAME_MESSAGE_BUF (f))
6891 {
6892 if (m)
6893 {
6894 int len;
6895 #ifdef NO_ARG_ARRAY
6896 char *a[3];
6897 a[0] = (char *) a1;
6898 a[1] = (char *) a2;
6899 a[2] = (char *) a3;
6900
6901 len = doprnt (FRAME_MESSAGE_BUF (f),
6902 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6903 #else
6904 len = doprnt (FRAME_MESSAGE_BUF (f),
6905 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6906 (char **) &a1);
6907 #endif /* NO_ARG_ARRAY */
6908
6909 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6910 }
6911 else
6912 message1 (0);
6913
6914 /* Print should start at the beginning of the message
6915 buffer next time. */
6916 message_buf_print = 0;
6917 }
6918 }
6919 }
6920
6921
6922 /* The non-logging version of message. */
6923
6924 void
6925 message_nolog (m, a1, a2, a3)
6926 char *m;
6927 EMACS_INT a1, a2, a3;
6928 {
6929 Lisp_Object old_log_max;
6930 old_log_max = Vmessage_log_max;
6931 Vmessage_log_max = Qnil;
6932 message (m, a1, a2, a3);
6933 Vmessage_log_max = old_log_max;
6934 }
6935
6936
6937 /* Display the current message in the current mini-buffer. This is
6938 only called from error handlers in process.c, and is not time
6939 critical. */
6940
6941 void
6942 update_echo_area ()
6943 {
6944 if (!NILP (echo_area_buffer[0]))
6945 {
6946 Lisp_Object string;
6947 string = Fcurrent_message ();
6948 message3 (string, SBYTES (string),
6949 !NILP (current_buffer->enable_multibyte_characters));
6950 }
6951 }
6952
6953
6954 /* Make sure echo area buffers in `echo_buffers' are live.
6955 If they aren't, make new ones. */
6956
6957 static void
6958 ensure_echo_area_buffers ()
6959 {
6960 int i;
6961
6962 for (i = 0; i < 2; ++i)
6963 if (!BUFFERP (echo_buffer[i])
6964 || NILP (XBUFFER (echo_buffer[i])->name))
6965 {
6966 char name[30];
6967 Lisp_Object old_buffer;
6968 int j;
6969
6970 old_buffer = echo_buffer[i];
6971 sprintf (name, " *Echo Area %d*", i);
6972 echo_buffer[i] = Fget_buffer_create (build_string (name));
6973 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6974
6975 for (j = 0; j < 2; ++j)
6976 if (EQ (old_buffer, echo_area_buffer[j]))
6977 echo_area_buffer[j] = echo_buffer[i];
6978 }
6979 }
6980
6981
6982 /* Call FN with args A1..A4 with either the current or last displayed
6983 echo_area_buffer as current buffer.
6984
6985 WHICH zero means use the current message buffer
6986 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6987 from echo_buffer[] and clear it.
6988
6989 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6990 suitable buffer from echo_buffer[] and clear it.
6991
6992 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6993 that the current message becomes the last displayed one, make
6994 choose a suitable buffer for echo_area_buffer[0], and clear it.
6995
6996 Value is what FN returns. */
6997
6998 static int
6999 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7000 struct window *w;
7001 int which;
7002 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7003 EMACS_INT a1;
7004 Lisp_Object a2;
7005 EMACS_INT a3, a4;
7006 {
7007 Lisp_Object buffer;
7008 int this_one, the_other, clear_buffer_p, rc;
7009 int count = SPECPDL_INDEX ();
7010
7011 /* If buffers aren't live, make new ones. */
7012 ensure_echo_area_buffers ();
7013
7014 clear_buffer_p = 0;
7015
7016 if (which == 0)
7017 this_one = 0, the_other = 1;
7018 else if (which > 0)
7019 this_one = 1, the_other = 0;
7020 else
7021 {
7022 this_one = 0, the_other = 1;
7023 clear_buffer_p = 1;
7024
7025 /* We need a fresh one in case the current echo buffer equals
7026 the one containing the last displayed echo area message. */
7027 if (!NILP (echo_area_buffer[this_one])
7028 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7029 echo_area_buffer[this_one] = Qnil;
7030 }
7031
7032 /* Choose a suitable buffer from echo_buffer[] is we don't
7033 have one. */
7034 if (NILP (echo_area_buffer[this_one]))
7035 {
7036 echo_area_buffer[this_one]
7037 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7038 ? echo_buffer[the_other]
7039 : echo_buffer[this_one]);
7040 clear_buffer_p = 1;
7041 }
7042
7043 buffer = echo_area_buffer[this_one];
7044
7045 /* Don't get confused by reusing the buffer used for echoing
7046 for a different purpose. */
7047 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7048 cancel_echoing ();
7049
7050 record_unwind_protect (unwind_with_echo_area_buffer,
7051 with_echo_area_buffer_unwind_data (w));
7052
7053 /* Make the echo area buffer current. Note that for display
7054 purposes, it is not necessary that the displayed window's buffer
7055 == current_buffer, except for text property lookup. So, let's
7056 only set that buffer temporarily here without doing a full
7057 Fset_window_buffer. We must also change w->pointm, though,
7058 because otherwise an assertions in unshow_buffer fails, and Emacs
7059 aborts. */
7060 set_buffer_internal_1 (XBUFFER (buffer));
7061 if (w)
7062 {
7063 w->buffer = buffer;
7064 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7065 }
7066
7067 current_buffer->undo_list = Qt;
7068 current_buffer->read_only = Qnil;
7069 specbind (Qinhibit_read_only, Qt);
7070 specbind (Qinhibit_modification_hooks, Qt);
7071
7072 if (clear_buffer_p && Z > BEG)
7073 del_range (BEG, Z);
7074
7075 xassert (BEGV >= BEG);
7076 xassert (ZV <= Z && ZV >= BEGV);
7077
7078 rc = fn (a1, a2, a3, a4);
7079
7080 xassert (BEGV >= BEG);
7081 xassert (ZV <= Z && ZV >= BEGV);
7082
7083 unbind_to (count, Qnil);
7084 return rc;
7085 }
7086
7087
7088 /* Save state that should be preserved around the call to the function
7089 FN called in with_echo_area_buffer. */
7090
7091 static Lisp_Object
7092 with_echo_area_buffer_unwind_data (w)
7093 struct window *w;
7094 {
7095 int i = 0;
7096 Lisp_Object vector;
7097
7098 /* Reduce consing by keeping one vector in
7099 Vwith_echo_area_save_vector. */
7100 vector = Vwith_echo_area_save_vector;
7101 Vwith_echo_area_save_vector = Qnil;
7102
7103 if (NILP (vector))
7104 vector = Fmake_vector (make_number (7), Qnil);
7105
7106 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7107 AREF (vector, i) = Vdeactivate_mark, ++i;
7108 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7109
7110 if (w)
7111 {
7112 XSETWINDOW (AREF (vector, i), w); ++i;
7113 AREF (vector, i) = w->buffer; ++i;
7114 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7115 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7116 }
7117 else
7118 {
7119 int end = i + 4;
7120 for (; i < end; ++i)
7121 AREF (vector, i) = Qnil;
7122 }
7123
7124 xassert (i == ASIZE (vector));
7125 return vector;
7126 }
7127
7128
7129 /* Restore global state from VECTOR which was created by
7130 with_echo_area_buffer_unwind_data. */
7131
7132 static Lisp_Object
7133 unwind_with_echo_area_buffer (vector)
7134 Lisp_Object vector;
7135 {
7136 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7137 Vdeactivate_mark = AREF (vector, 1);
7138 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7139
7140 if (WINDOWP (AREF (vector, 3)))
7141 {
7142 struct window *w;
7143 Lisp_Object buffer, charpos, bytepos;
7144
7145 w = XWINDOW (AREF (vector, 3));
7146 buffer = AREF (vector, 4);
7147 charpos = AREF (vector, 5);
7148 bytepos = AREF (vector, 6);
7149
7150 w->buffer = buffer;
7151 set_marker_both (w->pointm, buffer,
7152 XFASTINT (charpos), XFASTINT (bytepos));
7153 }
7154
7155 Vwith_echo_area_save_vector = vector;
7156 return Qnil;
7157 }
7158
7159
7160 /* Set up the echo area for use by print functions. MULTIBYTE_P
7161 non-zero means we will print multibyte. */
7162
7163 void
7164 setup_echo_area_for_printing (multibyte_p)
7165 int multibyte_p;
7166 {
7167 /* If we can't find an echo area any more, exit. */
7168 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7169 Fkill_emacs (Qnil);
7170
7171 ensure_echo_area_buffers ();
7172
7173 if (!message_buf_print)
7174 {
7175 /* A message has been output since the last time we printed.
7176 Choose a fresh echo area buffer. */
7177 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7178 echo_area_buffer[0] = echo_buffer[1];
7179 else
7180 echo_area_buffer[0] = echo_buffer[0];
7181
7182 /* Switch to that buffer and clear it. */
7183 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7184 current_buffer->truncate_lines = Qnil;
7185
7186 if (Z > BEG)
7187 {
7188 int count = SPECPDL_INDEX ();
7189 specbind (Qinhibit_read_only, Qt);
7190 /* Note that undo recording is always disabled. */
7191 del_range (BEG, Z);
7192 unbind_to (count, Qnil);
7193 }
7194 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7195
7196 /* Set up the buffer for the multibyteness we need. */
7197 if (multibyte_p
7198 != !NILP (current_buffer->enable_multibyte_characters))
7199 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7200
7201 /* Raise the frame containing the echo area. */
7202 if (minibuffer_auto_raise)
7203 {
7204 struct frame *sf = SELECTED_FRAME ();
7205 Lisp_Object mini_window;
7206 mini_window = FRAME_MINIBUF_WINDOW (sf);
7207 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7208 }
7209
7210 message_log_maybe_newline ();
7211 message_buf_print = 1;
7212 }
7213 else
7214 {
7215 if (NILP (echo_area_buffer[0]))
7216 {
7217 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7218 echo_area_buffer[0] = echo_buffer[1];
7219 else
7220 echo_area_buffer[0] = echo_buffer[0];
7221 }
7222
7223 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7224 {
7225 /* Someone switched buffers between print requests. */
7226 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7227 current_buffer->truncate_lines = Qnil;
7228 }
7229 }
7230 }
7231
7232
7233 /* Display an echo area message in window W. Value is non-zero if W's
7234 height is changed. If display_last_displayed_message_p is
7235 non-zero, display the message that was last displayed, otherwise
7236 display the current message. */
7237
7238 static int
7239 display_echo_area (w)
7240 struct window *w;
7241 {
7242 int i, no_message_p, window_height_changed_p, count;
7243
7244 /* Temporarily disable garbage collections while displaying the echo
7245 area. This is done because a GC can print a message itself.
7246 That message would modify the echo area buffer's contents while a
7247 redisplay of the buffer is going on, and seriously confuse
7248 redisplay. */
7249 count = inhibit_garbage_collection ();
7250
7251 /* If there is no message, we must call display_echo_area_1
7252 nevertheless because it resizes the window. But we will have to
7253 reset the echo_area_buffer in question to nil at the end because
7254 with_echo_area_buffer will sets it to an empty buffer. */
7255 i = display_last_displayed_message_p ? 1 : 0;
7256 no_message_p = NILP (echo_area_buffer[i]);
7257
7258 window_height_changed_p
7259 = with_echo_area_buffer (w, display_last_displayed_message_p,
7260 display_echo_area_1,
7261 (EMACS_INT) w, Qnil, 0, 0);
7262
7263 if (no_message_p)
7264 echo_area_buffer[i] = Qnil;
7265
7266 unbind_to (count, Qnil);
7267 return window_height_changed_p;
7268 }
7269
7270
7271 /* Helper for display_echo_area. Display the current buffer which
7272 contains the current echo area message in window W, a mini-window,
7273 a pointer to which is passed in A1. A2..A4 are currently not used.
7274 Change the height of W so that all of the message is displayed.
7275 Value is non-zero if height of W was changed. */
7276
7277 static int
7278 display_echo_area_1 (a1, a2, a3, a4)
7279 EMACS_INT a1;
7280 Lisp_Object a2;
7281 EMACS_INT a3, a4;
7282 {
7283 struct window *w = (struct window *) a1;
7284 Lisp_Object window;
7285 struct text_pos start;
7286 int window_height_changed_p = 0;
7287
7288 /* Do this before displaying, so that we have a large enough glyph
7289 matrix for the display. */
7290 window_height_changed_p = resize_mini_window (w, 0);
7291
7292 /* Display. */
7293 clear_glyph_matrix (w->desired_matrix);
7294 XSETWINDOW (window, w);
7295 SET_TEXT_POS (start, BEG, BEG_BYTE);
7296 try_window (window, start);
7297
7298 return window_height_changed_p;
7299 }
7300
7301
7302 /* Resize the echo area window to exactly the size needed for the
7303 currently displayed message, if there is one. If a mini-buffer
7304 is active, don't shrink it. */
7305
7306 void
7307 resize_echo_area_exactly ()
7308 {
7309 if (BUFFERP (echo_area_buffer[0])
7310 && WINDOWP (echo_area_window))
7311 {
7312 struct window *w = XWINDOW (echo_area_window);
7313 int resized_p;
7314 Lisp_Object resize_exactly;
7315
7316 if (minibuf_level == 0)
7317 resize_exactly = Qt;
7318 else
7319 resize_exactly = Qnil;
7320
7321 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7322 (EMACS_INT) w, resize_exactly, 0, 0);
7323 if (resized_p)
7324 {
7325 ++windows_or_buffers_changed;
7326 ++update_mode_lines;
7327 redisplay_internal (0);
7328 }
7329 }
7330 }
7331
7332
7333 /* Callback function for with_echo_area_buffer, when used from
7334 resize_echo_area_exactly. A1 contains a pointer to the window to
7335 resize, EXACTLY non-nil means resize the mini-window exactly to the
7336 size of the text displayed. A3 and A4 are not used. Value is what
7337 resize_mini_window returns. */
7338
7339 static int
7340 resize_mini_window_1 (a1, exactly, a3, a4)
7341 EMACS_INT a1;
7342 Lisp_Object exactly;
7343 EMACS_INT a3, a4;
7344 {
7345 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7346 }
7347
7348
7349 /* Resize mini-window W to fit the size of its contents. EXACT:P
7350 means size the window exactly to the size needed. Otherwise, it's
7351 only enlarged until W's buffer is empty. Value is non-zero if
7352 the window height has been changed. */
7353
7354 int
7355 resize_mini_window (w, exact_p)
7356 struct window *w;
7357 int exact_p;
7358 {
7359 struct frame *f = XFRAME (w->frame);
7360 int window_height_changed_p = 0;
7361
7362 xassert (MINI_WINDOW_P (w));
7363
7364 /* Don't resize windows while redisplaying a window; it would
7365 confuse redisplay functions when the size of the window they are
7366 displaying changes from under them. Such a resizing can happen,
7367 for instance, when which-func prints a long message while
7368 we are running fontification-functions. We're running these
7369 functions with safe_call which binds inhibit-redisplay to t. */
7370 if (!NILP (Vinhibit_redisplay))
7371 return 0;
7372
7373 /* Nil means don't try to resize. */
7374 if (NILP (Vresize_mini_windows)
7375 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7376 return 0;
7377
7378 if (!FRAME_MINIBUF_ONLY_P (f))
7379 {
7380 struct it it;
7381 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7382 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7383 int height, max_height;
7384 int unit = FRAME_LINE_HEIGHT (f);
7385 struct text_pos start;
7386 struct buffer *old_current_buffer = NULL;
7387
7388 if (current_buffer != XBUFFER (w->buffer))
7389 {
7390 old_current_buffer = current_buffer;
7391 set_buffer_internal (XBUFFER (w->buffer));
7392 }
7393
7394 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7395
7396 /* Compute the max. number of lines specified by the user. */
7397 if (FLOATP (Vmax_mini_window_height))
7398 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7399 else if (INTEGERP (Vmax_mini_window_height))
7400 max_height = XINT (Vmax_mini_window_height);
7401 else
7402 max_height = total_height / 4;
7403
7404 /* Correct that max. height if it's bogus. */
7405 max_height = max (1, max_height);
7406 max_height = min (total_height, max_height);
7407
7408 /* Find out the height of the text in the window. */
7409 if (it.truncate_lines_p)
7410 height = 1;
7411 else
7412 {
7413 last_height = 0;
7414 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7415 if (it.max_ascent == 0 && it.max_descent == 0)
7416 height = it.current_y + last_height;
7417 else
7418 height = it.current_y + it.max_ascent + it.max_descent;
7419 height -= it.extra_line_spacing;
7420 height = (height + unit - 1) / unit;
7421 }
7422
7423 /* Compute a suitable window start. */
7424 if (height > max_height)
7425 {
7426 height = max_height;
7427 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7428 move_it_vertically_backward (&it, (height - 1) * unit);
7429 start = it.current.pos;
7430 }
7431 else
7432 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7433 SET_MARKER_FROM_TEXT_POS (w->start, start);
7434
7435 if (EQ (Vresize_mini_windows, Qgrow_only))
7436 {
7437 /* Let it grow only, until we display an empty message, in which
7438 case the window shrinks again. */
7439 if (height > WINDOW_TOTAL_LINES (w))
7440 {
7441 int old_height = WINDOW_TOTAL_LINES (w);
7442 freeze_window_starts (f, 1);
7443 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7444 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7445 }
7446 else if (height < WINDOW_TOTAL_LINES (w)
7447 && (exact_p || BEGV == ZV))
7448 {
7449 int old_height = WINDOW_TOTAL_LINES (w);
7450 freeze_window_starts (f, 0);
7451 shrink_mini_window (w);
7452 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7453 }
7454 }
7455 else
7456 {
7457 /* Always resize to exact size needed. */
7458 if (height > WINDOW_TOTAL_LINES (w))
7459 {
7460 int old_height = WINDOW_TOTAL_LINES (w);
7461 freeze_window_starts (f, 1);
7462 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7463 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7464 }
7465 else if (height < WINDOW_TOTAL_LINES (w))
7466 {
7467 int old_height = WINDOW_TOTAL_LINES (w);
7468 freeze_window_starts (f, 0);
7469 shrink_mini_window (w);
7470
7471 if (height)
7472 {
7473 freeze_window_starts (f, 1);
7474 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7475 }
7476
7477 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7478 }
7479 }
7480
7481 if (old_current_buffer)
7482 set_buffer_internal (old_current_buffer);
7483 }
7484
7485 return window_height_changed_p;
7486 }
7487
7488
7489 /* Value is the current message, a string, or nil if there is no
7490 current message. */
7491
7492 Lisp_Object
7493 current_message ()
7494 {
7495 Lisp_Object msg;
7496
7497 if (NILP (echo_area_buffer[0]))
7498 msg = Qnil;
7499 else
7500 {
7501 with_echo_area_buffer (0, 0, current_message_1,
7502 (EMACS_INT) &msg, Qnil, 0, 0);
7503 if (NILP (msg))
7504 echo_area_buffer[0] = Qnil;
7505 }
7506
7507 return msg;
7508 }
7509
7510
7511 static int
7512 current_message_1 (a1, a2, a3, a4)
7513 EMACS_INT a1;
7514 Lisp_Object a2;
7515 EMACS_INT a3, a4;
7516 {
7517 Lisp_Object *msg = (Lisp_Object *) a1;
7518
7519 if (Z > BEG)
7520 *msg = make_buffer_string (BEG, Z, 1);
7521 else
7522 *msg = Qnil;
7523 return 0;
7524 }
7525
7526
7527 /* Push the current message on Vmessage_stack for later restauration
7528 by restore_message. Value is non-zero if the current message isn't
7529 empty. This is a relatively infrequent operation, so it's not
7530 worth optimizing. */
7531
7532 int
7533 push_message ()
7534 {
7535 Lisp_Object msg;
7536 msg = current_message ();
7537 Vmessage_stack = Fcons (msg, Vmessage_stack);
7538 return STRINGP (msg);
7539 }
7540
7541
7542 /* Restore message display from the top of Vmessage_stack. */
7543
7544 void
7545 restore_message ()
7546 {
7547 Lisp_Object msg;
7548
7549 xassert (CONSP (Vmessage_stack));
7550 msg = XCAR (Vmessage_stack);
7551 if (STRINGP (msg))
7552 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7553 else
7554 message3_nolog (msg, 0, 0);
7555 }
7556
7557
7558 /* Handler for record_unwind_protect calling pop_message. */
7559
7560 Lisp_Object
7561 pop_message_unwind (dummy)
7562 Lisp_Object dummy;
7563 {
7564 pop_message ();
7565 return Qnil;
7566 }
7567
7568 /* Pop the top-most entry off Vmessage_stack. */
7569
7570 void
7571 pop_message ()
7572 {
7573 xassert (CONSP (Vmessage_stack));
7574 Vmessage_stack = XCDR (Vmessage_stack);
7575 }
7576
7577
7578 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7579 exits. If the stack is not empty, we have a missing pop_message
7580 somewhere. */
7581
7582 void
7583 check_message_stack ()
7584 {
7585 if (!NILP (Vmessage_stack))
7586 abort ();
7587 }
7588
7589
7590 /* Truncate to NCHARS what will be displayed in the echo area the next
7591 time we display it---but don't redisplay it now. */
7592
7593 void
7594 truncate_echo_area (nchars)
7595 int nchars;
7596 {
7597 if (nchars == 0)
7598 echo_area_buffer[0] = Qnil;
7599 /* A null message buffer means that the frame hasn't really been
7600 initialized yet. Error messages get reported properly by
7601 cmd_error, so this must be just an informative message; toss it. */
7602 else if (!noninteractive
7603 && INTERACTIVE
7604 && !NILP (echo_area_buffer[0]))
7605 {
7606 struct frame *sf = SELECTED_FRAME ();
7607 if (FRAME_MESSAGE_BUF (sf))
7608 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7609 }
7610 }
7611
7612
7613 /* Helper function for truncate_echo_area. Truncate the current
7614 message to at most NCHARS characters. */
7615
7616 static int
7617 truncate_message_1 (nchars, a2, a3, a4)
7618 EMACS_INT nchars;
7619 Lisp_Object a2;
7620 EMACS_INT a3, a4;
7621 {
7622 if (BEG + nchars < Z)
7623 del_range (BEG + nchars, Z);
7624 if (Z == BEG)
7625 echo_area_buffer[0] = Qnil;
7626 return 0;
7627 }
7628
7629
7630 /* Set the current message to a substring of S or STRING.
7631
7632 If STRING is a Lisp string, set the message to the first NBYTES
7633 bytes from STRING. NBYTES zero means use the whole string. If
7634 STRING is multibyte, the message will be displayed multibyte.
7635
7636 If S is not null, set the message to the first LEN bytes of S. LEN
7637 zero means use the whole string. MULTIBYTE_P non-zero means S is
7638 multibyte. Display the message multibyte in that case. */
7639
7640 void
7641 set_message (s, string, nbytes, multibyte_p)
7642 const char *s;
7643 Lisp_Object string;
7644 int nbytes, multibyte_p;
7645 {
7646 message_enable_multibyte
7647 = ((s && multibyte_p)
7648 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7649
7650 with_echo_area_buffer (0, -1, set_message_1,
7651 (EMACS_INT) s, string, nbytes, multibyte_p);
7652 message_buf_print = 0;
7653 help_echo_showing_p = 0;
7654 }
7655
7656
7657 /* Helper function for set_message. Arguments have the same meaning
7658 as there, with A1 corresponding to S and A2 corresponding to STRING
7659 This function is called with the echo area buffer being
7660 current. */
7661
7662 static int
7663 set_message_1 (a1, a2, nbytes, multibyte_p)
7664 EMACS_INT a1;
7665 Lisp_Object a2;
7666 EMACS_INT nbytes, multibyte_p;
7667 {
7668 const char *s = (const char *) a1;
7669 Lisp_Object string = a2;
7670
7671 xassert (BEG == Z);
7672
7673 /* Change multibyteness of the echo buffer appropriately. */
7674 if (message_enable_multibyte
7675 != !NILP (current_buffer->enable_multibyte_characters))
7676 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7677
7678 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7679
7680 /* Insert new message at BEG. */
7681 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7682
7683 if (STRINGP (string))
7684 {
7685 int nchars;
7686
7687 if (nbytes == 0)
7688 nbytes = SBYTES (string);
7689 nchars = string_byte_to_char (string, nbytes);
7690
7691 /* This function takes care of single/multibyte conversion. We
7692 just have to ensure that the echo area buffer has the right
7693 setting of enable_multibyte_characters. */
7694 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7695 }
7696 else if (s)
7697 {
7698 if (nbytes == 0)
7699 nbytes = strlen (s);
7700
7701 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7702 {
7703 /* Convert from multi-byte to single-byte. */
7704 int i, c, n;
7705 unsigned char work[1];
7706
7707 /* Convert a multibyte string to single-byte. */
7708 for (i = 0; i < nbytes; i += n)
7709 {
7710 c = string_char_and_length (s + i, nbytes - i, &n);
7711 work[0] = (SINGLE_BYTE_CHAR_P (c)
7712 ? c
7713 : multibyte_char_to_unibyte (c, Qnil));
7714 insert_1_both (work, 1, 1, 1, 0, 0);
7715 }
7716 }
7717 else if (!multibyte_p
7718 && !NILP (current_buffer->enable_multibyte_characters))
7719 {
7720 /* Convert from single-byte to multi-byte. */
7721 int i, c, n;
7722 const unsigned char *msg = (const unsigned char *) s;
7723 unsigned char str[MAX_MULTIBYTE_LENGTH];
7724
7725 /* Convert a single-byte string to multibyte. */
7726 for (i = 0; i < nbytes; i++)
7727 {
7728 c = unibyte_char_to_multibyte (msg[i]);
7729 n = CHAR_STRING (c, str);
7730 insert_1_both (str, 1, n, 1, 0, 0);
7731 }
7732 }
7733 else
7734 insert_1 (s, nbytes, 1, 0, 0);
7735 }
7736
7737 return 0;
7738 }
7739
7740
7741 /* Clear messages. CURRENT_P non-zero means clear the current
7742 message. LAST_DISPLAYED_P non-zero means clear the message
7743 last displayed. */
7744
7745 void
7746 clear_message (current_p, last_displayed_p)
7747 int current_p, last_displayed_p;
7748 {
7749 if (current_p)
7750 {
7751 echo_area_buffer[0] = Qnil;
7752 message_cleared_p = 1;
7753 }
7754
7755 if (last_displayed_p)
7756 echo_area_buffer[1] = Qnil;
7757
7758 message_buf_print = 0;
7759 }
7760
7761 /* Clear garbaged frames.
7762
7763 This function is used where the old redisplay called
7764 redraw_garbaged_frames which in turn called redraw_frame which in
7765 turn called clear_frame. The call to clear_frame was a source of
7766 flickering. I believe a clear_frame is not necessary. It should
7767 suffice in the new redisplay to invalidate all current matrices,
7768 and ensure a complete redisplay of all windows. */
7769
7770 static void
7771 clear_garbaged_frames ()
7772 {
7773 if (frame_garbaged)
7774 {
7775 Lisp_Object tail, frame;
7776 int changed_count = 0;
7777
7778 FOR_EACH_FRAME (tail, frame)
7779 {
7780 struct frame *f = XFRAME (frame);
7781
7782 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7783 {
7784 if (f->resized_p)
7785 {
7786 Fredraw_frame (frame);
7787 f->force_flush_display_p = 1;
7788 }
7789 clear_current_matrices (f);
7790 changed_count++;
7791 f->garbaged = 0;
7792 f->resized_p = 0;
7793 }
7794 }
7795
7796 frame_garbaged = 0;
7797 if (changed_count)
7798 ++windows_or_buffers_changed;
7799 }
7800 }
7801
7802
7803 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7804 is non-zero update selected_frame. Value is non-zero if the
7805 mini-windows height has been changed. */
7806
7807 static int
7808 echo_area_display (update_frame_p)
7809 int update_frame_p;
7810 {
7811 Lisp_Object mini_window;
7812 struct window *w;
7813 struct frame *f;
7814 int window_height_changed_p = 0;
7815 struct frame *sf = SELECTED_FRAME ();
7816
7817 mini_window = FRAME_MINIBUF_WINDOW (sf);
7818 w = XWINDOW (mini_window);
7819 f = XFRAME (WINDOW_FRAME (w));
7820
7821 /* Don't display if frame is invisible or not yet initialized. */
7822 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7823 return 0;
7824
7825 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7826 #ifndef MAC_OS8
7827 #ifdef HAVE_WINDOW_SYSTEM
7828 /* When Emacs starts, selected_frame may be a visible terminal
7829 frame, even if we run under a window system. If we let this
7830 through, a message would be displayed on the terminal. */
7831 if (EQ (selected_frame, Vterminal_frame)
7832 && !NILP (Vwindow_system))
7833 return 0;
7834 #endif /* HAVE_WINDOW_SYSTEM */
7835 #endif
7836
7837 /* Redraw garbaged frames. */
7838 if (frame_garbaged)
7839 clear_garbaged_frames ();
7840
7841 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7842 {
7843 echo_area_window = mini_window;
7844 window_height_changed_p = display_echo_area (w);
7845 w->must_be_updated_p = 1;
7846
7847 /* Update the display, unless called from redisplay_internal.
7848 Also don't update the screen during redisplay itself. The
7849 update will happen at the end of redisplay, and an update
7850 here could cause confusion. */
7851 if (update_frame_p && !redisplaying_p)
7852 {
7853 int n = 0;
7854
7855 /* If the display update has been interrupted by pending
7856 input, update mode lines in the frame. Due to the
7857 pending input, it might have been that redisplay hasn't
7858 been called, so that mode lines above the echo area are
7859 garbaged. This looks odd, so we prevent it here. */
7860 if (!display_completed)
7861 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7862
7863 if (window_height_changed_p
7864 /* Don't do this if Emacs is shutting down. Redisplay
7865 needs to run hooks. */
7866 && !NILP (Vrun_hooks))
7867 {
7868 /* Must update other windows. Likewise as in other
7869 cases, don't let this update be interrupted by
7870 pending input. */
7871 int count = SPECPDL_INDEX ();
7872 specbind (Qredisplay_dont_pause, Qt);
7873 windows_or_buffers_changed = 1;
7874 redisplay_internal (0);
7875 unbind_to (count, Qnil);
7876 }
7877 else if (FRAME_WINDOW_P (f) && n == 0)
7878 {
7879 /* Window configuration is the same as before.
7880 Can do with a display update of the echo area,
7881 unless we displayed some mode lines. */
7882 update_single_window (w, 1);
7883 rif->flush_display (f);
7884 }
7885 else
7886 update_frame (f, 1, 1);
7887
7888 /* If cursor is in the echo area, make sure that the next
7889 redisplay displays the minibuffer, so that the cursor will
7890 be replaced with what the minibuffer wants. */
7891 if (cursor_in_echo_area)
7892 ++windows_or_buffers_changed;
7893 }
7894 }
7895 else if (!EQ (mini_window, selected_window))
7896 windows_or_buffers_changed++;
7897
7898 /* Last displayed message is now the current message. */
7899 echo_area_buffer[1] = echo_area_buffer[0];
7900
7901 /* Prevent redisplay optimization in redisplay_internal by resetting
7902 this_line_start_pos. This is done because the mini-buffer now
7903 displays the message instead of its buffer text. */
7904 if (EQ (mini_window, selected_window))
7905 CHARPOS (this_line_start_pos) = 0;
7906
7907 return window_height_changed_p;
7908 }
7909
7910
7911 \f
7912 /***********************************************************************
7913 Frame Titles
7914 ***********************************************************************/
7915
7916
7917 /* The frame title buffering code is also used by Fformat_mode_line.
7918 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7919
7920 /* A buffer for constructing frame titles in it; allocated from the
7921 heap in init_xdisp and resized as needed in store_frame_title_char. */
7922
7923 static char *frame_title_buf;
7924
7925 /* The buffer's end, and a current output position in it. */
7926
7927 static char *frame_title_buf_end;
7928 static char *frame_title_ptr;
7929
7930
7931 /* Store a single character C for the frame title in frame_title_buf.
7932 Re-allocate frame_title_buf if necessary. */
7933
7934 static void
7935 #ifdef PROTOTYPES
7936 store_frame_title_char (char c)
7937 #else
7938 store_frame_title_char (c)
7939 char c;
7940 #endif
7941 {
7942 /* If output position has reached the end of the allocated buffer,
7943 double the buffer's size. */
7944 if (frame_title_ptr == frame_title_buf_end)
7945 {
7946 int len = frame_title_ptr - frame_title_buf;
7947 int new_size = 2 * len * sizeof *frame_title_buf;
7948 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7949 frame_title_buf_end = frame_title_buf + new_size;
7950 frame_title_ptr = frame_title_buf + len;
7951 }
7952
7953 *frame_title_ptr++ = c;
7954 }
7955
7956
7957 /* Store part of a frame title in frame_title_buf, beginning at
7958 frame_title_ptr. STR is the string to store. Do not copy
7959 characters that yield more columns than PRECISION; PRECISION <= 0
7960 means copy the whole string. Pad with spaces until FIELD_WIDTH
7961 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7962 pad. Called from display_mode_element when it is used to build a
7963 frame title. */
7964
7965 static int
7966 store_frame_title (str, field_width, precision)
7967 const unsigned char *str;
7968 int field_width, precision;
7969 {
7970 int n = 0;
7971 int dummy, nbytes;
7972
7973 /* Copy at most PRECISION chars from STR. */
7974 nbytes = strlen (str);
7975 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7976 while (nbytes--)
7977 store_frame_title_char (*str++);
7978
7979 /* Fill up with spaces until FIELD_WIDTH reached. */
7980 while (field_width > 0
7981 && n < field_width)
7982 {
7983 store_frame_title_char (' ');
7984 ++n;
7985 }
7986
7987 return n;
7988 }
7989
7990 #ifdef HAVE_WINDOW_SYSTEM
7991
7992 /* Set the title of FRAME, if it has changed. The title format is
7993 Vicon_title_format if FRAME is iconified, otherwise it is
7994 frame_title_format. */
7995
7996 static void
7997 x_consider_frame_title (frame)
7998 Lisp_Object frame;
7999 {
8000 struct frame *f = XFRAME (frame);
8001
8002 if (FRAME_WINDOW_P (f)
8003 || FRAME_MINIBUF_ONLY_P (f)
8004 || f->explicit_name)
8005 {
8006 /* Do we have more than one visible frame on this X display? */
8007 Lisp_Object tail;
8008 Lisp_Object fmt;
8009 struct buffer *obuf;
8010 int len;
8011 struct it it;
8012
8013 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8014 {
8015 Lisp_Object other_frame = XCAR (tail);
8016 struct frame *tf = XFRAME (other_frame);
8017
8018 if (tf != f
8019 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8020 && !FRAME_MINIBUF_ONLY_P (tf)
8021 && !EQ (other_frame, tip_frame)
8022 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8023 break;
8024 }
8025
8026 /* Set global variable indicating that multiple frames exist. */
8027 multiple_frames = CONSP (tail);
8028
8029 /* Switch to the buffer of selected window of the frame. Set up
8030 frame_title_ptr so that display_mode_element will output into it;
8031 then display the title. */
8032 obuf = current_buffer;
8033 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8034 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8035 frame_title_ptr = frame_title_buf;
8036 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8037 NULL, DEFAULT_FACE_ID);
8038 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8039 len = frame_title_ptr - frame_title_buf;
8040 frame_title_ptr = NULL;
8041 set_buffer_internal_1 (obuf);
8042
8043 /* Set the title only if it's changed. This avoids consing in
8044 the common case where it hasn't. (If it turns out that we've
8045 already wasted too much time by walking through the list with
8046 display_mode_element, then we might need to optimize at a
8047 higher level than this.) */
8048 if (! STRINGP (f->name)
8049 || SBYTES (f->name) != len
8050 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8051 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8052 }
8053 }
8054
8055 #endif /* not HAVE_WINDOW_SYSTEM */
8056
8057
8058
8059 \f
8060 /***********************************************************************
8061 Menu Bars
8062 ***********************************************************************/
8063
8064
8065 /* Prepare for redisplay by updating menu-bar item lists when
8066 appropriate. This can call eval. */
8067
8068 void
8069 prepare_menu_bars ()
8070 {
8071 int all_windows;
8072 struct gcpro gcpro1, gcpro2;
8073 struct frame *f;
8074 Lisp_Object tooltip_frame;
8075
8076 #ifdef HAVE_WINDOW_SYSTEM
8077 tooltip_frame = tip_frame;
8078 #else
8079 tooltip_frame = Qnil;
8080 #endif
8081
8082 /* Update all frame titles based on their buffer names, etc. We do
8083 this before the menu bars so that the buffer-menu will show the
8084 up-to-date frame titles. */
8085 #ifdef HAVE_WINDOW_SYSTEM
8086 if (windows_or_buffers_changed || update_mode_lines)
8087 {
8088 Lisp_Object tail, frame;
8089
8090 FOR_EACH_FRAME (tail, frame)
8091 {
8092 f = XFRAME (frame);
8093 if (!EQ (frame, tooltip_frame)
8094 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8095 x_consider_frame_title (frame);
8096 }
8097 }
8098 #endif /* HAVE_WINDOW_SYSTEM */
8099
8100 /* Update the menu bar item lists, if appropriate. This has to be
8101 done before any actual redisplay or generation of display lines. */
8102 all_windows = (update_mode_lines
8103 || buffer_shared > 1
8104 || windows_or_buffers_changed);
8105 if (all_windows)
8106 {
8107 Lisp_Object tail, frame;
8108 int count = SPECPDL_INDEX ();
8109
8110 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8111
8112 FOR_EACH_FRAME (tail, frame)
8113 {
8114 f = XFRAME (frame);
8115
8116 /* Ignore tooltip frame. */
8117 if (EQ (frame, tooltip_frame))
8118 continue;
8119
8120 /* If a window on this frame changed size, report that to
8121 the user and clear the size-change flag. */
8122 if (FRAME_WINDOW_SIZES_CHANGED (f))
8123 {
8124 Lisp_Object functions;
8125
8126 /* Clear flag first in case we get an error below. */
8127 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8128 functions = Vwindow_size_change_functions;
8129 GCPRO2 (tail, functions);
8130
8131 while (CONSP (functions))
8132 {
8133 call1 (XCAR (functions), frame);
8134 functions = XCDR (functions);
8135 }
8136 UNGCPRO;
8137 }
8138
8139 GCPRO1 (tail);
8140 update_menu_bar (f, 0);
8141 #ifdef HAVE_WINDOW_SYSTEM
8142 update_tool_bar (f, 0);
8143 #endif
8144 UNGCPRO;
8145 }
8146
8147 unbind_to (count, Qnil);
8148 }
8149 else
8150 {
8151 struct frame *sf = SELECTED_FRAME ();
8152 update_menu_bar (sf, 1);
8153 #ifdef HAVE_WINDOW_SYSTEM
8154 update_tool_bar (sf, 1);
8155 #endif
8156 }
8157
8158 /* Motif needs this. See comment in xmenu.c. Turn it off when
8159 pending_menu_activation is not defined. */
8160 #ifdef USE_X_TOOLKIT
8161 pending_menu_activation = 0;
8162 #endif
8163 }
8164
8165
8166 /* Update the menu bar item list for frame F. This has to be done
8167 before we start to fill in any display lines, because it can call
8168 eval.
8169
8170 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8171
8172 static void
8173 update_menu_bar (f, save_match_data)
8174 struct frame *f;
8175 int save_match_data;
8176 {
8177 Lisp_Object window;
8178 register struct window *w;
8179
8180 /* If called recursively during a menu update, do nothing. This can
8181 happen when, for instance, an activate-menubar-hook causes a
8182 redisplay. */
8183 if (inhibit_menubar_update)
8184 return;
8185
8186 window = FRAME_SELECTED_WINDOW (f);
8187 w = XWINDOW (window);
8188
8189 #if 0 /* The if statement below this if statement used to include the
8190 condition !NILP (w->update_mode_line), rather than using
8191 update_mode_lines directly, and this if statement may have
8192 been added to make that condition work. Now the if
8193 statement below matches its comment, this isn't needed. */
8194 if (update_mode_lines)
8195 w->update_mode_line = Qt;
8196 #endif
8197
8198 if (FRAME_WINDOW_P (f)
8199 ?
8200 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8201 || defined (USE_GTK)
8202 FRAME_EXTERNAL_MENU_BAR (f)
8203 #else
8204 FRAME_MENU_BAR_LINES (f) > 0
8205 #endif
8206 : FRAME_MENU_BAR_LINES (f) > 0)
8207 {
8208 /* If the user has switched buffers or windows, we need to
8209 recompute to reflect the new bindings. But we'll
8210 recompute when update_mode_lines is set too; that means
8211 that people can use force-mode-line-update to request
8212 that the menu bar be recomputed. The adverse effect on
8213 the rest of the redisplay algorithm is about the same as
8214 windows_or_buffers_changed anyway. */
8215 if (windows_or_buffers_changed
8216 /* This used to test w->update_mode_line, but we believe
8217 there is no need to recompute the menu in that case. */
8218 || update_mode_lines
8219 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8220 < BUF_MODIFF (XBUFFER (w->buffer)))
8221 != !NILP (w->last_had_star))
8222 || ((!NILP (Vtransient_mark_mode)
8223 && !NILP (XBUFFER (w->buffer)->mark_active))
8224 != !NILP (w->region_showing)))
8225 {
8226 struct buffer *prev = current_buffer;
8227 int count = SPECPDL_INDEX ();
8228
8229 specbind (Qinhibit_menubar_update, Qt);
8230
8231 set_buffer_internal_1 (XBUFFER (w->buffer));
8232 if (save_match_data)
8233 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8234 if (NILP (Voverriding_local_map_menu_flag))
8235 {
8236 specbind (Qoverriding_terminal_local_map, Qnil);
8237 specbind (Qoverriding_local_map, Qnil);
8238 }
8239
8240 /* Run the Lucid hook. */
8241 safe_run_hooks (Qactivate_menubar_hook);
8242
8243 /* If it has changed current-menubar from previous value,
8244 really recompute the menu-bar from the value. */
8245 if (! NILP (Vlucid_menu_bar_dirty_flag))
8246 call0 (Qrecompute_lucid_menubar);
8247
8248 safe_run_hooks (Qmenu_bar_update_hook);
8249 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8250
8251 /* Redisplay the menu bar in case we changed it. */
8252 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8253 || defined (USE_GTK)
8254 if (FRAME_WINDOW_P (f)
8255 #if defined (MAC_OS)
8256 /* All frames on Mac OS share the same menubar. So only the
8257 selected frame should be allowed to set it. */
8258 && f == SELECTED_FRAME ()
8259 #endif
8260 )
8261 set_frame_menubar (f, 0, 0);
8262 else
8263 /* On a terminal screen, the menu bar is an ordinary screen
8264 line, and this makes it get updated. */
8265 w->update_mode_line = Qt;
8266 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8267 /* In the non-toolkit version, the menu bar is an ordinary screen
8268 line, and this makes it get updated. */
8269 w->update_mode_line = Qt;
8270 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8271
8272 unbind_to (count, Qnil);
8273 set_buffer_internal_1 (prev);
8274 }
8275 }
8276 }
8277
8278
8279 \f
8280 /***********************************************************************
8281 Output Cursor
8282 ***********************************************************************/
8283
8284 #ifdef HAVE_WINDOW_SYSTEM
8285
8286 /* EXPORT:
8287 Nominal cursor position -- where to draw output.
8288 HPOS and VPOS are window relative glyph matrix coordinates.
8289 X and Y are window relative pixel coordinates. */
8290
8291 struct cursor_pos output_cursor;
8292
8293
8294 /* EXPORT:
8295 Set the global variable output_cursor to CURSOR. All cursor
8296 positions are relative to updated_window. */
8297
8298 void
8299 set_output_cursor (cursor)
8300 struct cursor_pos *cursor;
8301 {
8302 output_cursor.hpos = cursor->hpos;
8303 output_cursor.vpos = cursor->vpos;
8304 output_cursor.x = cursor->x;
8305 output_cursor.y = cursor->y;
8306 }
8307
8308
8309 /* EXPORT for RIF:
8310 Set a nominal cursor position.
8311
8312 HPOS and VPOS are column/row positions in a window glyph matrix. X
8313 and Y are window text area relative pixel positions.
8314
8315 If this is done during an update, updated_window will contain the
8316 window that is being updated and the position is the future output
8317 cursor position for that window. If updated_window is null, use
8318 selected_window and display the cursor at the given position. */
8319
8320 void
8321 x_cursor_to (vpos, hpos, y, x)
8322 int vpos, hpos, y, x;
8323 {
8324 struct window *w;
8325
8326 /* If updated_window is not set, work on selected_window. */
8327 if (updated_window)
8328 w = updated_window;
8329 else
8330 w = XWINDOW (selected_window);
8331
8332 /* Set the output cursor. */
8333 output_cursor.hpos = hpos;
8334 output_cursor.vpos = vpos;
8335 output_cursor.x = x;
8336 output_cursor.y = y;
8337
8338 /* If not called as part of an update, really display the cursor.
8339 This will also set the cursor position of W. */
8340 if (updated_window == NULL)
8341 {
8342 BLOCK_INPUT;
8343 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8344 if (rif->flush_display_optional)
8345 rif->flush_display_optional (SELECTED_FRAME ());
8346 UNBLOCK_INPUT;
8347 }
8348 }
8349
8350 #endif /* HAVE_WINDOW_SYSTEM */
8351
8352 \f
8353 /***********************************************************************
8354 Tool-bars
8355 ***********************************************************************/
8356
8357 #ifdef HAVE_WINDOW_SYSTEM
8358
8359 /* Where the mouse was last time we reported a mouse event. */
8360
8361 FRAME_PTR last_mouse_frame;
8362
8363 /* Tool-bar item index of the item on which a mouse button was pressed
8364 or -1. */
8365
8366 int last_tool_bar_item;
8367
8368
8369 /* Update the tool-bar item list for frame F. This has to be done
8370 before we start to fill in any display lines. Called from
8371 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8372 and restore it here. */
8373
8374 static void
8375 update_tool_bar (f, save_match_data)
8376 struct frame *f;
8377 int save_match_data;
8378 {
8379 #ifdef USE_GTK
8380 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8381 #else
8382 int do_update = WINDOWP (f->tool_bar_window)
8383 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8384 #endif
8385
8386 if (do_update)
8387 {
8388 Lisp_Object window;
8389 struct window *w;
8390
8391 window = FRAME_SELECTED_WINDOW (f);
8392 w = XWINDOW (window);
8393
8394 /* If the user has switched buffers or windows, we need to
8395 recompute to reflect the new bindings. But we'll
8396 recompute when update_mode_lines is set too; that means
8397 that people can use force-mode-line-update to request
8398 that the menu bar be recomputed. The adverse effect on
8399 the rest of the redisplay algorithm is about the same as
8400 windows_or_buffers_changed anyway. */
8401 if (windows_or_buffers_changed
8402 || !NILP (w->update_mode_line)
8403 || update_mode_lines
8404 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8405 < BUF_MODIFF (XBUFFER (w->buffer)))
8406 != !NILP (w->last_had_star))
8407 || ((!NILP (Vtransient_mark_mode)
8408 && !NILP (XBUFFER (w->buffer)->mark_active))
8409 != !NILP (w->region_showing)))
8410 {
8411 struct buffer *prev = current_buffer;
8412 int count = SPECPDL_INDEX ();
8413 Lisp_Object old_tool_bar;
8414 struct gcpro gcpro1;
8415
8416 /* Set current_buffer to the buffer of the selected
8417 window of the frame, so that we get the right local
8418 keymaps. */
8419 set_buffer_internal_1 (XBUFFER (w->buffer));
8420
8421 /* Save match data, if we must. */
8422 if (save_match_data)
8423 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8424
8425 /* Make sure that we don't accidentally use bogus keymaps. */
8426 if (NILP (Voverriding_local_map_menu_flag))
8427 {
8428 specbind (Qoverriding_terminal_local_map, Qnil);
8429 specbind (Qoverriding_local_map, Qnil);
8430 }
8431
8432 old_tool_bar = f->tool_bar_items;
8433 GCPRO1 (old_tool_bar);
8434
8435 /* Build desired tool-bar items from keymaps. */
8436 BLOCK_INPUT;
8437 f->tool_bar_items
8438 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8439 UNBLOCK_INPUT;
8440
8441 /* Redisplay the tool-bar if we changed it. */
8442 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8443 w->update_mode_line = Qt;
8444
8445 UNGCPRO;
8446
8447 unbind_to (count, Qnil);
8448 set_buffer_internal_1 (prev);
8449 }
8450 }
8451 }
8452
8453
8454 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8455 F's desired tool-bar contents. F->tool_bar_items must have
8456 been set up previously by calling prepare_menu_bars. */
8457
8458 static void
8459 build_desired_tool_bar_string (f)
8460 struct frame *f;
8461 {
8462 int i, size, size_needed;
8463 struct gcpro gcpro1, gcpro2, gcpro3;
8464 Lisp_Object image, plist, props;
8465
8466 image = plist = props = Qnil;
8467 GCPRO3 (image, plist, props);
8468
8469 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8470 Otherwise, make a new string. */
8471
8472 /* The size of the string we might be able to reuse. */
8473 size = (STRINGP (f->desired_tool_bar_string)
8474 ? SCHARS (f->desired_tool_bar_string)
8475 : 0);
8476
8477 /* We need one space in the string for each image. */
8478 size_needed = f->n_tool_bar_items;
8479
8480 /* Reuse f->desired_tool_bar_string, if possible. */
8481 if (size < size_needed || NILP (f->desired_tool_bar_string))
8482 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8483 make_number (' '));
8484 else
8485 {
8486 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8487 Fremove_text_properties (make_number (0), make_number (size),
8488 props, f->desired_tool_bar_string);
8489 }
8490
8491 /* Put a `display' property on the string for the images to display,
8492 put a `menu_item' property on tool-bar items with a value that
8493 is the index of the item in F's tool-bar item vector. */
8494 for (i = 0; i < f->n_tool_bar_items; ++i)
8495 {
8496 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8497
8498 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8499 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8500 int hmargin, vmargin, relief, idx, end;
8501 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8502
8503 /* If image is a vector, choose the image according to the
8504 button state. */
8505 image = PROP (TOOL_BAR_ITEM_IMAGES);
8506 if (VECTORP (image))
8507 {
8508 if (enabled_p)
8509 idx = (selected_p
8510 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8511 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8512 else
8513 idx = (selected_p
8514 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8515 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8516
8517 xassert (ASIZE (image) >= idx);
8518 image = AREF (image, idx);
8519 }
8520 else
8521 idx = -1;
8522
8523 /* Ignore invalid image specifications. */
8524 if (!valid_image_p (image))
8525 continue;
8526
8527 /* Display the tool-bar button pressed, or depressed. */
8528 plist = Fcopy_sequence (XCDR (image));
8529
8530 /* Compute margin and relief to draw. */
8531 relief = (tool_bar_button_relief >= 0
8532 ? tool_bar_button_relief
8533 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8534 hmargin = vmargin = relief;
8535
8536 if (INTEGERP (Vtool_bar_button_margin)
8537 && XINT (Vtool_bar_button_margin) > 0)
8538 {
8539 hmargin += XFASTINT (Vtool_bar_button_margin);
8540 vmargin += XFASTINT (Vtool_bar_button_margin);
8541 }
8542 else if (CONSP (Vtool_bar_button_margin))
8543 {
8544 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8545 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8546 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8547
8548 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8549 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8550 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8551 }
8552
8553 if (auto_raise_tool_bar_buttons_p)
8554 {
8555 /* Add a `:relief' property to the image spec if the item is
8556 selected. */
8557 if (selected_p)
8558 {
8559 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8560 hmargin -= relief;
8561 vmargin -= relief;
8562 }
8563 }
8564 else
8565 {
8566 /* If image is selected, display it pressed, i.e. with a
8567 negative relief. If it's not selected, display it with a
8568 raised relief. */
8569 plist = Fplist_put (plist, QCrelief,
8570 (selected_p
8571 ? make_number (-relief)
8572 : make_number (relief)));
8573 hmargin -= relief;
8574 vmargin -= relief;
8575 }
8576
8577 /* Put a margin around the image. */
8578 if (hmargin || vmargin)
8579 {
8580 if (hmargin == vmargin)
8581 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8582 else
8583 plist = Fplist_put (plist, QCmargin,
8584 Fcons (make_number (hmargin),
8585 make_number (vmargin)));
8586 }
8587
8588 /* If button is not enabled, and we don't have special images
8589 for the disabled state, make the image appear disabled by
8590 applying an appropriate algorithm to it. */
8591 if (!enabled_p && idx < 0)
8592 plist = Fplist_put (plist, QCconversion, Qdisabled);
8593
8594 /* Put a `display' text property on the string for the image to
8595 display. Put a `menu-item' property on the string that gives
8596 the start of this item's properties in the tool-bar items
8597 vector. */
8598 image = Fcons (Qimage, plist);
8599 props = list4 (Qdisplay, image,
8600 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8601
8602 /* Let the last image hide all remaining spaces in the tool bar
8603 string. The string can be longer than needed when we reuse a
8604 previous string. */
8605 if (i + 1 == f->n_tool_bar_items)
8606 end = SCHARS (f->desired_tool_bar_string);
8607 else
8608 end = i + 1;
8609 Fadd_text_properties (make_number (i), make_number (end),
8610 props, f->desired_tool_bar_string);
8611 #undef PROP
8612 }
8613
8614 UNGCPRO;
8615 }
8616
8617
8618 /* Display one line of the tool-bar of frame IT->f. */
8619
8620 static void
8621 display_tool_bar_line (it)
8622 struct it *it;
8623 {
8624 struct glyph_row *row = it->glyph_row;
8625 int max_x = it->last_visible_x;
8626 struct glyph *last;
8627
8628 prepare_desired_row (row);
8629 row->y = it->current_y;
8630
8631 /* Note that this isn't made use of if the face hasn't a box,
8632 so there's no need to check the face here. */
8633 it->start_of_box_run_p = 1;
8634
8635 while (it->current_x < max_x)
8636 {
8637 int x_before, x, n_glyphs_before, i, nglyphs;
8638
8639 /* Get the next display element. */
8640 if (!get_next_display_element (it))
8641 break;
8642
8643 /* Produce glyphs. */
8644 x_before = it->current_x;
8645 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8646 PRODUCE_GLYPHS (it);
8647
8648 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8649 i = 0;
8650 x = x_before;
8651 while (i < nglyphs)
8652 {
8653 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8654
8655 if (x + glyph->pixel_width > max_x)
8656 {
8657 /* Glyph doesn't fit on line. */
8658 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8659 it->current_x = x;
8660 goto out;
8661 }
8662
8663 ++it->hpos;
8664 x += glyph->pixel_width;
8665 ++i;
8666 }
8667
8668 /* Stop at line ends. */
8669 if (ITERATOR_AT_END_OF_LINE_P (it))
8670 break;
8671
8672 set_iterator_to_next (it, 1);
8673 }
8674
8675 out:;
8676
8677 row->displays_text_p = row->used[TEXT_AREA] != 0;
8678 extend_face_to_end_of_line (it);
8679 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8680 last->right_box_line_p = 1;
8681 if (last == row->glyphs[TEXT_AREA])
8682 last->left_box_line_p = 1;
8683 compute_line_metrics (it);
8684
8685 /* If line is empty, make it occupy the rest of the tool-bar. */
8686 if (!row->displays_text_p)
8687 {
8688 row->height = row->phys_height = it->last_visible_y - row->y;
8689 row->ascent = row->phys_ascent = 0;
8690 }
8691
8692 row->full_width_p = 1;
8693 row->continued_p = 0;
8694 row->truncated_on_left_p = 0;
8695 row->truncated_on_right_p = 0;
8696
8697 it->current_x = it->hpos = 0;
8698 it->current_y += row->height;
8699 ++it->vpos;
8700 ++it->glyph_row;
8701 }
8702
8703
8704 /* Value is the number of screen lines needed to make all tool-bar
8705 items of frame F visible. */
8706
8707 static int
8708 tool_bar_lines_needed (f)
8709 struct frame *f;
8710 {
8711 struct window *w = XWINDOW (f->tool_bar_window);
8712 struct it it;
8713
8714 /* Initialize an iterator for iteration over
8715 F->desired_tool_bar_string in the tool-bar window of frame F. */
8716 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8717 it.first_visible_x = 0;
8718 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8719 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8720
8721 while (!ITERATOR_AT_END_P (&it))
8722 {
8723 it.glyph_row = w->desired_matrix->rows;
8724 clear_glyph_row (it.glyph_row);
8725 display_tool_bar_line (&it);
8726 }
8727
8728 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8729 }
8730
8731
8732 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8733 0, 1, 0,
8734 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8735 (frame)
8736 Lisp_Object frame;
8737 {
8738 struct frame *f;
8739 struct window *w;
8740 int nlines = 0;
8741
8742 if (NILP (frame))
8743 frame = selected_frame;
8744 else
8745 CHECK_FRAME (frame);
8746 f = XFRAME (frame);
8747
8748 if (WINDOWP (f->tool_bar_window)
8749 || (w = XWINDOW (f->tool_bar_window),
8750 WINDOW_TOTAL_LINES (w) > 0))
8751 {
8752 update_tool_bar (f, 1);
8753 if (f->n_tool_bar_items)
8754 {
8755 build_desired_tool_bar_string (f);
8756 nlines = tool_bar_lines_needed (f);
8757 }
8758 }
8759
8760 return make_number (nlines);
8761 }
8762
8763
8764 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8765 height should be changed. */
8766
8767 static int
8768 redisplay_tool_bar (f)
8769 struct frame *f;
8770 {
8771 struct window *w;
8772 struct it it;
8773 struct glyph_row *row;
8774 int change_height_p = 0;
8775
8776 #ifdef USE_GTK
8777 if (FRAME_EXTERNAL_TOOL_BAR (f))
8778 update_frame_tool_bar (f);
8779 return 0;
8780 #endif
8781
8782 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8783 do anything. This means you must start with tool-bar-lines
8784 non-zero to get the auto-sizing effect. Or in other words, you
8785 can turn off tool-bars by specifying tool-bar-lines zero. */
8786 if (!WINDOWP (f->tool_bar_window)
8787 || (w = XWINDOW (f->tool_bar_window),
8788 WINDOW_TOTAL_LINES (w) == 0))
8789 return 0;
8790
8791 /* Set up an iterator for the tool-bar window. */
8792 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8793 it.first_visible_x = 0;
8794 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8795 row = it.glyph_row;
8796
8797 /* Build a string that represents the contents of the tool-bar. */
8798 build_desired_tool_bar_string (f);
8799 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8800
8801 /* Display as many lines as needed to display all tool-bar items. */
8802 while (it.current_y < it.last_visible_y)
8803 display_tool_bar_line (&it);
8804
8805 /* It doesn't make much sense to try scrolling in the tool-bar
8806 window, so don't do it. */
8807 w->desired_matrix->no_scrolling_p = 1;
8808 w->must_be_updated_p = 1;
8809
8810 if (auto_resize_tool_bars_p)
8811 {
8812 int nlines;
8813
8814 /* If we couldn't display everything, change the tool-bar's
8815 height. */
8816 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8817 change_height_p = 1;
8818
8819 /* If there are blank lines at the end, except for a partially
8820 visible blank line at the end that is smaller than
8821 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8822 row = it.glyph_row - 1;
8823 if (!row->displays_text_p
8824 && row->height >= FRAME_LINE_HEIGHT (f))
8825 change_height_p = 1;
8826
8827 /* If row displays tool-bar items, but is partially visible,
8828 change the tool-bar's height. */
8829 if (row->displays_text_p
8830 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8831 change_height_p = 1;
8832
8833 /* Resize windows as needed by changing the `tool-bar-lines'
8834 frame parameter. */
8835 if (change_height_p
8836 && (nlines = tool_bar_lines_needed (f),
8837 nlines != WINDOW_TOTAL_LINES (w)))
8838 {
8839 extern Lisp_Object Qtool_bar_lines;
8840 Lisp_Object frame;
8841 int old_height = WINDOW_TOTAL_LINES (w);
8842
8843 XSETFRAME (frame, f);
8844 clear_glyph_matrix (w->desired_matrix);
8845 Fmodify_frame_parameters (frame,
8846 Fcons (Fcons (Qtool_bar_lines,
8847 make_number (nlines)),
8848 Qnil));
8849 if (WINDOW_TOTAL_LINES (w) != old_height)
8850 fonts_changed_p = 1;
8851 }
8852 }
8853
8854 return change_height_p;
8855 }
8856
8857
8858 /* Get information about the tool-bar item which is displayed in GLYPH
8859 on frame F. Return in *PROP_IDX the index where tool-bar item
8860 properties start in F->tool_bar_items. Value is zero if
8861 GLYPH doesn't display a tool-bar item. */
8862
8863 static int
8864 tool_bar_item_info (f, glyph, prop_idx)
8865 struct frame *f;
8866 struct glyph *glyph;
8867 int *prop_idx;
8868 {
8869 Lisp_Object prop;
8870 int success_p;
8871 int charpos;
8872
8873 /* This function can be called asynchronously, which means we must
8874 exclude any possibility that Fget_text_property signals an
8875 error. */
8876 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8877 charpos = max (0, charpos);
8878
8879 /* Get the text property `menu-item' at pos. The value of that
8880 property is the start index of this item's properties in
8881 F->tool_bar_items. */
8882 prop = Fget_text_property (make_number (charpos),
8883 Qmenu_item, f->current_tool_bar_string);
8884 if (INTEGERP (prop))
8885 {
8886 *prop_idx = XINT (prop);
8887 success_p = 1;
8888 }
8889 else
8890 success_p = 0;
8891
8892 return success_p;
8893 }
8894
8895 \f
8896 /* Get information about the tool-bar item at position X/Y on frame F.
8897 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8898 the current matrix of the tool-bar window of F, or NULL if not
8899 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8900 item in F->tool_bar_items. Value is
8901
8902 -1 if X/Y is not on a tool-bar item
8903 0 if X/Y is on the same item that was highlighted before.
8904 1 otherwise. */
8905
8906 static int
8907 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8908 struct frame *f;
8909 int x, y;
8910 struct glyph **glyph;
8911 int *hpos, *vpos, *prop_idx;
8912 {
8913 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8914 struct window *w = XWINDOW (f->tool_bar_window);
8915 int area;
8916
8917 /* Find the glyph under X/Y. */
8918 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8919 if (*glyph == NULL)
8920 return -1;
8921
8922 /* Get the start of this tool-bar item's properties in
8923 f->tool_bar_items. */
8924 if (!tool_bar_item_info (f, *glyph, prop_idx))
8925 return -1;
8926
8927 /* Is mouse on the highlighted item? */
8928 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8929 && *vpos >= dpyinfo->mouse_face_beg_row
8930 && *vpos <= dpyinfo->mouse_face_end_row
8931 && (*vpos > dpyinfo->mouse_face_beg_row
8932 || *hpos >= dpyinfo->mouse_face_beg_col)
8933 && (*vpos < dpyinfo->mouse_face_end_row
8934 || *hpos < dpyinfo->mouse_face_end_col
8935 || dpyinfo->mouse_face_past_end))
8936 return 0;
8937
8938 return 1;
8939 }
8940
8941
8942 /* EXPORT:
8943 Handle mouse button event on the tool-bar of frame F, at
8944 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8945 0 for button release. MODIFIERS is event modifiers for button
8946 release. */
8947
8948 void
8949 handle_tool_bar_click (f, x, y, down_p, modifiers)
8950 struct frame *f;
8951 int x, y, down_p;
8952 unsigned int modifiers;
8953 {
8954 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8955 struct window *w = XWINDOW (f->tool_bar_window);
8956 int hpos, vpos, prop_idx;
8957 struct glyph *glyph;
8958 Lisp_Object enabled_p;
8959
8960 /* If not on the highlighted tool-bar item, return. */
8961 frame_to_window_pixel_xy (w, &x, &y);
8962 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8963 return;
8964
8965 /* If item is disabled, do nothing. */
8966 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8967 if (NILP (enabled_p))
8968 return;
8969
8970 if (down_p)
8971 {
8972 /* Show item in pressed state. */
8973 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8974 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8975 last_tool_bar_item = prop_idx;
8976 }
8977 else
8978 {
8979 Lisp_Object key, frame;
8980 struct input_event event;
8981 EVENT_INIT (event);
8982
8983 /* Show item in released state. */
8984 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8985 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8986
8987 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8988
8989 XSETFRAME (frame, f);
8990 event.kind = TOOL_BAR_EVENT;
8991 event.frame_or_window = frame;
8992 event.arg = frame;
8993 kbd_buffer_store_event (&event);
8994
8995 event.kind = TOOL_BAR_EVENT;
8996 event.frame_or_window = frame;
8997 event.arg = key;
8998 event.modifiers = modifiers;
8999 kbd_buffer_store_event (&event);
9000 last_tool_bar_item = -1;
9001 }
9002 }
9003
9004
9005 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9006 tool-bar window-relative coordinates X/Y. Called from
9007 note_mouse_highlight. */
9008
9009 static void
9010 note_tool_bar_highlight (f, x, y)
9011 struct frame *f;
9012 int x, y;
9013 {
9014 Lisp_Object window = f->tool_bar_window;
9015 struct window *w = XWINDOW (window);
9016 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9017 int hpos, vpos;
9018 struct glyph *glyph;
9019 struct glyph_row *row;
9020 int i;
9021 Lisp_Object enabled_p;
9022 int prop_idx;
9023 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9024 int mouse_down_p, rc;
9025
9026 /* Function note_mouse_highlight is called with negative x(y
9027 values when mouse moves outside of the frame. */
9028 if (x <= 0 || y <= 0)
9029 {
9030 clear_mouse_face (dpyinfo);
9031 return;
9032 }
9033
9034 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9035 if (rc < 0)
9036 {
9037 /* Not on tool-bar item. */
9038 clear_mouse_face (dpyinfo);
9039 return;
9040 }
9041 else if (rc == 0)
9042 /* On same tool-bar item as before. */
9043 goto set_help_echo;
9044
9045 clear_mouse_face (dpyinfo);
9046
9047 /* Mouse is down, but on different tool-bar item? */
9048 mouse_down_p = (dpyinfo->grabbed
9049 && f == last_mouse_frame
9050 && FRAME_LIVE_P (f));
9051 if (mouse_down_p
9052 && last_tool_bar_item != prop_idx)
9053 return;
9054
9055 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9056 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9057
9058 /* If tool-bar item is not enabled, don't highlight it. */
9059 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9060 if (!NILP (enabled_p))
9061 {
9062 /* Compute the x-position of the glyph. In front and past the
9063 image is a space. We include this in the highlighted area. */
9064 row = MATRIX_ROW (w->current_matrix, vpos);
9065 for (i = x = 0; i < hpos; ++i)
9066 x += row->glyphs[TEXT_AREA][i].pixel_width;
9067
9068 /* Record this as the current active region. */
9069 dpyinfo->mouse_face_beg_col = hpos;
9070 dpyinfo->mouse_face_beg_row = vpos;
9071 dpyinfo->mouse_face_beg_x = x;
9072 dpyinfo->mouse_face_beg_y = row->y;
9073 dpyinfo->mouse_face_past_end = 0;
9074
9075 dpyinfo->mouse_face_end_col = hpos + 1;
9076 dpyinfo->mouse_face_end_row = vpos;
9077 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9078 dpyinfo->mouse_face_end_y = row->y;
9079 dpyinfo->mouse_face_window = window;
9080 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9081
9082 /* Display it as active. */
9083 show_mouse_face (dpyinfo, draw);
9084 dpyinfo->mouse_face_image_state = draw;
9085 }
9086
9087 set_help_echo:
9088
9089 /* Set help_echo_string to a help string to display for this tool-bar item.
9090 XTread_socket does the rest. */
9091 help_echo_object = help_echo_window = Qnil;
9092 help_echo_pos = -1;
9093 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9094 if (NILP (help_echo_string))
9095 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9096 }
9097
9098 #endif /* HAVE_WINDOW_SYSTEM */
9099
9100
9101 \f
9102 /************************************************************************
9103 Horizontal scrolling
9104 ************************************************************************/
9105
9106 static int hscroll_window_tree P_ ((Lisp_Object));
9107 static int hscroll_windows P_ ((Lisp_Object));
9108
9109 /* For all leaf windows in the window tree rooted at WINDOW, set their
9110 hscroll value so that PT is (i) visible in the window, and (ii) so
9111 that it is not within a certain margin at the window's left and
9112 right border. Value is non-zero if any window's hscroll has been
9113 changed. */
9114
9115 static int
9116 hscroll_window_tree (window)
9117 Lisp_Object window;
9118 {
9119 int hscrolled_p = 0;
9120 int hscroll_relative_p = FLOATP (Vhscroll_step);
9121 int hscroll_step_abs = 0;
9122 double hscroll_step_rel = 0;
9123
9124 if (hscroll_relative_p)
9125 {
9126 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9127 if (hscroll_step_rel < 0)
9128 {
9129 hscroll_relative_p = 0;
9130 hscroll_step_abs = 0;
9131 }
9132 }
9133 else if (INTEGERP (Vhscroll_step))
9134 {
9135 hscroll_step_abs = XINT (Vhscroll_step);
9136 if (hscroll_step_abs < 0)
9137 hscroll_step_abs = 0;
9138 }
9139 else
9140 hscroll_step_abs = 0;
9141
9142 while (WINDOWP (window))
9143 {
9144 struct window *w = XWINDOW (window);
9145
9146 if (WINDOWP (w->hchild))
9147 hscrolled_p |= hscroll_window_tree (w->hchild);
9148 else if (WINDOWP (w->vchild))
9149 hscrolled_p |= hscroll_window_tree (w->vchild);
9150 else if (w->cursor.vpos >= 0)
9151 {
9152 int h_margin;
9153 int text_area_width;
9154 struct glyph_row *current_cursor_row
9155 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9156 struct glyph_row *desired_cursor_row
9157 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9158 struct glyph_row *cursor_row
9159 = (desired_cursor_row->enabled_p
9160 ? desired_cursor_row
9161 : current_cursor_row);
9162
9163 text_area_width = window_box_width (w, TEXT_AREA);
9164
9165 /* Scroll when cursor is inside this scroll margin. */
9166 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9167
9168 if ((XFASTINT (w->hscroll)
9169 && w->cursor.x <= h_margin)
9170 || (cursor_row->enabled_p
9171 && cursor_row->truncated_on_right_p
9172 && (w->cursor.x >= text_area_width - h_margin)))
9173 {
9174 struct it it;
9175 int hscroll;
9176 struct buffer *saved_current_buffer;
9177 int pt;
9178 int wanted_x;
9179
9180 /* Find point in a display of infinite width. */
9181 saved_current_buffer = current_buffer;
9182 current_buffer = XBUFFER (w->buffer);
9183
9184 if (w == XWINDOW (selected_window))
9185 pt = BUF_PT (current_buffer);
9186 else
9187 {
9188 pt = marker_position (w->pointm);
9189 pt = max (BEGV, pt);
9190 pt = min (ZV, pt);
9191 }
9192
9193 /* Move iterator to pt starting at cursor_row->start in
9194 a line with infinite width. */
9195 init_to_row_start (&it, w, cursor_row);
9196 it.last_visible_x = INFINITY;
9197 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9198 current_buffer = saved_current_buffer;
9199
9200 /* Position cursor in window. */
9201 if (!hscroll_relative_p && hscroll_step_abs == 0)
9202 hscroll = max (0, (it.current_x
9203 - (ITERATOR_AT_END_OF_LINE_P (&it)
9204 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9205 : (text_area_width / 2))))
9206 / FRAME_COLUMN_WIDTH (it.f);
9207 else if (w->cursor.x >= text_area_width - h_margin)
9208 {
9209 if (hscroll_relative_p)
9210 wanted_x = text_area_width * (1 - hscroll_step_rel)
9211 - h_margin;
9212 else
9213 wanted_x = text_area_width
9214 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9215 - h_margin;
9216 hscroll
9217 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9218 }
9219 else
9220 {
9221 if (hscroll_relative_p)
9222 wanted_x = text_area_width * hscroll_step_rel
9223 + h_margin;
9224 else
9225 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9226 + h_margin;
9227 hscroll
9228 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9229 }
9230 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9231
9232 /* Don't call Fset_window_hscroll if value hasn't
9233 changed because it will prevent redisplay
9234 optimizations. */
9235 if (XFASTINT (w->hscroll) != hscroll)
9236 {
9237 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9238 w->hscroll = make_number (hscroll);
9239 hscrolled_p = 1;
9240 }
9241 }
9242 }
9243
9244 window = w->next;
9245 }
9246
9247 /* Value is non-zero if hscroll of any leaf window has been changed. */
9248 return hscrolled_p;
9249 }
9250
9251
9252 /* Set hscroll so that cursor is visible and not inside horizontal
9253 scroll margins for all windows in the tree rooted at WINDOW. See
9254 also hscroll_window_tree above. Value is non-zero if any window's
9255 hscroll has been changed. If it has, desired matrices on the frame
9256 of WINDOW are cleared. */
9257
9258 static int
9259 hscroll_windows (window)
9260 Lisp_Object window;
9261 {
9262 int hscrolled_p;
9263
9264 if (automatic_hscrolling_p)
9265 {
9266 hscrolled_p = hscroll_window_tree (window);
9267 if (hscrolled_p)
9268 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9269 }
9270 else
9271 hscrolled_p = 0;
9272 return hscrolled_p;
9273 }
9274
9275
9276 \f
9277 /************************************************************************
9278 Redisplay
9279 ************************************************************************/
9280
9281 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9282 to a non-zero value. This is sometimes handy to have in a debugger
9283 session. */
9284
9285 #if GLYPH_DEBUG
9286
9287 /* First and last unchanged row for try_window_id. */
9288
9289 int debug_first_unchanged_at_end_vpos;
9290 int debug_last_unchanged_at_beg_vpos;
9291
9292 /* Delta vpos and y. */
9293
9294 int debug_dvpos, debug_dy;
9295
9296 /* Delta in characters and bytes for try_window_id. */
9297
9298 int debug_delta, debug_delta_bytes;
9299
9300 /* Values of window_end_pos and window_end_vpos at the end of
9301 try_window_id. */
9302
9303 EMACS_INT debug_end_pos, debug_end_vpos;
9304
9305 /* Append a string to W->desired_matrix->method. FMT is a printf
9306 format string. A1...A9 are a supplement for a variable-length
9307 argument list. If trace_redisplay_p is non-zero also printf the
9308 resulting string to stderr. */
9309
9310 static void
9311 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9312 struct window *w;
9313 char *fmt;
9314 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9315 {
9316 char buffer[512];
9317 char *method = w->desired_matrix->method;
9318 int len = strlen (method);
9319 int size = sizeof w->desired_matrix->method;
9320 int remaining = size - len - 1;
9321
9322 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9323 if (len && remaining)
9324 {
9325 method[len] = '|';
9326 --remaining, ++len;
9327 }
9328
9329 strncpy (method + len, buffer, remaining);
9330
9331 if (trace_redisplay_p)
9332 fprintf (stderr, "%p (%s): %s\n",
9333 w,
9334 ((BUFFERP (w->buffer)
9335 && STRINGP (XBUFFER (w->buffer)->name))
9336 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9337 : "no buffer"),
9338 buffer);
9339 }
9340
9341 #endif /* GLYPH_DEBUG */
9342
9343
9344 /* Value is non-zero if all changes in window W, which displays
9345 current_buffer, are in the text between START and END. START is a
9346 buffer position, END is given as a distance from Z. Used in
9347 redisplay_internal for display optimization. */
9348
9349 static INLINE int
9350 text_outside_line_unchanged_p (w, start, end)
9351 struct window *w;
9352 int start, end;
9353 {
9354 int unchanged_p = 1;
9355
9356 /* If text or overlays have changed, see where. */
9357 if (XFASTINT (w->last_modified) < MODIFF
9358 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9359 {
9360 /* Gap in the line? */
9361 if (GPT < start || Z - GPT < end)
9362 unchanged_p = 0;
9363
9364 /* Changes start in front of the line, or end after it? */
9365 if (unchanged_p
9366 && (BEG_UNCHANGED < start - 1
9367 || END_UNCHANGED < end))
9368 unchanged_p = 0;
9369
9370 /* If selective display, can't optimize if changes start at the
9371 beginning of the line. */
9372 if (unchanged_p
9373 && INTEGERP (current_buffer->selective_display)
9374 && XINT (current_buffer->selective_display) > 0
9375 && (BEG_UNCHANGED < start || GPT <= start))
9376 unchanged_p = 0;
9377
9378 /* If there are overlays at the start or end of the line, these
9379 may have overlay strings with newlines in them. A change at
9380 START, for instance, may actually concern the display of such
9381 overlay strings as well, and they are displayed on different
9382 lines. So, quickly rule out this case. (For the future, it
9383 might be desirable to implement something more telling than
9384 just BEG/END_UNCHANGED.) */
9385 if (unchanged_p)
9386 {
9387 if (BEG + BEG_UNCHANGED == start
9388 && overlay_touches_p (start))
9389 unchanged_p = 0;
9390 if (END_UNCHANGED == end
9391 && overlay_touches_p (Z - end))
9392 unchanged_p = 0;
9393 }
9394 }
9395
9396 return unchanged_p;
9397 }
9398
9399
9400 /* Do a frame update, taking possible shortcuts into account. This is
9401 the main external entry point for redisplay.
9402
9403 If the last redisplay displayed an echo area message and that message
9404 is no longer requested, we clear the echo area or bring back the
9405 mini-buffer if that is in use. */
9406
9407 void
9408 redisplay ()
9409 {
9410 redisplay_internal (0);
9411 }
9412
9413
9414 static Lisp_Object
9415 overlay_arrow_string_or_property (var, pbitmap)
9416 Lisp_Object var;
9417 int *pbitmap;
9418 {
9419 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9420 Lisp_Object bitmap;
9421
9422 if (pbitmap)
9423 {
9424 *pbitmap = 0;
9425 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9426 *pbitmap = XINT (bitmap);
9427 }
9428
9429 if (!NILP (pstr))
9430 return pstr;
9431 return Voverlay_arrow_string;
9432 }
9433
9434 /* Return 1 if there are any overlay-arrows in current_buffer. */
9435 static int
9436 overlay_arrow_in_current_buffer_p ()
9437 {
9438 Lisp_Object vlist;
9439
9440 for (vlist = Voverlay_arrow_variable_list;
9441 CONSP (vlist);
9442 vlist = XCDR (vlist))
9443 {
9444 Lisp_Object var = XCAR (vlist);
9445 Lisp_Object val;
9446
9447 if (!SYMBOLP (var))
9448 continue;
9449 val = find_symbol_value (var);
9450 if (MARKERP (val)
9451 && current_buffer == XMARKER (val)->buffer)
9452 return 1;
9453 }
9454 return 0;
9455 }
9456
9457
9458 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9459 has changed. */
9460
9461 static int
9462 overlay_arrows_changed_p ()
9463 {
9464 Lisp_Object vlist;
9465
9466 for (vlist = Voverlay_arrow_variable_list;
9467 CONSP (vlist);
9468 vlist = XCDR (vlist))
9469 {
9470 Lisp_Object var = XCAR (vlist);
9471 Lisp_Object val, pstr;
9472
9473 if (!SYMBOLP (var))
9474 continue;
9475 val = find_symbol_value (var);
9476 if (!MARKERP (val))
9477 continue;
9478 if (! EQ (COERCE_MARKER (val),
9479 Fget (var, Qlast_arrow_position))
9480 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9481 EQ (pstr, Fget (var, Qlast_arrow_string))))
9482 return 1;
9483 }
9484 return 0;
9485 }
9486
9487 /* Mark overlay arrows to be updated on next redisplay. */
9488
9489 static void
9490 update_overlay_arrows (up_to_date)
9491 int up_to_date;
9492 {
9493 Lisp_Object vlist;
9494
9495 for (vlist = Voverlay_arrow_variable_list;
9496 CONSP (vlist);
9497 vlist = XCDR (vlist))
9498 {
9499 Lisp_Object var = XCAR (vlist);
9500
9501 if (!SYMBOLP (var))
9502 continue;
9503
9504 if (up_to_date > 0)
9505 {
9506 Lisp_Object val = find_symbol_value (var);
9507 Fput (var, Qlast_arrow_position,
9508 COERCE_MARKER (val));
9509 Fput (var, Qlast_arrow_string,
9510 overlay_arrow_string_or_property (var, 0));
9511 }
9512 else if (up_to_date < 0
9513 || !NILP (Fget (var, Qlast_arrow_position)))
9514 {
9515 Fput (var, Qlast_arrow_position, Qt);
9516 Fput (var, Qlast_arrow_string, Qt);
9517 }
9518 }
9519 }
9520
9521
9522 /* Return overlay arrow string at row, or nil. */
9523
9524 static Lisp_Object
9525 overlay_arrow_at_row (f, row, pbitmap)
9526 struct frame *f;
9527 struct glyph_row *row;
9528 int *pbitmap;
9529 {
9530 Lisp_Object vlist;
9531
9532 for (vlist = Voverlay_arrow_variable_list;
9533 CONSP (vlist);
9534 vlist = XCDR (vlist))
9535 {
9536 Lisp_Object var = XCAR (vlist);
9537 Lisp_Object val;
9538
9539 if (!SYMBOLP (var))
9540 continue;
9541
9542 val = find_symbol_value (var);
9543
9544 if (MARKERP (val)
9545 && current_buffer == XMARKER (val)->buffer
9546 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9547 {
9548 val = overlay_arrow_string_or_property (var, pbitmap);
9549 if (FRAME_WINDOW_P (f))
9550 return Qt;
9551 else if (STRINGP (val))
9552 return val;
9553 break;
9554 }
9555 }
9556
9557 *pbitmap = 0;
9558 return Qnil;
9559 }
9560
9561 /* Return 1 if point moved out of or into a composition. Otherwise
9562 return 0. PREV_BUF and PREV_PT are the last point buffer and
9563 position. BUF and PT are the current point buffer and position. */
9564
9565 int
9566 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9567 struct buffer *prev_buf, *buf;
9568 int prev_pt, pt;
9569 {
9570 int start, end;
9571 Lisp_Object prop;
9572 Lisp_Object buffer;
9573
9574 XSETBUFFER (buffer, buf);
9575 /* Check a composition at the last point if point moved within the
9576 same buffer. */
9577 if (prev_buf == buf)
9578 {
9579 if (prev_pt == pt)
9580 /* Point didn't move. */
9581 return 0;
9582
9583 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9584 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9585 && COMPOSITION_VALID_P (start, end, prop)
9586 && start < prev_pt && end > prev_pt)
9587 /* The last point was within the composition. Return 1 iff
9588 point moved out of the composition. */
9589 return (pt <= start || pt >= end);
9590 }
9591
9592 /* Check a composition at the current point. */
9593 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9594 && find_composition (pt, -1, &start, &end, &prop, buffer)
9595 && COMPOSITION_VALID_P (start, end, prop)
9596 && start < pt && end > pt);
9597 }
9598
9599
9600 /* Reconsider the setting of B->clip_changed which is displayed
9601 in window W. */
9602
9603 static INLINE void
9604 reconsider_clip_changes (w, b)
9605 struct window *w;
9606 struct buffer *b;
9607 {
9608 if (b->clip_changed
9609 && !NILP (w->window_end_valid)
9610 && w->current_matrix->buffer == b
9611 && w->current_matrix->zv == BUF_ZV (b)
9612 && w->current_matrix->begv == BUF_BEGV (b))
9613 b->clip_changed = 0;
9614
9615 /* If display wasn't paused, and W is not a tool bar window, see if
9616 point has been moved into or out of a composition. In that case,
9617 we set b->clip_changed to 1 to force updating the screen. If
9618 b->clip_changed has already been set to 1, we can skip this
9619 check. */
9620 if (!b->clip_changed
9621 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9622 {
9623 int pt;
9624
9625 if (w == XWINDOW (selected_window))
9626 pt = BUF_PT (current_buffer);
9627 else
9628 pt = marker_position (w->pointm);
9629
9630 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9631 || pt != XINT (w->last_point))
9632 && check_point_in_composition (w->current_matrix->buffer,
9633 XINT (w->last_point),
9634 XBUFFER (w->buffer), pt))
9635 b->clip_changed = 1;
9636 }
9637 }
9638 \f
9639
9640 /* Select FRAME to forward the values of frame-local variables into C
9641 variables so that the redisplay routines can access those values
9642 directly. */
9643
9644 static void
9645 select_frame_for_redisplay (frame)
9646 Lisp_Object frame;
9647 {
9648 Lisp_Object tail, sym, val;
9649 Lisp_Object old = selected_frame;
9650
9651 selected_frame = frame;
9652
9653 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9654 if (CONSP (XCAR (tail))
9655 && (sym = XCAR (XCAR (tail)),
9656 SYMBOLP (sym))
9657 && (sym = indirect_variable (sym),
9658 val = SYMBOL_VALUE (sym),
9659 (BUFFER_LOCAL_VALUEP (val)
9660 || SOME_BUFFER_LOCAL_VALUEP (val)))
9661 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9662 Fsymbol_value (sym);
9663
9664 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9665 if (CONSP (XCAR (tail))
9666 && (sym = XCAR (XCAR (tail)),
9667 SYMBOLP (sym))
9668 && (sym = indirect_variable (sym),
9669 val = SYMBOL_VALUE (sym),
9670 (BUFFER_LOCAL_VALUEP (val)
9671 || SOME_BUFFER_LOCAL_VALUEP (val)))
9672 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9673 Fsymbol_value (sym);
9674 }
9675
9676
9677 #define STOP_POLLING \
9678 do { if (! polling_stopped_here) stop_polling (); \
9679 polling_stopped_here = 1; } while (0)
9680
9681 #define RESUME_POLLING \
9682 do { if (polling_stopped_here) start_polling (); \
9683 polling_stopped_here = 0; } while (0)
9684
9685
9686 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9687 response to any user action; therefore, we should preserve the echo
9688 area. (Actually, our caller does that job.) Perhaps in the future
9689 avoid recentering windows if it is not necessary; currently that
9690 causes some problems. */
9691
9692 static void
9693 redisplay_internal (preserve_echo_area)
9694 int preserve_echo_area;
9695 {
9696 struct window *w = XWINDOW (selected_window);
9697 struct frame *f = XFRAME (w->frame);
9698 int pause;
9699 int must_finish = 0;
9700 struct text_pos tlbufpos, tlendpos;
9701 int number_of_visible_frames;
9702 int count;
9703 struct frame *sf = SELECTED_FRAME ();
9704 int polling_stopped_here = 0;
9705
9706 /* Non-zero means redisplay has to consider all windows on all
9707 frames. Zero means, only selected_window is considered. */
9708 int consider_all_windows_p;
9709
9710 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9711
9712 /* No redisplay if running in batch mode or frame is not yet fully
9713 initialized, or redisplay is explicitly turned off by setting
9714 Vinhibit_redisplay. */
9715 if (noninteractive
9716 || !NILP (Vinhibit_redisplay)
9717 || !f->glyphs_initialized_p)
9718 return;
9719
9720 /* The flag redisplay_performed_directly_p is set by
9721 direct_output_for_insert when it already did the whole screen
9722 update necessary. */
9723 if (redisplay_performed_directly_p)
9724 {
9725 redisplay_performed_directly_p = 0;
9726 if (!hscroll_windows (selected_window))
9727 return;
9728 }
9729
9730 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9731 if (popup_activated ())
9732 return;
9733 #endif
9734
9735 /* I don't think this happens but let's be paranoid. */
9736 if (redisplaying_p)
9737 return;
9738
9739 /* Record a function that resets redisplaying_p to its old value
9740 when we leave this function. */
9741 count = SPECPDL_INDEX ();
9742 record_unwind_protect (unwind_redisplay,
9743 Fcons (make_number (redisplaying_p), selected_frame));
9744 ++redisplaying_p;
9745 specbind (Qinhibit_free_realized_faces, Qnil);
9746
9747 retry:
9748 pause = 0;
9749 reconsider_clip_changes (w, current_buffer);
9750
9751 /* If new fonts have been loaded that make a glyph matrix adjustment
9752 necessary, do it. */
9753 if (fonts_changed_p)
9754 {
9755 adjust_glyphs (NULL);
9756 ++windows_or_buffers_changed;
9757 fonts_changed_p = 0;
9758 }
9759
9760 /* If face_change_count is non-zero, init_iterator will free all
9761 realized faces, which includes the faces referenced from current
9762 matrices. So, we can't reuse current matrices in this case. */
9763 if (face_change_count)
9764 ++windows_or_buffers_changed;
9765
9766 if (! FRAME_WINDOW_P (sf)
9767 && previous_terminal_frame != sf)
9768 {
9769 /* Since frames on an ASCII terminal share the same display
9770 area, displaying a different frame means redisplay the whole
9771 thing. */
9772 windows_or_buffers_changed++;
9773 SET_FRAME_GARBAGED (sf);
9774 XSETFRAME (Vterminal_frame, sf);
9775 }
9776 previous_terminal_frame = sf;
9777
9778 /* Set the visible flags for all frames. Do this before checking
9779 for resized or garbaged frames; they want to know if their frames
9780 are visible. See the comment in frame.h for
9781 FRAME_SAMPLE_VISIBILITY. */
9782 {
9783 Lisp_Object tail, frame;
9784
9785 number_of_visible_frames = 0;
9786
9787 FOR_EACH_FRAME (tail, frame)
9788 {
9789 struct frame *f = XFRAME (frame);
9790
9791 FRAME_SAMPLE_VISIBILITY (f);
9792 if (FRAME_VISIBLE_P (f))
9793 ++number_of_visible_frames;
9794 clear_desired_matrices (f);
9795 }
9796 }
9797
9798 /* Notice any pending interrupt request to change frame size. */
9799 do_pending_window_change (1);
9800
9801 /* Clear frames marked as garbaged. */
9802 if (frame_garbaged)
9803 clear_garbaged_frames ();
9804
9805 /* Build menubar and tool-bar items. */
9806 prepare_menu_bars ();
9807
9808 if (windows_or_buffers_changed)
9809 update_mode_lines++;
9810
9811 /* Detect case that we need to write or remove a star in the mode line. */
9812 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9813 {
9814 w->update_mode_line = Qt;
9815 if (buffer_shared > 1)
9816 update_mode_lines++;
9817 }
9818
9819 /* If %c is in the mode line, update it if needed. */
9820 if (!NILP (w->column_number_displayed)
9821 /* This alternative quickly identifies a common case
9822 where no change is needed. */
9823 && !(PT == XFASTINT (w->last_point)
9824 && XFASTINT (w->last_modified) >= MODIFF
9825 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9826 && (XFASTINT (w->column_number_displayed)
9827 != (int) current_column ())) /* iftc */
9828 w->update_mode_line = Qt;
9829
9830 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9831
9832 /* The variable buffer_shared is set in redisplay_window and
9833 indicates that we redisplay a buffer in different windows. See
9834 there. */
9835 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9836 || cursor_type_changed);
9837
9838 /* If specs for an arrow have changed, do thorough redisplay
9839 to ensure we remove any arrow that should no longer exist. */
9840 if (overlay_arrows_changed_p ())
9841 consider_all_windows_p = windows_or_buffers_changed = 1;
9842
9843 /* Normally the message* functions will have already displayed and
9844 updated the echo area, but the frame may have been trashed, or
9845 the update may have been preempted, so display the echo area
9846 again here. Checking message_cleared_p captures the case that
9847 the echo area should be cleared. */
9848 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9849 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9850 || (message_cleared_p
9851 && minibuf_level == 0
9852 /* If the mini-window is currently selected, this means the
9853 echo-area doesn't show through. */
9854 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9855 {
9856 int window_height_changed_p = echo_area_display (0);
9857 must_finish = 1;
9858
9859 /* If we don't display the current message, don't clear the
9860 message_cleared_p flag, because, if we did, we wouldn't clear
9861 the echo area in the next redisplay which doesn't preserve
9862 the echo area. */
9863 if (!display_last_displayed_message_p)
9864 message_cleared_p = 0;
9865
9866 if (fonts_changed_p)
9867 goto retry;
9868 else if (window_height_changed_p)
9869 {
9870 consider_all_windows_p = 1;
9871 ++update_mode_lines;
9872 ++windows_or_buffers_changed;
9873
9874 /* If window configuration was changed, frames may have been
9875 marked garbaged. Clear them or we will experience
9876 surprises wrt scrolling. */
9877 if (frame_garbaged)
9878 clear_garbaged_frames ();
9879 }
9880 }
9881 else if (EQ (selected_window, minibuf_window)
9882 && (current_buffer->clip_changed
9883 || XFASTINT (w->last_modified) < MODIFF
9884 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9885 && resize_mini_window (w, 0))
9886 {
9887 /* Resized active mini-window to fit the size of what it is
9888 showing if its contents might have changed. */
9889 must_finish = 1;
9890 consider_all_windows_p = 1;
9891 ++windows_or_buffers_changed;
9892 ++update_mode_lines;
9893
9894 /* If window configuration was changed, frames may have been
9895 marked garbaged. Clear them or we will experience
9896 surprises wrt scrolling. */
9897 if (frame_garbaged)
9898 clear_garbaged_frames ();
9899 }
9900
9901
9902 /* If showing the region, and mark has changed, we must redisplay
9903 the whole window. The assignment to this_line_start_pos prevents
9904 the optimization directly below this if-statement. */
9905 if (((!NILP (Vtransient_mark_mode)
9906 && !NILP (XBUFFER (w->buffer)->mark_active))
9907 != !NILP (w->region_showing))
9908 || (!NILP (w->region_showing)
9909 && !EQ (w->region_showing,
9910 Fmarker_position (XBUFFER (w->buffer)->mark))))
9911 CHARPOS (this_line_start_pos) = 0;
9912
9913 /* Optimize the case that only the line containing the cursor in the
9914 selected window has changed. Variables starting with this_ are
9915 set in display_line and record information about the line
9916 containing the cursor. */
9917 tlbufpos = this_line_start_pos;
9918 tlendpos = this_line_end_pos;
9919 if (!consider_all_windows_p
9920 && CHARPOS (tlbufpos) > 0
9921 && NILP (w->update_mode_line)
9922 && !current_buffer->clip_changed
9923 && !current_buffer->prevent_redisplay_optimizations_p
9924 && FRAME_VISIBLE_P (XFRAME (w->frame))
9925 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9926 /* Make sure recorded data applies to current buffer, etc. */
9927 && this_line_buffer == current_buffer
9928 && current_buffer == XBUFFER (w->buffer)
9929 && NILP (w->force_start)
9930 && NILP (w->optional_new_start)
9931 /* Point must be on the line that we have info recorded about. */
9932 && PT >= CHARPOS (tlbufpos)
9933 && PT <= Z - CHARPOS (tlendpos)
9934 /* All text outside that line, including its final newline,
9935 must be unchanged */
9936 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9937 CHARPOS (tlendpos)))
9938 {
9939 if (CHARPOS (tlbufpos) > BEGV
9940 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9941 && (CHARPOS (tlbufpos) == ZV
9942 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9943 /* Former continuation line has disappeared by becoming empty */
9944 goto cancel;
9945 else if (XFASTINT (w->last_modified) < MODIFF
9946 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9947 || MINI_WINDOW_P (w))
9948 {
9949 /* We have to handle the case of continuation around a
9950 wide-column character (See the comment in indent.c around
9951 line 885).
9952
9953 For instance, in the following case:
9954
9955 -------- Insert --------
9956 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9957 J_I_ ==> J_I_ `^^' are cursors.
9958 ^^ ^^
9959 -------- --------
9960
9961 As we have to redraw the line above, we should goto cancel. */
9962
9963 struct it it;
9964 int line_height_before = this_line_pixel_height;
9965
9966 /* Note that start_display will handle the case that the
9967 line starting at tlbufpos is a continuation lines. */
9968 start_display (&it, w, tlbufpos);
9969
9970 /* Implementation note: It this still necessary? */
9971 if (it.current_x != this_line_start_x)
9972 goto cancel;
9973
9974 TRACE ((stderr, "trying display optimization 1\n"));
9975 w->cursor.vpos = -1;
9976 overlay_arrow_seen = 0;
9977 it.vpos = this_line_vpos;
9978 it.current_y = this_line_y;
9979 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9980 display_line (&it);
9981
9982 /* If line contains point, is not continued,
9983 and ends at same distance from eob as before, we win */
9984 if (w->cursor.vpos >= 0
9985 /* Line is not continued, otherwise this_line_start_pos
9986 would have been set to 0 in display_line. */
9987 && CHARPOS (this_line_start_pos)
9988 /* Line ends as before. */
9989 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9990 /* Line has same height as before. Otherwise other lines
9991 would have to be shifted up or down. */
9992 && this_line_pixel_height == line_height_before)
9993 {
9994 /* If this is not the window's last line, we must adjust
9995 the charstarts of the lines below. */
9996 if (it.current_y < it.last_visible_y)
9997 {
9998 struct glyph_row *row
9999 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10000 int delta, delta_bytes;
10001
10002 if (Z - CHARPOS (tlendpos) == ZV)
10003 {
10004 /* This line ends at end of (accessible part of)
10005 buffer. There is no newline to count. */
10006 delta = (Z
10007 - CHARPOS (tlendpos)
10008 - MATRIX_ROW_START_CHARPOS (row));
10009 delta_bytes = (Z_BYTE
10010 - BYTEPOS (tlendpos)
10011 - MATRIX_ROW_START_BYTEPOS (row));
10012 }
10013 else
10014 {
10015 /* This line ends in a newline. Must take
10016 account of the newline and the rest of the
10017 text that follows. */
10018 delta = (Z
10019 - CHARPOS (tlendpos)
10020 - MATRIX_ROW_START_CHARPOS (row));
10021 delta_bytes = (Z_BYTE
10022 - BYTEPOS (tlendpos)
10023 - MATRIX_ROW_START_BYTEPOS (row));
10024 }
10025
10026 increment_matrix_positions (w->current_matrix,
10027 this_line_vpos + 1,
10028 w->current_matrix->nrows,
10029 delta, delta_bytes);
10030 }
10031
10032 /* If this row displays text now but previously didn't,
10033 or vice versa, w->window_end_vpos may have to be
10034 adjusted. */
10035 if ((it.glyph_row - 1)->displays_text_p)
10036 {
10037 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10038 XSETINT (w->window_end_vpos, this_line_vpos);
10039 }
10040 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10041 && this_line_vpos > 0)
10042 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10043 w->window_end_valid = Qnil;
10044
10045 /* Update hint: No need to try to scroll in update_window. */
10046 w->desired_matrix->no_scrolling_p = 1;
10047
10048 #if GLYPH_DEBUG
10049 *w->desired_matrix->method = 0;
10050 debug_method_add (w, "optimization 1");
10051 #endif
10052 #ifdef HAVE_WINDOW_SYSTEM
10053 update_window_fringes (w, 0);
10054 #endif
10055 goto update;
10056 }
10057 else
10058 goto cancel;
10059 }
10060 else if (/* Cursor position hasn't changed. */
10061 PT == XFASTINT (w->last_point)
10062 /* Make sure the cursor was last displayed
10063 in this window. Otherwise we have to reposition it. */
10064 && 0 <= w->cursor.vpos
10065 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10066 {
10067 if (!must_finish)
10068 {
10069 do_pending_window_change (1);
10070
10071 /* We used to always goto end_of_redisplay here, but this
10072 isn't enough if we have a blinking cursor. */
10073 if (w->cursor_off_p == w->last_cursor_off_p)
10074 goto end_of_redisplay;
10075 }
10076 goto update;
10077 }
10078 /* If highlighting the region, or if the cursor is in the echo area,
10079 then we can't just move the cursor. */
10080 else if (! (!NILP (Vtransient_mark_mode)
10081 && !NILP (current_buffer->mark_active))
10082 && (EQ (selected_window, current_buffer->last_selected_window)
10083 || highlight_nonselected_windows)
10084 && NILP (w->region_showing)
10085 && NILP (Vshow_trailing_whitespace)
10086 && !cursor_in_echo_area)
10087 {
10088 struct it it;
10089 struct glyph_row *row;
10090
10091 /* Skip from tlbufpos to PT and see where it is. Note that
10092 PT may be in invisible text. If so, we will end at the
10093 next visible position. */
10094 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10095 NULL, DEFAULT_FACE_ID);
10096 it.current_x = this_line_start_x;
10097 it.current_y = this_line_y;
10098 it.vpos = this_line_vpos;
10099
10100 /* The call to move_it_to stops in front of PT, but
10101 moves over before-strings. */
10102 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10103
10104 if (it.vpos == this_line_vpos
10105 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10106 row->enabled_p))
10107 {
10108 xassert (this_line_vpos == it.vpos);
10109 xassert (this_line_y == it.current_y);
10110 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10111 #if GLYPH_DEBUG
10112 *w->desired_matrix->method = 0;
10113 debug_method_add (w, "optimization 3");
10114 #endif
10115 goto update;
10116 }
10117 else
10118 goto cancel;
10119 }
10120
10121 cancel:
10122 /* Text changed drastically or point moved off of line. */
10123 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10124 }
10125
10126 CHARPOS (this_line_start_pos) = 0;
10127 consider_all_windows_p |= buffer_shared > 1;
10128 ++clear_face_cache_count;
10129
10130
10131 /* Build desired matrices, and update the display. If
10132 consider_all_windows_p is non-zero, do it for all windows on all
10133 frames. Otherwise do it for selected_window, only. */
10134
10135 if (consider_all_windows_p)
10136 {
10137 Lisp_Object tail, frame;
10138 int i, n = 0, size = 50;
10139 struct frame **updated
10140 = (struct frame **) alloca (size * sizeof *updated);
10141
10142 /* Clear the face cache eventually. */
10143 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10144 {
10145 clear_face_cache (0);
10146 clear_face_cache_count = 0;
10147 }
10148
10149 /* Recompute # windows showing selected buffer. This will be
10150 incremented each time such a window is displayed. */
10151 buffer_shared = 0;
10152
10153 FOR_EACH_FRAME (tail, frame)
10154 {
10155 struct frame *f = XFRAME (frame);
10156
10157 if (FRAME_WINDOW_P (f) || f == sf)
10158 {
10159 if (! EQ (frame, selected_frame))
10160 /* Select the frame, for the sake of frame-local
10161 variables. */
10162 select_frame_for_redisplay (frame);
10163
10164 #ifdef HAVE_WINDOW_SYSTEM
10165 if (clear_face_cache_count % 50 == 0
10166 && FRAME_WINDOW_P (f))
10167 clear_image_cache (f, 0);
10168 #endif /* HAVE_WINDOW_SYSTEM */
10169
10170 /* Mark all the scroll bars to be removed; we'll redeem
10171 the ones we want when we redisplay their windows. */
10172 if (condemn_scroll_bars_hook)
10173 condemn_scroll_bars_hook (f);
10174
10175 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10176 redisplay_windows (FRAME_ROOT_WINDOW (f));
10177
10178 /* Any scroll bars which redisplay_windows should have
10179 nuked should now go away. */
10180 if (judge_scroll_bars_hook)
10181 judge_scroll_bars_hook (f);
10182
10183 /* If fonts changed, display again. */
10184 /* ??? rms: I suspect it is a mistake to jump all the way
10185 back to retry here. It should just retry this frame. */
10186 if (fonts_changed_p)
10187 goto retry;
10188
10189 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10190 {
10191 /* See if we have to hscroll. */
10192 if (hscroll_windows (f->root_window))
10193 goto retry;
10194
10195 /* Prevent various kinds of signals during display
10196 update. stdio is not robust about handling
10197 signals, which can cause an apparent I/O
10198 error. */
10199 if (interrupt_input)
10200 unrequest_sigio ();
10201 STOP_POLLING;
10202
10203 /* Update the display. */
10204 set_window_update_flags (XWINDOW (f->root_window), 1);
10205 pause |= update_frame (f, 0, 0);
10206 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10207 if (pause)
10208 break;
10209 #endif
10210
10211 if (n == size)
10212 {
10213 int nbytes = size * sizeof *updated;
10214 struct frame **p = (struct frame **) alloca (2 * nbytes);
10215 bcopy (updated, p, nbytes);
10216 size *= 2;
10217 }
10218
10219 updated[n++] = f;
10220 }
10221 }
10222 }
10223
10224 if (!pause)
10225 {
10226 /* Do the mark_window_display_accurate after all windows have
10227 been redisplayed because this call resets flags in buffers
10228 which are needed for proper redisplay. */
10229 for (i = 0; i < n; ++i)
10230 {
10231 struct frame *f = updated[i];
10232 mark_window_display_accurate (f->root_window, 1);
10233 if (frame_up_to_date_hook)
10234 frame_up_to_date_hook (f);
10235 }
10236 }
10237 }
10238 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10239 {
10240 Lisp_Object mini_window;
10241 struct frame *mini_frame;
10242
10243 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10244 /* Use list_of_error, not Qerror, so that
10245 we catch only errors and don't run the debugger. */
10246 internal_condition_case_1 (redisplay_window_1, selected_window,
10247 list_of_error,
10248 redisplay_window_error);
10249
10250 /* Compare desired and current matrices, perform output. */
10251
10252 update:
10253 /* If fonts changed, display again. */
10254 if (fonts_changed_p)
10255 goto retry;
10256
10257 /* Prevent various kinds of signals during display update.
10258 stdio is not robust about handling signals,
10259 which can cause an apparent I/O error. */
10260 if (interrupt_input)
10261 unrequest_sigio ();
10262 STOP_POLLING;
10263
10264 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10265 {
10266 if (hscroll_windows (selected_window))
10267 goto retry;
10268
10269 XWINDOW (selected_window)->must_be_updated_p = 1;
10270 pause = update_frame (sf, 0, 0);
10271 }
10272
10273 /* We may have called echo_area_display at the top of this
10274 function. If the echo area is on another frame, that may
10275 have put text on a frame other than the selected one, so the
10276 above call to update_frame would not have caught it. Catch
10277 it here. */
10278 mini_window = FRAME_MINIBUF_WINDOW (sf);
10279 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10280
10281 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10282 {
10283 XWINDOW (mini_window)->must_be_updated_p = 1;
10284 pause |= update_frame (mini_frame, 0, 0);
10285 if (!pause && hscroll_windows (mini_window))
10286 goto retry;
10287 }
10288 }
10289
10290 /* If display was paused because of pending input, make sure we do a
10291 thorough update the next time. */
10292 if (pause)
10293 {
10294 /* Prevent the optimization at the beginning of
10295 redisplay_internal that tries a single-line update of the
10296 line containing the cursor in the selected window. */
10297 CHARPOS (this_line_start_pos) = 0;
10298
10299 /* Let the overlay arrow be updated the next time. */
10300 update_overlay_arrows (0);
10301
10302 /* If we pause after scrolling, some rows in the current
10303 matrices of some windows are not valid. */
10304 if (!WINDOW_FULL_WIDTH_P (w)
10305 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10306 update_mode_lines = 1;
10307 }
10308 else
10309 {
10310 if (!consider_all_windows_p)
10311 {
10312 /* This has already been done above if
10313 consider_all_windows_p is set. */
10314 mark_window_display_accurate_1 (w, 1);
10315
10316 /* Say overlay arrows are up to date. */
10317 update_overlay_arrows (1);
10318
10319 if (frame_up_to_date_hook != 0)
10320 frame_up_to_date_hook (sf);
10321 }
10322
10323 update_mode_lines = 0;
10324 windows_or_buffers_changed = 0;
10325 cursor_type_changed = 0;
10326 }
10327
10328 /* Start SIGIO interrupts coming again. Having them off during the
10329 code above makes it less likely one will discard output, but not
10330 impossible, since there might be stuff in the system buffer here.
10331 But it is much hairier to try to do anything about that. */
10332 if (interrupt_input)
10333 request_sigio ();
10334 RESUME_POLLING;
10335
10336 /* If a frame has become visible which was not before, redisplay
10337 again, so that we display it. Expose events for such a frame
10338 (which it gets when becoming visible) don't call the parts of
10339 redisplay constructing glyphs, so simply exposing a frame won't
10340 display anything in this case. So, we have to display these
10341 frames here explicitly. */
10342 if (!pause)
10343 {
10344 Lisp_Object tail, frame;
10345 int new_count = 0;
10346
10347 FOR_EACH_FRAME (tail, frame)
10348 {
10349 int this_is_visible = 0;
10350
10351 if (XFRAME (frame)->visible)
10352 this_is_visible = 1;
10353 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10354 if (XFRAME (frame)->visible)
10355 this_is_visible = 1;
10356
10357 if (this_is_visible)
10358 new_count++;
10359 }
10360
10361 if (new_count != number_of_visible_frames)
10362 windows_or_buffers_changed++;
10363 }
10364
10365 /* Change frame size now if a change is pending. */
10366 do_pending_window_change (1);
10367
10368 /* If we just did a pending size change, or have additional
10369 visible frames, redisplay again. */
10370 if (windows_or_buffers_changed && !pause)
10371 goto retry;
10372
10373 end_of_redisplay:
10374 unbind_to (count, Qnil);
10375 RESUME_POLLING;
10376 }
10377
10378
10379 /* Redisplay, but leave alone any recent echo area message unless
10380 another message has been requested in its place.
10381
10382 This is useful in situations where you need to redisplay but no
10383 user action has occurred, making it inappropriate for the message
10384 area to be cleared. See tracking_off and
10385 wait_reading_process_output for examples of these situations.
10386
10387 FROM_WHERE is an integer saying from where this function was
10388 called. This is useful for debugging. */
10389
10390 void
10391 redisplay_preserve_echo_area (from_where)
10392 int from_where;
10393 {
10394 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10395
10396 if (!NILP (echo_area_buffer[1]))
10397 {
10398 /* We have a previously displayed message, but no current
10399 message. Redisplay the previous message. */
10400 display_last_displayed_message_p = 1;
10401 redisplay_internal (1);
10402 display_last_displayed_message_p = 0;
10403 }
10404 else
10405 redisplay_internal (1);
10406 }
10407
10408
10409 /* Function registered with record_unwind_protect in
10410 redisplay_internal. Reset redisplaying_p to the value it had
10411 before redisplay_internal was called, and clear
10412 prevent_freeing_realized_faces_p. It also selects the previously
10413 selected frame. */
10414
10415 static Lisp_Object
10416 unwind_redisplay (val)
10417 Lisp_Object val;
10418 {
10419 Lisp_Object old_redisplaying_p, old_frame;
10420
10421 old_redisplaying_p = XCAR (val);
10422 redisplaying_p = XFASTINT (old_redisplaying_p);
10423 old_frame = XCDR (val);
10424 if (! EQ (old_frame, selected_frame))
10425 select_frame_for_redisplay (old_frame);
10426 return Qnil;
10427 }
10428
10429
10430 /* Mark the display of window W as accurate or inaccurate. If
10431 ACCURATE_P is non-zero mark display of W as accurate. If
10432 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10433 redisplay_internal is called. */
10434
10435 static void
10436 mark_window_display_accurate_1 (w, accurate_p)
10437 struct window *w;
10438 int accurate_p;
10439 {
10440 if (BUFFERP (w->buffer))
10441 {
10442 struct buffer *b = XBUFFER (w->buffer);
10443
10444 w->last_modified
10445 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10446 w->last_overlay_modified
10447 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10448 w->last_had_star
10449 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10450
10451 if (accurate_p)
10452 {
10453 b->clip_changed = 0;
10454 b->prevent_redisplay_optimizations_p = 0;
10455
10456 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10457 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10458 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10459 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10460
10461 w->current_matrix->buffer = b;
10462 w->current_matrix->begv = BUF_BEGV (b);
10463 w->current_matrix->zv = BUF_ZV (b);
10464
10465 w->last_cursor = w->cursor;
10466 w->last_cursor_off_p = w->cursor_off_p;
10467
10468 if (w == XWINDOW (selected_window))
10469 w->last_point = make_number (BUF_PT (b));
10470 else
10471 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10472 }
10473 }
10474
10475 if (accurate_p)
10476 {
10477 w->window_end_valid = w->buffer;
10478 #if 0 /* This is incorrect with variable-height lines. */
10479 xassert (XINT (w->window_end_vpos)
10480 < (WINDOW_TOTAL_LINES (w)
10481 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10482 #endif
10483 w->update_mode_line = Qnil;
10484 }
10485 }
10486
10487
10488 /* Mark the display of windows in the window tree rooted at WINDOW as
10489 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10490 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10491 be redisplayed the next time redisplay_internal is called. */
10492
10493 void
10494 mark_window_display_accurate (window, accurate_p)
10495 Lisp_Object window;
10496 int accurate_p;
10497 {
10498 struct window *w;
10499
10500 for (; !NILP (window); window = w->next)
10501 {
10502 w = XWINDOW (window);
10503 mark_window_display_accurate_1 (w, accurate_p);
10504
10505 if (!NILP (w->vchild))
10506 mark_window_display_accurate (w->vchild, accurate_p);
10507 if (!NILP (w->hchild))
10508 mark_window_display_accurate (w->hchild, accurate_p);
10509 }
10510
10511 if (accurate_p)
10512 {
10513 update_overlay_arrows (1);
10514 }
10515 else
10516 {
10517 /* Force a thorough redisplay the next time by setting
10518 last_arrow_position and last_arrow_string to t, which is
10519 unequal to any useful value of Voverlay_arrow_... */
10520 update_overlay_arrows (-1);
10521 }
10522 }
10523
10524
10525 /* Return value in display table DP (Lisp_Char_Table *) for character
10526 C. Since a display table doesn't have any parent, we don't have to
10527 follow parent. Do not call this function directly but use the
10528 macro DISP_CHAR_VECTOR. */
10529
10530 Lisp_Object
10531 disp_char_vector (dp, c)
10532 struct Lisp_Char_Table *dp;
10533 int c;
10534 {
10535 int code[4], i;
10536 Lisp_Object val;
10537
10538 if (SINGLE_BYTE_CHAR_P (c))
10539 return (dp->contents[c]);
10540
10541 SPLIT_CHAR (c, code[0], code[1], code[2]);
10542 if (code[1] < 32)
10543 code[1] = -1;
10544 else if (code[2] < 32)
10545 code[2] = -1;
10546
10547 /* Here, the possible range of code[0] (== charset ID) is
10548 128..max_charset. Since the top level char table contains data
10549 for multibyte characters after 256th element, we must increment
10550 code[0] by 128 to get a correct index. */
10551 code[0] += 128;
10552 code[3] = -1; /* anchor */
10553
10554 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10555 {
10556 val = dp->contents[code[i]];
10557 if (!SUB_CHAR_TABLE_P (val))
10558 return (NILP (val) ? dp->defalt : val);
10559 }
10560
10561 /* Here, val is a sub char table. We return the default value of
10562 it. */
10563 return (dp->defalt);
10564 }
10565
10566
10567 \f
10568 /***********************************************************************
10569 Window Redisplay
10570 ***********************************************************************/
10571
10572 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10573
10574 static void
10575 redisplay_windows (window)
10576 Lisp_Object window;
10577 {
10578 while (!NILP (window))
10579 {
10580 struct window *w = XWINDOW (window);
10581
10582 if (!NILP (w->hchild))
10583 redisplay_windows (w->hchild);
10584 else if (!NILP (w->vchild))
10585 redisplay_windows (w->vchild);
10586 else
10587 {
10588 displayed_buffer = XBUFFER (w->buffer);
10589 /* Use list_of_error, not Qerror, so that
10590 we catch only errors and don't run the debugger. */
10591 internal_condition_case_1 (redisplay_window_0, window,
10592 list_of_error,
10593 redisplay_window_error);
10594 }
10595
10596 window = w->next;
10597 }
10598 }
10599
10600 static Lisp_Object
10601 redisplay_window_error ()
10602 {
10603 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10604 return Qnil;
10605 }
10606
10607 static Lisp_Object
10608 redisplay_window_0 (window)
10609 Lisp_Object window;
10610 {
10611 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10612 redisplay_window (window, 0);
10613 return Qnil;
10614 }
10615
10616 static Lisp_Object
10617 redisplay_window_1 (window)
10618 Lisp_Object window;
10619 {
10620 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10621 redisplay_window (window, 1);
10622 return Qnil;
10623 }
10624 \f
10625
10626 /* Increment GLYPH until it reaches END or CONDITION fails while
10627 adding (GLYPH)->pixel_width to X. */
10628
10629 #define SKIP_GLYPHS(glyph, end, x, condition) \
10630 do \
10631 { \
10632 (x) += (glyph)->pixel_width; \
10633 ++(glyph); \
10634 } \
10635 while ((glyph) < (end) && (condition))
10636
10637
10638 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10639 DELTA is the number of bytes by which positions recorded in ROW
10640 differ from current buffer positions. */
10641
10642 void
10643 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10644 struct window *w;
10645 struct glyph_row *row;
10646 struct glyph_matrix *matrix;
10647 int delta, delta_bytes, dy, dvpos;
10648 {
10649 struct glyph *glyph = row->glyphs[TEXT_AREA];
10650 struct glyph *end = glyph + row->used[TEXT_AREA];
10651 struct glyph *cursor = NULL;
10652 /* The first glyph that starts a sequence of glyphs from string. */
10653 struct glyph *string_start;
10654 /* The X coordinate of string_start. */
10655 int string_start_x;
10656 /* The last known character position. */
10657 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10658 /* The last known character position before string_start. */
10659 int string_before_pos;
10660 int x = row->x;
10661 int cursor_x = x;
10662 int cursor_from_overlay_pos = 0;
10663 int pt_old = PT - delta;
10664
10665 /* Skip over glyphs not having an object at the start of the row.
10666 These are special glyphs like truncation marks on terminal
10667 frames. */
10668 if (row->displays_text_p)
10669 while (glyph < end
10670 && INTEGERP (glyph->object)
10671 && glyph->charpos < 0)
10672 {
10673 x += glyph->pixel_width;
10674 ++glyph;
10675 }
10676
10677 string_start = NULL;
10678 while (glyph < end
10679 && !INTEGERP (glyph->object)
10680 && (!BUFFERP (glyph->object)
10681 || (last_pos = glyph->charpos) < pt_old))
10682 {
10683 if (! STRINGP (glyph->object))
10684 {
10685 string_start = NULL;
10686 x += glyph->pixel_width;
10687 ++glyph;
10688 if (cursor_from_overlay_pos
10689 && last_pos > cursor_from_overlay_pos)
10690 {
10691 cursor_from_overlay_pos = 0;
10692 cursor = 0;
10693 }
10694 }
10695 else
10696 {
10697 string_before_pos = last_pos;
10698 string_start = glyph;
10699 string_start_x = x;
10700 /* Skip all glyphs from string. */
10701 do
10702 {
10703 int pos;
10704 if ((cursor == NULL || glyph > cursor)
10705 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10706 Qcursor, (glyph)->object))
10707 && (pos = string_buffer_position (w, glyph->object,
10708 string_before_pos),
10709 (pos == 0 /* From overlay */
10710 || pos == pt_old)))
10711 {
10712 /* Estimate overlay buffer position from the buffer
10713 positions of the glyphs before and after the overlay.
10714 Add 1 to last_pos so that if point corresponds to the
10715 glyph right after the overlay, we still use a 'cursor'
10716 property found in that overlay. */
10717 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10718 cursor = glyph;
10719 cursor_x = x;
10720 }
10721 x += glyph->pixel_width;
10722 ++glyph;
10723 }
10724 while (glyph < end && STRINGP (glyph->object));
10725 }
10726 }
10727
10728 if (cursor != NULL)
10729 {
10730 glyph = cursor;
10731 x = cursor_x;
10732 }
10733 else if (string_start
10734 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10735 {
10736 /* We may have skipped over point because the previous glyphs
10737 are from string. As there's no easy way to know the
10738 character position of the current glyph, find the correct
10739 glyph on point by scanning from string_start again. */
10740 Lisp_Object limit;
10741 Lisp_Object string;
10742 int pos;
10743
10744 limit = make_number (pt_old + 1);
10745 end = glyph;
10746 glyph = string_start;
10747 x = string_start_x;
10748 string = glyph->object;
10749 pos = string_buffer_position (w, string, string_before_pos);
10750 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10751 because we always put cursor after overlay strings. */
10752 while (pos == 0 && glyph < end)
10753 {
10754 string = glyph->object;
10755 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10756 if (glyph < end)
10757 pos = string_buffer_position (w, glyph->object, string_before_pos);
10758 }
10759
10760 while (glyph < end)
10761 {
10762 pos = XINT (Fnext_single_char_property_change
10763 (make_number (pos), Qdisplay, Qnil, limit));
10764 if (pos > pt_old)
10765 break;
10766 /* Skip glyphs from the same string. */
10767 string = glyph->object;
10768 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10769 /* Skip glyphs from an overlay. */
10770 while (glyph < end
10771 && ! string_buffer_position (w, glyph->object, pos))
10772 {
10773 string = glyph->object;
10774 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10775 }
10776 }
10777 }
10778
10779 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10780 w->cursor.x = x;
10781 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10782 w->cursor.y = row->y + dy;
10783
10784 if (w == XWINDOW (selected_window))
10785 {
10786 if (!row->continued_p
10787 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10788 && row->x == 0)
10789 {
10790 this_line_buffer = XBUFFER (w->buffer);
10791
10792 CHARPOS (this_line_start_pos)
10793 = MATRIX_ROW_START_CHARPOS (row) + delta;
10794 BYTEPOS (this_line_start_pos)
10795 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10796
10797 CHARPOS (this_line_end_pos)
10798 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10799 BYTEPOS (this_line_end_pos)
10800 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10801
10802 this_line_y = w->cursor.y;
10803 this_line_pixel_height = row->height;
10804 this_line_vpos = w->cursor.vpos;
10805 this_line_start_x = row->x;
10806 }
10807 else
10808 CHARPOS (this_line_start_pos) = 0;
10809 }
10810 }
10811
10812
10813 /* Run window scroll functions, if any, for WINDOW with new window
10814 start STARTP. Sets the window start of WINDOW to that position.
10815
10816 We assume that the window's buffer is really current. */
10817
10818 static INLINE struct text_pos
10819 run_window_scroll_functions (window, startp)
10820 Lisp_Object window;
10821 struct text_pos startp;
10822 {
10823 struct window *w = XWINDOW (window);
10824 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10825
10826 if (current_buffer != XBUFFER (w->buffer))
10827 abort ();
10828
10829 if (!NILP (Vwindow_scroll_functions))
10830 {
10831 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10832 make_number (CHARPOS (startp)));
10833 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10834 /* In case the hook functions switch buffers. */
10835 if (current_buffer != XBUFFER (w->buffer))
10836 set_buffer_internal_1 (XBUFFER (w->buffer));
10837 }
10838
10839 return startp;
10840 }
10841
10842
10843 /* Make sure the line containing the cursor is fully visible.
10844 A value of 1 means there is nothing to be done.
10845 (Either the line is fully visible, or it cannot be made so,
10846 or we cannot tell.)
10847
10848 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10849 is higher than window.
10850
10851 A value of 0 means the caller should do scrolling
10852 as if point had gone off the screen. */
10853
10854 static int
10855 make_cursor_line_fully_visible (w, force_p)
10856 struct window *w;
10857 int force_p;
10858 {
10859 struct glyph_matrix *matrix;
10860 struct glyph_row *row;
10861 int window_height;
10862
10863 /* It's not always possible to find the cursor, e.g, when a window
10864 is full of overlay strings. Don't do anything in that case. */
10865 if (w->cursor.vpos < 0)
10866 return 1;
10867
10868 matrix = w->desired_matrix;
10869 row = MATRIX_ROW (matrix, w->cursor.vpos);
10870
10871 /* If the cursor row is not partially visible, there's nothing to do. */
10872 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10873 return 1;
10874
10875 /* If the row the cursor is in is taller than the window's height,
10876 it's not clear what to do, so do nothing. */
10877 window_height = window_box_height (w);
10878 if (row->height >= window_height)
10879 {
10880 if (!force_p || w->vscroll)
10881 return 1;
10882 }
10883 return 0;
10884
10885 #if 0
10886 /* This code used to try to scroll the window just enough to make
10887 the line visible. It returned 0 to say that the caller should
10888 allocate larger glyph matrices. */
10889
10890 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10891 {
10892 int dy = row->height - row->visible_height;
10893 w->vscroll = 0;
10894 w->cursor.y += dy;
10895 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10896 }
10897 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10898 {
10899 int dy = - (row->height - row->visible_height);
10900 w->vscroll = dy;
10901 w->cursor.y += dy;
10902 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10903 }
10904
10905 /* When we change the cursor y-position of the selected window,
10906 change this_line_y as well so that the display optimization for
10907 the cursor line of the selected window in redisplay_internal uses
10908 the correct y-position. */
10909 if (w == XWINDOW (selected_window))
10910 this_line_y = w->cursor.y;
10911
10912 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10913 redisplay with larger matrices. */
10914 if (matrix->nrows < required_matrix_height (w))
10915 {
10916 fonts_changed_p = 1;
10917 return 0;
10918 }
10919
10920 return 1;
10921 #endif /* 0 */
10922 }
10923
10924
10925 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10926 non-zero means only WINDOW is redisplayed in redisplay_internal.
10927 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10928 in redisplay_window to bring a partially visible line into view in
10929 the case that only the cursor has moved.
10930
10931 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10932 last screen line's vertical height extends past the end of the screen.
10933
10934 Value is
10935
10936 1 if scrolling succeeded
10937
10938 0 if scrolling didn't find point.
10939
10940 -1 if new fonts have been loaded so that we must interrupt
10941 redisplay, adjust glyph matrices, and try again. */
10942
10943 enum
10944 {
10945 SCROLLING_SUCCESS,
10946 SCROLLING_FAILED,
10947 SCROLLING_NEED_LARGER_MATRICES
10948 };
10949
10950 static int
10951 try_scrolling (window, just_this_one_p, scroll_conservatively,
10952 scroll_step, temp_scroll_step, last_line_misfit)
10953 Lisp_Object window;
10954 int just_this_one_p;
10955 EMACS_INT scroll_conservatively, scroll_step;
10956 int temp_scroll_step;
10957 int last_line_misfit;
10958 {
10959 struct window *w = XWINDOW (window);
10960 struct frame *f = XFRAME (w->frame);
10961 struct text_pos scroll_margin_pos;
10962 struct text_pos pos;
10963 struct text_pos startp;
10964 struct it it;
10965 Lisp_Object window_end;
10966 int this_scroll_margin;
10967 int dy = 0;
10968 int scroll_max;
10969 int rc;
10970 int amount_to_scroll = 0;
10971 Lisp_Object aggressive;
10972 int height;
10973 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10974
10975 #if GLYPH_DEBUG
10976 debug_method_add (w, "try_scrolling");
10977 #endif
10978
10979 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10980
10981 /* Compute scroll margin height in pixels. We scroll when point is
10982 within this distance from the top or bottom of the window. */
10983 if (scroll_margin > 0)
10984 {
10985 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10986 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10987 }
10988 else
10989 this_scroll_margin = 0;
10990
10991 /* Force scroll_conservatively to have a reasonable value so it doesn't
10992 cause an overflow while computing how much to scroll. */
10993 if (scroll_conservatively)
10994 scroll_conservatively = min (scroll_conservatively,
10995 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
10996
10997 /* Compute how much we should try to scroll maximally to bring point
10998 into view. */
10999 if (scroll_step || scroll_conservatively || temp_scroll_step)
11000 scroll_max = max (scroll_step,
11001 max (scroll_conservatively, temp_scroll_step));
11002 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11003 || NUMBERP (current_buffer->scroll_up_aggressively))
11004 /* We're trying to scroll because of aggressive scrolling
11005 but no scroll_step is set. Choose an arbitrary one. Maybe
11006 there should be a variable for this. */
11007 scroll_max = 10;
11008 else
11009 scroll_max = 0;
11010 scroll_max *= FRAME_LINE_HEIGHT (f);
11011
11012 /* Decide whether we have to scroll down. Start at the window end
11013 and move this_scroll_margin up to find the position of the scroll
11014 margin. */
11015 window_end = Fwindow_end (window, Qt);
11016
11017 too_near_end:
11018
11019 CHARPOS (scroll_margin_pos) = XINT (window_end);
11020 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11021
11022 if (this_scroll_margin || extra_scroll_margin_lines)
11023 {
11024 start_display (&it, w, scroll_margin_pos);
11025 if (this_scroll_margin)
11026 move_it_vertically (&it, - this_scroll_margin);
11027 if (extra_scroll_margin_lines)
11028 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11029 scroll_margin_pos = it.current.pos;
11030 }
11031
11032 if (PT >= CHARPOS (scroll_margin_pos))
11033 {
11034 int y0;
11035
11036 /* Point is in the scroll margin at the bottom of the window, or
11037 below. Compute a new window start that makes point visible. */
11038
11039 /* Compute the distance from the scroll margin to PT.
11040 Give up if the distance is greater than scroll_max. */
11041 start_display (&it, w, scroll_margin_pos);
11042 y0 = it.current_y;
11043 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11044 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11045
11046 /* To make point visible, we have to move the window start
11047 down so that the line the cursor is in is visible, which
11048 means we have to add in the height of the cursor line. */
11049 dy = line_bottom_y (&it) - y0;
11050
11051 if (dy > scroll_max)
11052 return SCROLLING_FAILED;
11053
11054 /* Move the window start down. If scrolling conservatively,
11055 move it just enough down to make point visible. If
11056 scroll_step is set, move it down by scroll_step. */
11057 start_display (&it, w, startp);
11058
11059 if (scroll_conservatively)
11060 /* Set AMOUNT_TO_SCROLL to at least one line,
11061 and at most scroll_conservatively lines. */
11062 amount_to_scroll
11063 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11064 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11065 else if (scroll_step || temp_scroll_step)
11066 amount_to_scroll = scroll_max;
11067 else
11068 {
11069 aggressive = current_buffer->scroll_up_aggressively;
11070 height = WINDOW_BOX_TEXT_HEIGHT (w);
11071 if (NUMBERP (aggressive))
11072 {
11073 double float_amount = XFLOATINT (aggressive) * height;
11074 amount_to_scroll = float_amount;
11075 if (amount_to_scroll == 0 && float_amount > 0)
11076 amount_to_scroll = 1;
11077 }
11078 }
11079
11080 if (amount_to_scroll <= 0)
11081 return SCROLLING_FAILED;
11082
11083 /* If moving by amount_to_scroll leaves STARTP unchanged,
11084 move it down one screen line. */
11085
11086 move_it_vertically (&it, amount_to_scroll);
11087 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11088 move_it_by_lines (&it, 1, 1);
11089 startp = it.current.pos;
11090 }
11091 else
11092 {
11093 /* See if point is inside the scroll margin at the top of the
11094 window. */
11095 scroll_margin_pos = startp;
11096 if (this_scroll_margin)
11097 {
11098 start_display (&it, w, startp);
11099 move_it_vertically (&it, this_scroll_margin);
11100 scroll_margin_pos = it.current.pos;
11101 }
11102
11103 if (PT < CHARPOS (scroll_margin_pos))
11104 {
11105 /* Point is in the scroll margin at the top of the window or
11106 above what is displayed in the window. */
11107 int y0;
11108
11109 /* Compute the vertical distance from PT to the scroll
11110 margin position. Give up if distance is greater than
11111 scroll_max. */
11112 SET_TEXT_POS (pos, PT, PT_BYTE);
11113 start_display (&it, w, pos);
11114 y0 = it.current_y;
11115 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11116 it.last_visible_y, -1,
11117 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11118 dy = it.current_y - y0;
11119 if (dy > scroll_max)
11120 return SCROLLING_FAILED;
11121
11122 /* Compute new window start. */
11123 start_display (&it, w, startp);
11124
11125 if (scroll_conservatively)
11126 amount_to_scroll
11127 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11128 else if (scroll_step || temp_scroll_step)
11129 amount_to_scroll = scroll_max;
11130 else
11131 {
11132 aggressive = current_buffer->scroll_down_aggressively;
11133 height = WINDOW_BOX_TEXT_HEIGHT (w);
11134 if (NUMBERP (aggressive))
11135 {
11136 double float_amount = XFLOATINT (aggressive) * height;
11137 amount_to_scroll = float_amount;
11138 if (amount_to_scroll == 0 && float_amount > 0)
11139 amount_to_scroll = 1;
11140 }
11141 }
11142
11143 if (amount_to_scroll <= 0)
11144 return SCROLLING_FAILED;
11145
11146 move_it_vertically (&it, - amount_to_scroll);
11147 startp = it.current.pos;
11148 }
11149 }
11150
11151 /* Run window scroll functions. */
11152 startp = run_window_scroll_functions (window, startp);
11153
11154 /* Display the window. Give up if new fonts are loaded, or if point
11155 doesn't appear. */
11156 if (!try_window (window, startp))
11157 rc = SCROLLING_NEED_LARGER_MATRICES;
11158 else if (w->cursor.vpos < 0)
11159 {
11160 clear_glyph_matrix (w->desired_matrix);
11161 rc = SCROLLING_FAILED;
11162 }
11163 else
11164 {
11165 /* Maybe forget recorded base line for line number display. */
11166 if (!just_this_one_p
11167 || current_buffer->clip_changed
11168 || BEG_UNCHANGED < CHARPOS (startp))
11169 w->base_line_number = Qnil;
11170
11171 /* If cursor ends up on a partially visible line,
11172 treat that as being off the bottom of the screen. */
11173 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11174 {
11175 clear_glyph_matrix (w->desired_matrix);
11176 ++extra_scroll_margin_lines;
11177 goto too_near_end;
11178 }
11179 rc = SCROLLING_SUCCESS;
11180 }
11181
11182 return rc;
11183 }
11184
11185
11186 /* Compute a suitable window start for window W if display of W starts
11187 on a continuation line. Value is non-zero if a new window start
11188 was computed.
11189
11190 The new window start will be computed, based on W's width, starting
11191 from the start of the continued line. It is the start of the
11192 screen line with the minimum distance from the old start W->start. */
11193
11194 static int
11195 compute_window_start_on_continuation_line (w)
11196 struct window *w;
11197 {
11198 struct text_pos pos, start_pos;
11199 int window_start_changed_p = 0;
11200
11201 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11202
11203 /* If window start is on a continuation line... Window start may be
11204 < BEGV in case there's invisible text at the start of the
11205 buffer (M-x rmail, for example). */
11206 if (CHARPOS (start_pos) > BEGV
11207 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11208 {
11209 struct it it;
11210 struct glyph_row *row;
11211
11212 /* Handle the case that the window start is out of range. */
11213 if (CHARPOS (start_pos) < BEGV)
11214 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11215 else if (CHARPOS (start_pos) > ZV)
11216 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11217
11218 /* Find the start of the continued line. This should be fast
11219 because scan_buffer is fast (newline cache). */
11220 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11221 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11222 row, DEFAULT_FACE_ID);
11223 reseat_at_previous_visible_line_start (&it);
11224
11225 /* If the line start is "too far" away from the window start,
11226 say it takes too much time to compute a new window start. */
11227 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11228 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11229 {
11230 int min_distance, distance;
11231
11232 /* Move forward by display lines to find the new window
11233 start. If window width was enlarged, the new start can
11234 be expected to be > the old start. If window width was
11235 decreased, the new window start will be < the old start.
11236 So, we're looking for the display line start with the
11237 minimum distance from the old window start. */
11238 pos = it.current.pos;
11239 min_distance = INFINITY;
11240 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11241 distance < min_distance)
11242 {
11243 min_distance = distance;
11244 pos = it.current.pos;
11245 move_it_by_lines (&it, 1, 0);
11246 }
11247
11248 /* Set the window start there. */
11249 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11250 window_start_changed_p = 1;
11251 }
11252 }
11253
11254 return window_start_changed_p;
11255 }
11256
11257
11258 /* Try cursor movement in case text has not changed in window WINDOW,
11259 with window start STARTP. Value is
11260
11261 CURSOR_MOVEMENT_SUCCESS if successful
11262
11263 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11264
11265 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11266 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11267 we want to scroll as if scroll-step were set to 1. See the code.
11268
11269 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11270 which case we have to abort this redisplay, and adjust matrices
11271 first. */
11272
11273 enum
11274 {
11275 CURSOR_MOVEMENT_SUCCESS,
11276 CURSOR_MOVEMENT_CANNOT_BE_USED,
11277 CURSOR_MOVEMENT_MUST_SCROLL,
11278 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11279 };
11280
11281 static int
11282 try_cursor_movement (window, startp, scroll_step)
11283 Lisp_Object window;
11284 struct text_pos startp;
11285 int *scroll_step;
11286 {
11287 struct window *w = XWINDOW (window);
11288 struct frame *f = XFRAME (w->frame);
11289 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11290
11291 #if GLYPH_DEBUG
11292 if (inhibit_try_cursor_movement)
11293 return rc;
11294 #endif
11295
11296 /* Handle case where text has not changed, only point, and it has
11297 not moved off the frame. */
11298 if (/* Point may be in this window. */
11299 PT >= CHARPOS (startp)
11300 /* Selective display hasn't changed. */
11301 && !current_buffer->clip_changed
11302 /* Function force-mode-line-update is used to force a thorough
11303 redisplay. It sets either windows_or_buffers_changed or
11304 update_mode_lines. So don't take a shortcut here for these
11305 cases. */
11306 && !update_mode_lines
11307 && !windows_or_buffers_changed
11308 && !cursor_type_changed
11309 /* Can't use this case if highlighting a region. When a
11310 region exists, cursor movement has to do more than just
11311 set the cursor. */
11312 && !(!NILP (Vtransient_mark_mode)
11313 && !NILP (current_buffer->mark_active))
11314 && NILP (w->region_showing)
11315 && NILP (Vshow_trailing_whitespace)
11316 /* Right after splitting windows, last_point may be nil. */
11317 && INTEGERP (w->last_point)
11318 /* This code is not used for mini-buffer for the sake of the case
11319 of redisplaying to replace an echo area message; since in
11320 that case the mini-buffer contents per se are usually
11321 unchanged. This code is of no real use in the mini-buffer
11322 since the handling of this_line_start_pos, etc., in redisplay
11323 handles the same cases. */
11324 && !EQ (window, minibuf_window)
11325 /* When splitting windows or for new windows, it happens that
11326 redisplay is called with a nil window_end_vpos or one being
11327 larger than the window. This should really be fixed in
11328 window.c. I don't have this on my list, now, so we do
11329 approximately the same as the old redisplay code. --gerd. */
11330 && INTEGERP (w->window_end_vpos)
11331 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11332 && (FRAME_WINDOW_P (f)
11333 || !overlay_arrow_in_current_buffer_p ()))
11334 {
11335 int this_scroll_margin, top_scroll_margin;
11336 struct glyph_row *row = NULL;
11337
11338 #if GLYPH_DEBUG
11339 debug_method_add (w, "cursor movement");
11340 #endif
11341
11342 /* Scroll if point within this distance from the top or bottom
11343 of the window. This is a pixel value. */
11344 this_scroll_margin = max (0, scroll_margin);
11345 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11346 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11347
11348 top_scroll_margin = this_scroll_margin;
11349 if (WINDOW_WANTS_HEADER_LINE_P (w))
11350 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11351
11352 /* Start with the row the cursor was displayed during the last
11353 not paused redisplay. Give up if that row is not valid. */
11354 if (w->last_cursor.vpos < 0
11355 || w->last_cursor.vpos >= w->current_matrix->nrows)
11356 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11357 else
11358 {
11359 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11360 if (row->mode_line_p)
11361 ++row;
11362 if (!row->enabled_p)
11363 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11364 }
11365
11366 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11367 {
11368 int scroll_p = 0;
11369 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11370
11371 if (PT > XFASTINT (w->last_point))
11372 {
11373 /* Point has moved forward. */
11374 while (MATRIX_ROW_END_CHARPOS (row) < PT
11375 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11376 {
11377 xassert (row->enabled_p);
11378 ++row;
11379 }
11380
11381 /* The end position of a row equals the start position
11382 of the next row. If PT is there, we would rather
11383 display it in the next line. */
11384 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11385 && MATRIX_ROW_END_CHARPOS (row) == PT
11386 && !cursor_row_p (w, row))
11387 ++row;
11388
11389 /* If within the scroll margin, scroll. Note that
11390 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11391 the next line would be drawn, and that
11392 this_scroll_margin can be zero. */
11393 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11394 || PT > MATRIX_ROW_END_CHARPOS (row)
11395 /* Line is completely visible last line in window
11396 and PT is to be set in the next line. */
11397 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11398 && PT == MATRIX_ROW_END_CHARPOS (row)
11399 && !row->ends_at_zv_p
11400 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11401 scroll_p = 1;
11402 }
11403 else if (PT < XFASTINT (w->last_point))
11404 {
11405 /* Cursor has to be moved backward. Note that PT >=
11406 CHARPOS (startp) because of the outer if-statement. */
11407 while (!row->mode_line_p
11408 && (MATRIX_ROW_START_CHARPOS (row) > PT
11409 || (MATRIX_ROW_START_CHARPOS (row) == PT
11410 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11411 && (row->y > top_scroll_margin
11412 || CHARPOS (startp) == BEGV))
11413 {
11414 xassert (row->enabled_p);
11415 --row;
11416 }
11417
11418 /* Consider the following case: Window starts at BEGV,
11419 there is invisible, intangible text at BEGV, so that
11420 display starts at some point START > BEGV. It can
11421 happen that we are called with PT somewhere between
11422 BEGV and START. Try to handle that case. */
11423 if (row < w->current_matrix->rows
11424 || row->mode_line_p)
11425 {
11426 row = w->current_matrix->rows;
11427 if (row->mode_line_p)
11428 ++row;
11429 }
11430
11431 /* Due to newlines in overlay strings, we may have to
11432 skip forward over overlay strings. */
11433 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11434 && MATRIX_ROW_END_CHARPOS (row) == PT
11435 && !cursor_row_p (w, row))
11436 ++row;
11437
11438 /* If within the scroll margin, scroll. */
11439 if (row->y < top_scroll_margin
11440 && CHARPOS (startp) != BEGV)
11441 scroll_p = 1;
11442 }
11443
11444 if (PT < MATRIX_ROW_START_CHARPOS (row)
11445 || PT > MATRIX_ROW_END_CHARPOS (row))
11446 {
11447 /* if PT is not in the glyph row, give up. */
11448 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11449 }
11450 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11451 {
11452 if (PT == MATRIX_ROW_END_CHARPOS (row)
11453 && !row->ends_at_zv_p
11454 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11455 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11456 else if (row->height > window_box_height (w))
11457 {
11458 /* If we end up in a partially visible line, let's
11459 make it fully visible, except when it's taller
11460 than the window, in which case we can't do much
11461 about it. */
11462 *scroll_step = 1;
11463 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11464 }
11465 else
11466 {
11467 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11468 if (!make_cursor_line_fully_visible (w, 0))
11469 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11470 else
11471 rc = CURSOR_MOVEMENT_SUCCESS;
11472 }
11473 }
11474 else if (scroll_p)
11475 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11476 else
11477 {
11478 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11479 rc = CURSOR_MOVEMENT_SUCCESS;
11480 }
11481 }
11482 }
11483
11484 return rc;
11485 }
11486
11487 void
11488 set_vertical_scroll_bar (w)
11489 struct window *w;
11490 {
11491 int start, end, whole;
11492
11493 /* Calculate the start and end positions for the current window.
11494 At some point, it would be nice to choose between scrollbars
11495 which reflect the whole buffer size, with special markers
11496 indicating narrowing, and scrollbars which reflect only the
11497 visible region.
11498
11499 Note that mini-buffers sometimes aren't displaying any text. */
11500 if (!MINI_WINDOW_P (w)
11501 || (w == XWINDOW (minibuf_window)
11502 && NILP (echo_area_buffer[0])))
11503 {
11504 struct buffer *buf = XBUFFER (w->buffer);
11505 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11506 start = marker_position (w->start) - BUF_BEGV (buf);
11507 /* I don't think this is guaranteed to be right. For the
11508 moment, we'll pretend it is. */
11509 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11510
11511 if (end < start)
11512 end = start;
11513 if (whole < (end - start))
11514 whole = end - start;
11515 }
11516 else
11517 start = end = whole = 0;
11518
11519 /* Indicate what this scroll bar ought to be displaying now. */
11520 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11521 }
11522
11523
11524 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11525 selected_window is redisplayed.
11526
11527 We can return without actually redisplaying the window if
11528 fonts_changed_p is nonzero. In that case, redisplay_internal will
11529 retry. */
11530
11531 static void
11532 redisplay_window (window, just_this_one_p)
11533 Lisp_Object window;
11534 int just_this_one_p;
11535 {
11536 struct window *w = XWINDOW (window);
11537 struct frame *f = XFRAME (w->frame);
11538 struct buffer *buffer = XBUFFER (w->buffer);
11539 struct buffer *old = current_buffer;
11540 struct text_pos lpoint, opoint, startp;
11541 int update_mode_line;
11542 int tem;
11543 struct it it;
11544 /* Record it now because it's overwritten. */
11545 int current_matrix_up_to_date_p = 0;
11546 int used_current_matrix_p = 0;
11547 /* This is less strict than current_matrix_up_to_date_p.
11548 It indictes that the buffer contents and narrowing are unchanged. */
11549 int buffer_unchanged_p = 0;
11550 int temp_scroll_step = 0;
11551 int count = SPECPDL_INDEX ();
11552 int rc;
11553 int centering_position;
11554 int last_line_misfit = 0;
11555
11556 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11557 opoint = lpoint;
11558
11559 /* W must be a leaf window here. */
11560 xassert (!NILP (w->buffer));
11561 #if GLYPH_DEBUG
11562 *w->desired_matrix->method = 0;
11563 #endif
11564
11565 specbind (Qinhibit_point_motion_hooks, Qt);
11566
11567 reconsider_clip_changes (w, buffer);
11568
11569 /* Has the mode line to be updated? */
11570 update_mode_line = (!NILP (w->update_mode_line)
11571 || update_mode_lines
11572 || buffer->clip_changed
11573 || buffer->prevent_redisplay_optimizations_p);
11574
11575 if (MINI_WINDOW_P (w))
11576 {
11577 if (w == XWINDOW (echo_area_window)
11578 && !NILP (echo_area_buffer[0]))
11579 {
11580 if (update_mode_line)
11581 /* We may have to update a tty frame's menu bar or a
11582 tool-bar. Example `M-x C-h C-h C-g'. */
11583 goto finish_menu_bars;
11584 else
11585 /* We've already displayed the echo area glyphs in this window. */
11586 goto finish_scroll_bars;
11587 }
11588 else if ((w != XWINDOW (minibuf_window)
11589 || minibuf_level == 0)
11590 /* When buffer is nonempty, redisplay window normally. */
11591 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11592 /* Quail displays non-mini buffers in minibuffer window.
11593 In that case, redisplay the window normally. */
11594 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11595 {
11596 /* W is a mini-buffer window, but it's not active, so clear
11597 it. */
11598 int yb = window_text_bottom_y (w);
11599 struct glyph_row *row;
11600 int y;
11601
11602 for (y = 0, row = w->desired_matrix->rows;
11603 y < yb;
11604 y += row->height, ++row)
11605 blank_row (w, row, y);
11606 goto finish_scroll_bars;
11607 }
11608
11609 clear_glyph_matrix (w->desired_matrix);
11610 }
11611
11612 /* Otherwise set up data on this window; select its buffer and point
11613 value. */
11614 /* Really select the buffer, for the sake of buffer-local
11615 variables. */
11616 set_buffer_internal_1 (XBUFFER (w->buffer));
11617 SET_TEXT_POS (opoint, PT, PT_BYTE);
11618
11619 current_matrix_up_to_date_p
11620 = (!NILP (w->window_end_valid)
11621 && !current_buffer->clip_changed
11622 && !current_buffer->prevent_redisplay_optimizations_p
11623 && XFASTINT (w->last_modified) >= MODIFF
11624 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11625
11626 buffer_unchanged_p
11627 = (!NILP (w->window_end_valid)
11628 && !current_buffer->clip_changed
11629 && XFASTINT (w->last_modified) >= MODIFF
11630 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11631
11632 /* When windows_or_buffers_changed is non-zero, we can't rely on
11633 the window end being valid, so set it to nil there. */
11634 if (windows_or_buffers_changed)
11635 {
11636 /* If window starts on a continuation line, maybe adjust the
11637 window start in case the window's width changed. */
11638 if (XMARKER (w->start)->buffer == current_buffer)
11639 compute_window_start_on_continuation_line (w);
11640
11641 w->window_end_valid = Qnil;
11642 }
11643
11644 /* Some sanity checks. */
11645 CHECK_WINDOW_END (w);
11646 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11647 abort ();
11648 if (BYTEPOS (opoint) < CHARPOS (opoint))
11649 abort ();
11650
11651 /* If %c is in mode line, update it if needed. */
11652 if (!NILP (w->column_number_displayed)
11653 /* This alternative quickly identifies a common case
11654 where no change is needed. */
11655 && !(PT == XFASTINT (w->last_point)
11656 && XFASTINT (w->last_modified) >= MODIFF
11657 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11658 && (XFASTINT (w->column_number_displayed)
11659 != (int) current_column ())) /* iftc */
11660 update_mode_line = 1;
11661
11662 /* Count number of windows showing the selected buffer. An indirect
11663 buffer counts as its base buffer. */
11664 if (!just_this_one_p)
11665 {
11666 struct buffer *current_base, *window_base;
11667 current_base = current_buffer;
11668 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11669 if (current_base->base_buffer)
11670 current_base = current_base->base_buffer;
11671 if (window_base->base_buffer)
11672 window_base = window_base->base_buffer;
11673 if (current_base == window_base)
11674 buffer_shared++;
11675 }
11676
11677 /* Point refers normally to the selected window. For any other
11678 window, set up appropriate value. */
11679 if (!EQ (window, selected_window))
11680 {
11681 int new_pt = XMARKER (w->pointm)->charpos;
11682 int new_pt_byte = marker_byte_position (w->pointm);
11683 if (new_pt < BEGV)
11684 {
11685 new_pt = BEGV;
11686 new_pt_byte = BEGV_BYTE;
11687 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11688 }
11689 else if (new_pt > (ZV - 1))
11690 {
11691 new_pt = ZV;
11692 new_pt_byte = ZV_BYTE;
11693 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11694 }
11695
11696 /* We don't use SET_PT so that the point-motion hooks don't run. */
11697 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11698 }
11699
11700 /* If any of the character widths specified in the display table
11701 have changed, invalidate the width run cache. It's true that
11702 this may be a bit late to catch such changes, but the rest of
11703 redisplay goes (non-fatally) haywire when the display table is
11704 changed, so why should we worry about doing any better? */
11705 if (current_buffer->width_run_cache)
11706 {
11707 struct Lisp_Char_Table *disptab = buffer_display_table ();
11708
11709 if (! disptab_matches_widthtab (disptab,
11710 XVECTOR (current_buffer->width_table)))
11711 {
11712 invalidate_region_cache (current_buffer,
11713 current_buffer->width_run_cache,
11714 BEG, Z);
11715 recompute_width_table (current_buffer, disptab);
11716 }
11717 }
11718
11719 /* If window-start is screwed up, choose a new one. */
11720 if (XMARKER (w->start)->buffer != current_buffer)
11721 goto recenter;
11722
11723 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11724
11725 /* If someone specified a new starting point but did not insist,
11726 check whether it can be used. */
11727 if (!NILP (w->optional_new_start)
11728 && CHARPOS (startp) >= BEGV
11729 && CHARPOS (startp) <= ZV)
11730 {
11731 w->optional_new_start = Qnil;
11732 start_display (&it, w, startp);
11733 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11734 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11735 if (IT_CHARPOS (it) == PT)
11736 w->force_start = Qt;
11737 /* IT may overshoot PT if text at PT is invisible. */
11738 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11739 w->force_start = Qt;
11740
11741
11742 }
11743
11744 /* Handle case where place to start displaying has been specified,
11745 unless the specified location is outside the accessible range. */
11746 if (!NILP (w->force_start)
11747 || w->frozen_window_start_p)
11748 {
11749 /* We set this later on if we have to adjust point. */
11750 int new_vpos = -1;
11751
11752 w->force_start = Qnil;
11753 w->vscroll = 0;
11754 w->window_end_valid = Qnil;
11755
11756 /* Forget any recorded base line for line number display. */
11757 if (!buffer_unchanged_p)
11758 w->base_line_number = Qnil;
11759
11760 /* Redisplay the mode line. Select the buffer properly for that.
11761 Also, run the hook window-scroll-functions
11762 because we have scrolled. */
11763 /* Note, we do this after clearing force_start because
11764 if there's an error, it is better to forget about force_start
11765 than to get into an infinite loop calling the hook functions
11766 and having them get more errors. */
11767 if (!update_mode_line
11768 || ! NILP (Vwindow_scroll_functions))
11769 {
11770 update_mode_line = 1;
11771 w->update_mode_line = Qt;
11772 startp = run_window_scroll_functions (window, startp);
11773 }
11774
11775 w->last_modified = make_number (0);
11776 w->last_overlay_modified = make_number (0);
11777 if (CHARPOS (startp) < BEGV)
11778 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11779 else if (CHARPOS (startp) > ZV)
11780 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11781
11782 /* Redisplay, then check if cursor has been set during the
11783 redisplay. Give up if new fonts were loaded. */
11784 if (!try_window (window, startp))
11785 {
11786 w->force_start = Qt;
11787 clear_glyph_matrix (w->desired_matrix);
11788 goto need_larger_matrices;
11789 }
11790
11791 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11792 {
11793 /* If point does not appear, try to move point so it does
11794 appear. The desired matrix has been built above, so we
11795 can use it here. */
11796 new_vpos = window_box_height (w) / 2;
11797 }
11798
11799 if (!make_cursor_line_fully_visible (w, 0))
11800 {
11801 /* Point does appear, but on a line partly visible at end of window.
11802 Move it back to a fully-visible line. */
11803 new_vpos = window_box_height (w);
11804 }
11805
11806 /* If we need to move point for either of the above reasons,
11807 now actually do it. */
11808 if (new_vpos >= 0)
11809 {
11810 struct glyph_row *row;
11811
11812 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11813 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11814 ++row;
11815
11816 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11817 MATRIX_ROW_START_BYTEPOS (row));
11818
11819 if (w != XWINDOW (selected_window))
11820 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11821 else if (current_buffer == old)
11822 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11823
11824 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11825
11826 /* If we are highlighting the region, then we just changed
11827 the region, so redisplay to show it. */
11828 if (!NILP (Vtransient_mark_mode)
11829 && !NILP (current_buffer->mark_active))
11830 {
11831 clear_glyph_matrix (w->desired_matrix);
11832 if (!try_window (window, startp))
11833 goto need_larger_matrices;
11834 }
11835 }
11836
11837 #if GLYPH_DEBUG
11838 debug_method_add (w, "forced window start");
11839 #endif
11840 goto done;
11841 }
11842
11843 /* Handle case where text has not changed, only point, and it has
11844 not moved off the frame, and we are not retrying after hscroll.
11845 (current_matrix_up_to_date_p is nonzero when retrying.) */
11846 if (current_matrix_up_to_date_p
11847 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11848 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11849 {
11850 switch (rc)
11851 {
11852 case CURSOR_MOVEMENT_SUCCESS:
11853 used_current_matrix_p = 1;
11854 goto done;
11855
11856 #if 0 /* try_cursor_movement never returns this value. */
11857 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11858 goto need_larger_matrices;
11859 #endif
11860
11861 case CURSOR_MOVEMENT_MUST_SCROLL:
11862 goto try_to_scroll;
11863
11864 default:
11865 abort ();
11866 }
11867 }
11868 /* If current starting point was originally the beginning of a line
11869 but no longer is, find a new starting point. */
11870 else if (!NILP (w->start_at_line_beg)
11871 && !(CHARPOS (startp) <= BEGV
11872 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11873 {
11874 #if GLYPH_DEBUG
11875 debug_method_add (w, "recenter 1");
11876 #endif
11877 goto recenter;
11878 }
11879
11880 /* Try scrolling with try_window_id. Value is > 0 if update has
11881 been done, it is -1 if we know that the same window start will
11882 not work. It is 0 if unsuccessful for some other reason. */
11883 else if ((tem = try_window_id (w)) != 0)
11884 {
11885 #if GLYPH_DEBUG
11886 debug_method_add (w, "try_window_id %d", tem);
11887 #endif
11888
11889 if (fonts_changed_p)
11890 goto need_larger_matrices;
11891 if (tem > 0)
11892 goto done;
11893
11894 /* Otherwise try_window_id has returned -1 which means that we
11895 don't want the alternative below this comment to execute. */
11896 }
11897 else if (CHARPOS (startp) >= BEGV
11898 && CHARPOS (startp) <= ZV
11899 && PT >= CHARPOS (startp)
11900 && (CHARPOS (startp) < ZV
11901 /* Avoid starting at end of buffer. */
11902 || CHARPOS (startp) == BEGV
11903 || (XFASTINT (w->last_modified) >= MODIFF
11904 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11905 {
11906 #if GLYPH_DEBUG
11907 debug_method_add (w, "same window start");
11908 #endif
11909
11910 /* Try to redisplay starting at same place as before.
11911 If point has not moved off frame, accept the results. */
11912 if (!current_matrix_up_to_date_p
11913 /* Don't use try_window_reusing_current_matrix in this case
11914 because a window scroll function can have changed the
11915 buffer. */
11916 || !NILP (Vwindow_scroll_functions)
11917 || MINI_WINDOW_P (w)
11918 || !(used_current_matrix_p
11919 = try_window_reusing_current_matrix (w)))
11920 {
11921 IF_DEBUG (debug_method_add (w, "1"));
11922 try_window (window, startp);
11923 }
11924
11925 if (fonts_changed_p)
11926 goto need_larger_matrices;
11927
11928 if (w->cursor.vpos >= 0)
11929 {
11930 if (!just_this_one_p
11931 || current_buffer->clip_changed
11932 || BEG_UNCHANGED < CHARPOS (startp))
11933 /* Forget any recorded base line for line number display. */
11934 w->base_line_number = Qnil;
11935
11936 if (!make_cursor_line_fully_visible (w, 1))
11937 {
11938 clear_glyph_matrix (w->desired_matrix);
11939 last_line_misfit = 1;
11940 }
11941 /* Drop through and scroll. */
11942 else
11943 goto done;
11944 }
11945 else
11946 clear_glyph_matrix (w->desired_matrix);
11947 }
11948
11949 try_to_scroll:
11950
11951 w->last_modified = make_number (0);
11952 w->last_overlay_modified = make_number (0);
11953
11954 /* Redisplay the mode line. Select the buffer properly for that. */
11955 if (!update_mode_line)
11956 {
11957 update_mode_line = 1;
11958 w->update_mode_line = Qt;
11959 }
11960
11961 /* Try to scroll by specified few lines. */
11962 if ((scroll_conservatively
11963 || scroll_step
11964 || temp_scroll_step
11965 || NUMBERP (current_buffer->scroll_up_aggressively)
11966 || NUMBERP (current_buffer->scroll_down_aggressively))
11967 && !current_buffer->clip_changed
11968 && CHARPOS (startp) >= BEGV
11969 && CHARPOS (startp) <= ZV)
11970 {
11971 /* The function returns -1 if new fonts were loaded, 1 if
11972 successful, 0 if not successful. */
11973 int rc = try_scrolling (window, just_this_one_p,
11974 scroll_conservatively,
11975 scroll_step,
11976 temp_scroll_step, last_line_misfit);
11977 switch (rc)
11978 {
11979 case SCROLLING_SUCCESS:
11980 goto done;
11981
11982 case SCROLLING_NEED_LARGER_MATRICES:
11983 goto need_larger_matrices;
11984
11985 case SCROLLING_FAILED:
11986 break;
11987
11988 default:
11989 abort ();
11990 }
11991 }
11992
11993 /* Finally, just choose place to start which centers point */
11994
11995 recenter:
11996 centering_position = window_box_height (w) / 2;
11997
11998 point_at_top:
11999 /* Jump here with centering_position already set to 0. */
12000
12001 #if GLYPH_DEBUG
12002 debug_method_add (w, "recenter");
12003 #endif
12004
12005 /* w->vscroll = 0; */
12006
12007 /* Forget any previously recorded base line for line number display. */
12008 if (!buffer_unchanged_p)
12009 w->base_line_number = Qnil;
12010
12011 /* Move backward half the height of the window. */
12012 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12013 it.current_y = it.last_visible_y;
12014 move_it_vertically_backward (&it, centering_position);
12015 xassert (IT_CHARPOS (it) >= BEGV);
12016
12017 /* The function move_it_vertically_backward may move over more
12018 than the specified y-distance. If it->w is small, e.g. a
12019 mini-buffer window, we may end up in front of the window's
12020 display area. Start displaying at the start of the line
12021 containing PT in this case. */
12022 if (it.current_y <= 0)
12023 {
12024 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12025 move_it_vertically (&it, 0);
12026 xassert (IT_CHARPOS (it) <= PT);
12027 it.current_y = 0;
12028 }
12029
12030 it.current_x = it.hpos = 0;
12031
12032 /* Set startp here explicitly in case that helps avoid an infinite loop
12033 in case the window-scroll-functions functions get errors. */
12034 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12035
12036 /* Run scroll hooks. */
12037 startp = run_window_scroll_functions (window, it.current.pos);
12038
12039 /* Redisplay the window. */
12040 if (!current_matrix_up_to_date_p
12041 || windows_or_buffers_changed
12042 || cursor_type_changed
12043 /* Don't use try_window_reusing_current_matrix in this case
12044 because it can have changed the buffer. */
12045 || !NILP (Vwindow_scroll_functions)
12046 || !just_this_one_p
12047 || MINI_WINDOW_P (w)
12048 || !(used_current_matrix_p
12049 = try_window_reusing_current_matrix (w)))
12050 try_window (window, startp);
12051
12052 /* If new fonts have been loaded (due to fontsets), give up. We
12053 have to start a new redisplay since we need to re-adjust glyph
12054 matrices. */
12055 if (fonts_changed_p)
12056 goto need_larger_matrices;
12057
12058 /* If cursor did not appear assume that the middle of the window is
12059 in the first line of the window. Do it again with the next line.
12060 (Imagine a window of height 100, displaying two lines of height
12061 60. Moving back 50 from it->last_visible_y will end in the first
12062 line.) */
12063 if (w->cursor.vpos < 0)
12064 {
12065 if (!NILP (w->window_end_valid)
12066 && PT >= Z - XFASTINT (w->window_end_pos))
12067 {
12068 clear_glyph_matrix (w->desired_matrix);
12069 move_it_by_lines (&it, 1, 0);
12070 try_window (window, it.current.pos);
12071 }
12072 else if (PT < IT_CHARPOS (it))
12073 {
12074 clear_glyph_matrix (w->desired_matrix);
12075 move_it_by_lines (&it, -1, 0);
12076 try_window (window, it.current.pos);
12077 }
12078 else
12079 {
12080 /* Not much we can do about it. */
12081 }
12082 }
12083
12084 /* Consider the following case: Window starts at BEGV, there is
12085 invisible, intangible text at BEGV, so that display starts at
12086 some point START > BEGV. It can happen that we are called with
12087 PT somewhere between BEGV and START. Try to handle that case. */
12088 if (w->cursor.vpos < 0)
12089 {
12090 struct glyph_row *row = w->current_matrix->rows;
12091 if (row->mode_line_p)
12092 ++row;
12093 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12094 }
12095
12096 if (!make_cursor_line_fully_visible (w, centering_position > 0))
12097 {
12098 /* If vscroll is enabled, disable it and try again. */
12099 if (w->vscroll)
12100 {
12101 w->vscroll = 0;
12102 clear_glyph_matrix (w->desired_matrix);
12103 goto recenter;
12104 }
12105
12106 /* If centering point failed to make the whole line visible,
12107 put point at the top instead. That has to make the whole line
12108 visible, if it can be done. */
12109 clear_glyph_matrix (w->desired_matrix);
12110 centering_position = 0;
12111 goto point_at_top;
12112 }
12113
12114 done:
12115
12116 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12117 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12118 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12119 ? Qt : Qnil);
12120
12121 /* Display the mode line, if we must. */
12122 if ((update_mode_line
12123 /* If window not full width, must redo its mode line
12124 if (a) the window to its side is being redone and
12125 (b) we do a frame-based redisplay. This is a consequence
12126 of how inverted lines are drawn in frame-based redisplay. */
12127 || (!just_this_one_p
12128 && !FRAME_WINDOW_P (f)
12129 && !WINDOW_FULL_WIDTH_P (w))
12130 /* Line number to display. */
12131 || INTEGERP (w->base_line_pos)
12132 /* Column number is displayed and different from the one displayed. */
12133 || (!NILP (w->column_number_displayed)
12134 && (XFASTINT (w->column_number_displayed)
12135 != (int) current_column ()))) /* iftc */
12136 /* This means that the window has a mode line. */
12137 && (WINDOW_WANTS_MODELINE_P (w)
12138 || WINDOW_WANTS_HEADER_LINE_P (w)))
12139 {
12140 display_mode_lines (w);
12141
12142 /* If mode line height has changed, arrange for a thorough
12143 immediate redisplay using the correct mode line height. */
12144 if (WINDOW_WANTS_MODELINE_P (w)
12145 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12146 {
12147 fonts_changed_p = 1;
12148 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12149 = DESIRED_MODE_LINE_HEIGHT (w);
12150 }
12151
12152 /* If top line height has changed, arrange for a thorough
12153 immediate redisplay using the correct mode line height. */
12154 if (WINDOW_WANTS_HEADER_LINE_P (w)
12155 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12156 {
12157 fonts_changed_p = 1;
12158 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12159 = DESIRED_HEADER_LINE_HEIGHT (w);
12160 }
12161
12162 if (fonts_changed_p)
12163 goto need_larger_matrices;
12164 }
12165
12166 if (!line_number_displayed
12167 && !BUFFERP (w->base_line_pos))
12168 {
12169 w->base_line_pos = Qnil;
12170 w->base_line_number = Qnil;
12171 }
12172
12173 finish_menu_bars:
12174
12175 /* When we reach a frame's selected window, redo the frame's menu bar. */
12176 if (update_mode_line
12177 && EQ (FRAME_SELECTED_WINDOW (f), window))
12178 {
12179 int redisplay_menu_p = 0;
12180 int redisplay_tool_bar_p = 0;
12181
12182 if (FRAME_WINDOW_P (f))
12183 {
12184 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12185 || defined (USE_GTK)
12186 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12187 #else
12188 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12189 #endif
12190 }
12191 else
12192 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12193
12194 if (redisplay_menu_p)
12195 display_menu_bar (w);
12196
12197 #ifdef HAVE_WINDOW_SYSTEM
12198 #ifdef USE_GTK
12199 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12200 #else
12201 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12202 && (FRAME_TOOL_BAR_LINES (f) > 0
12203 || auto_resize_tool_bars_p);
12204
12205 #endif
12206
12207 if (redisplay_tool_bar_p)
12208 redisplay_tool_bar (f);
12209 #endif
12210 }
12211
12212 #ifdef HAVE_WINDOW_SYSTEM
12213 if (update_window_fringes (w, 0)
12214 && !just_this_one_p
12215 && (used_current_matrix_p || overlay_arrow_seen)
12216 && !w->pseudo_window_p)
12217 {
12218 update_begin (f);
12219 BLOCK_INPUT;
12220 draw_window_fringes (w);
12221 UNBLOCK_INPUT;
12222 update_end (f);
12223 }
12224 #endif /* HAVE_WINDOW_SYSTEM */
12225
12226 /* We go to this label, with fonts_changed_p nonzero,
12227 if it is necessary to try again using larger glyph matrices.
12228 We have to redeem the scroll bar even in this case,
12229 because the loop in redisplay_internal expects that. */
12230 need_larger_matrices:
12231 ;
12232 finish_scroll_bars:
12233
12234 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12235 {
12236 /* Set the thumb's position and size. */
12237 set_vertical_scroll_bar (w);
12238
12239 /* Note that we actually used the scroll bar attached to this
12240 window, so it shouldn't be deleted at the end of redisplay. */
12241 redeem_scroll_bar_hook (w);
12242 }
12243
12244 /* Restore current_buffer and value of point in it. */
12245 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12246 set_buffer_internal_1 (old);
12247 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12248
12249 unbind_to (count, Qnil);
12250 }
12251
12252
12253 /* Build the complete desired matrix of WINDOW with a window start
12254 buffer position POS. Value is non-zero if successful. It is zero
12255 if fonts were loaded during redisplay which makes re-adjusting
12256 glyph matrices necessary. */
12257
12258 int
12259 try_window (window, pos)
12260 Lisp_Object window;
12261 struct text_pos pos;
12262 {
12263 struct window *w = XWINDOW (window);
12264 struct it it;
12265 struct glyph_row *last_text_row = NULL;
12266
12267 /* Make POS the new window start. */
12268 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12269
12270 /* Mark cursor position as unknown. No overlay arrow seen. */
12271 w->cursor.vpos = -1;
12272 overlay_arrow_seen = 0;
12273
12274 /* Initialize iterator and info to start at POS. */
12275 start_display (&it, w, pos);
12276
12277 /* Display all lines of W. */
12278 while (it.current_y < it.last_visible_y)
12279 {
12280 if (display_line (&it))
12281 last_text_row = it.glyph_row - 1;
12282 if (fonts_changed_p)
12283 return 0;
12284 }
12285
12286 /* If bottom moved off end of frame, change mode line percentage. */
12287 if (XFASTINT (w->window_end_pos) <= 0
12288 && Z != IT_CHARPOS (it))
12289 w->update_mode_line = Qt;
12290
12291 /* Set window_end_pos to the offset of the last character displayed
12292 on the window from the end of current_buffer. Set
12293 window_end_vpos to its row number. */
12294 if (last_text_row)
12295 {
12296 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12297 w->window_end_bytepos
12298 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12299 w->window_end_pos
12300 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12301 w->window_end_vpos
12302 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12303 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12304 ->displays_text_p);
12305 }
12306 else
12307 {
12308 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12309 w->window_end_pos = make_number (Z - ZV);
12310 w->window_end_vpos = make_number (0);
12311 }
12312
12313 /* But that is not valid info until redisplay finishes. */
12314 w->window_end_valid = Qnil;
12315 return 1;
12316 }
12317
12318
12319 \f
12320 /************************************************************************
12321 Window redisplay reusing current matrix when buffer has not changed
12322 ************************************************************************/
12323
12324 /* Try redisplay of window W showing an unchanged buffer with a
12325 different window start than the last time it was displayed by
12326 reusing its current matrix. Value is non-zero if successful.
12327 W->start is the new window start. */
12328
12329 static int
12330 try_window_reusing_current_matrix (w)
12331 struct window *w;
12332 {
12333 struct frame *f = XFRAME (w->frame);
12334 struct glyph_row *row, *bottom_row;
12335 struct it it;
12336 struct run run;
12337 struct text_pos start, new_start;
12338 int nrows_scrolled, i;
12339 struct glyph_row *last_text_row;
12340 struct glyph_row *last_reused_text_row;
12341 struct glyph_row *start_row;
12342 int start_vpos, min_y, max_y;
12343
12344 #if GLYPH_DEBUG
12345 if (inhibit_try_window_reusing)
12346 return 0;
12347 #endif
12348
12349 if (/* This function doesn't handle terminal frames. */
12350 !FRAME_WINDOW_P (f)
12351 /* Don't try to reuse the display if windows have been split
12352 or such. */
12353 || windows_or_buffers_changed
12354 || cursor_type_changed)
12355 return 0;
12356
12357 /* Can't do this if region may have changed. */
12358 if ((!NILP (Vtransient_mark_mode)
12359 && !NILP (current_buffer->mark_active))
12360 || !NILP (w->region_showing)
12361 || !NILP (Vshow_trailing_whitespace))
12362 return 0;
12363
12364 /* If top-line visibility has changed, give up. */
12365 if (WINDOW_WANTS_HEADER_LINE_P (w)
12366 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12367 return 0;
12368
12369 /* Give up if old or new display is scrolled vertically. We could
12370 make this function handle this, but right now it doesn't. */
12371 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12372 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12373 return 0;
12374
12375 /* The variable new_start now holds the new window start. The old
12376 start `start' can be determined from the current matrix. */
12377 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12378 start = start_row->start.pos;
12379 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12380
12381 /* Clear the desired matrix for the display below. */
12382 clear_glyph_matrix (w->desired_matrix);
12383
12384 if (CHARPOS (new_start) <= CHARPOS (start))
12385 {
12386 int first_row_y;
12387
12388 /* Don't use this method if the display starts with an ellipsis
12389 displayed for invisible text. It's not easy to handle that case
12390 below, and it's certainly not worth the effort since this is
12391 not a frequent case. */
12392 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12393 return 0;
12394
12395 IF_DEBUG (debug_method_add (w, "twu1"));
12396
12397 /* Display up to a row that can be reused. The variable
12398 last_text_row is set to the last row displayed that displays
12399 text. Note that it.vpos == 0 if or if not there is a
12400 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12401 start_display (&it, w, new_start);
12402 first_row_y = it.current_y;
12403 w->cursor.vpos = -1;
12404 last_text_row = last_reused_text_row = NULL;
12405
12406 while (it.current_y < it.last_visible_y
12407 && !fonts_changed_p)
12408 {
12409 /* If we have reached into the characters in the START row,
12410 that means the line boundaries have changed. So we
12411 can't start copying with the row START. Maybe it will
12412 work to start copying with the following row. */
12413 while (IT_CHARPOS (it) > CHARPOS (start))
12414 {
12415 /* Advance to the next row as the "start". */
12416 start_row++;
12417 start = start_row->start.pos;
12418 /* If there are no more rows to try, or just one, give up. */
12419 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12420 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row)
12421 || CHARPOS (start) == ZV)
12422 {
12423 clear_glyph_matrix (w->desired_matrix);
12424 return 0;
12425 }
12426
12427 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12428 }
12429 /* If we have reached alignment,
12430 we can copy the rest of the rows. */
12431 if (IT_CHARPOS (it) == CHARPOS (start))
12432 break;
12433
12434 if (display_line (&it))
12435 last_text_row = it.glyph_row - 1;
12436 }
12437
12438 /* A value of current_y < last_visible_y means that we stopped
12439 at the previous window start, which in turn means that we
12440 have at least one reusable row. */
12441 if (it.current_y < it.last_visible_y)
12442 {
12443 /* IT.vpos always starts from 0; it counts text lines. */
12444 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12445
12446 /* Find PT if not already found in the lines displayed. */
12447 if (w->cursor.vpos < 0)
12448 {
12449 int dy = it.current_y - start_row->y;
12450
12451 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12452 row = row_containing_pos (w, PT, row, NULL, dy);
12453 if (row)
12454 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12455 dy, nrows_scrolled);
12456 else
12457 {
12458 clear_glyph_matrix (w->desired_matrix);
12459 return 0;
12460 }
12461 }
12462
12463 /* Scroll the display. Do it before the current matrix is
12464 changed. The problem here is that update has not yet
12465 run, i.e. part of the current matrix is not up to date.
12466 scroll_run_hook will clear the cursor, and use the
12467 current matrix to get the height of the row the cursor is
12468 in. */
12469 run.current_y = start_row->y;
12470 run.desired_y = it.current_y;
12471 run.height = it.last_visible_y - it.current_y;
12472
12473 if (run.height > 0 && run.current_y != run.desired_y)
12474 {
12475 update_begin (f);
12476 rif->update_window_begin_hook (w);
12477 rif->clear_window_mouse_face (w);
12478 rif->scroll_run_hook (w, &run);
12479 rif->update_window_end_hook (w, 0, 0);
12480 update_end (f);
12481 }
12482
12483 /* Shift current matrix down by nrows_scrolled lines. */
12484 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12485 rotate_matrix (w->current_matrix,
12486 start_vpos,
12487 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12488 nrows_scrolled);
12489
12490 /* Disable lines that must be updated. */
12491 for (i = 0; i < it.vpos; ++i)
12492 (start_row + i)->enabled_p = 0;
12493
12494 /* Re-compute Y positions. */
12495 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12496 max_y = it.last_visible_y;
12497 for (row = start_row + nrows_scrolled;
12498 row < bottom_row;
12499 ++row)
12500 {
12501 row->y = it.current_y;
12502 row->visible_height = row->height;
12503
12504 if (row->y < min_y)
12505 row->visible_height -= min_y - row->y;
12506 if (row->y + row->height > max_y)
12507 row->visible_height -= row->y + row->height - max_y;
12508 row->redraw_fringe_bitmaps_p = 1;
12509
12510 it.current_y += row->height;
12511
12512 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12513 last_reused_text_row = row;
12514 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12515 break;
12516 }
12517
12518 /* Disable lines in the current matrix which are now
12519 below the window. */
12520 for (++row; row < bottom_row; ++row)
12521 row->enabled_p = 0;
12522 }
12523
12524 /* Update window_end_pos etc.; last_reused_text_row is the last
12525 reused row from the current matrix containing text, if any.
12526 The value of last_text_row is the last displayed line
12527 containing text. */
12528 if (last_reused_text_row)
12529 {
12530 w->window_end_bytepos
12531 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12532 w->window_end_pos
12533 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12534 w->window_end_vpos
12535 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12536 w->current_matrix));
12537 }
12538 else if (last_text_row)
12539 {
12540 w->window_end_bytepos
12541 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12542 w->window_end_pos
12543 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12544 w->window_end_vpos
12545 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12546 }
12547 else
12548 {
12549 /* This window must be completely empty. */
12550 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12551 w->window_end_pos = make_number (Z - ZV);
12552 w->window_end_vpos = make_number (0);
12553 }
12554 w->window_end_valid = Qnil;
12555
12556 /* Update hint: don't try scrolling again in update_window. */
12557 w->desired_matrix->no_scrolling_p = 1;
12558
12559 #if GLYPH_DEBUG
12560 debug_method_add (w, "try_window_reusing_current_matrix 1");
12561 #endif
12562 return 1;
12563 }
12564 else if (CHARPOS (new_start) > CHARPOS (start))
12565 {
12566 struct glyph_row *pt_row, *row;
12567 struct glyph_row *first_reusable_row;
12568 struct glyph_row *first_row_to_display;
12569 int dy;
12570 int yb = window_text_bottom_y (w);
12571
12572 /* Find the row starting at new_start, if there is one. Don't
12573 reuse a partially visible line at the end. */
12574 first_reusable_row = start_row;
12575 while (first_reusable_row->enabled_p
12576 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12577 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12578 < CHARPOS (new_start)))
12579 ++first_reusable_row;
12580
12581 /* Give up if there is no row to reuse. */
12582 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12583 || !first_reusable_row->enabled_p
12584 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12585 != CHARPOS (new_start)))
12586 return 0;
12587
12588 /* We can reuse fully visible rows beginning with
12589 first_reusable_row to the end of the window. Set
12590 first_row_to_display to the first row that cannot be reused.
12591 Set pt_row to the row containing point, if there is any. */
12592 pt_row = NULL;
12593 for (first_row_to_display = first_reusable_row;
12594 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12595 ++first_row_to_display)
12596 {
12597 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12598 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12599 pt_row = first_row_to_display;
12600 }
12601
12602 /* Start displaying at the start of first_row_to_display. */
12603 xassert (first_row_to_display->y < yb);
12604 init_to_row_start (&it, w, first_row_to_display);
12605
12606 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12607 - start_vpos);
12608 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12609 - nrows_scrolled);
12610 it.current_y = (first_row_to_display->y - first_reusable_row->y
12611 + WINDOW_HEADER_LINE_HEIGHT (w));
12612
12613 /* Display lines beginning with first_row_to_display in the
12614 desired matrix. Set last_text_row to the last row displayed
12615 that displays text. */
12616 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12617 if (pt_row == NULL)
12618 w->cursor.vpos = -1;
12619 last_text_row = NULL;
12620 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12621 if (display_line (&it))
12622 last_text_row = it.glyph_row - 1;
12623
12624 /* Give up If point isn't in a row displayed or reused. */
12625 if (w->cursor.vpos < 0)
12626 {
12627 clear_glyph_matrix (w->desired_matrix);
12628 return 0;
12629 }
12630
12631 /* If point is in a reused row, adjust y and vpos of the cursor
12632 position. */
12633 if (pt_row)
12634 {
12635 w->cursor.vpos -= nrows_scrolled;
12636 w->cursor.y -= first_reusable_row->y - start_row->y;
12637 }
12638
12639 /* Scroll the display. */
12640 run.current_y = first_reusable_row->y;
12641 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12642 run.height = it.last_visible_y - run.current_y;
12643 dy = run.current_y - run.desired_y;
12644
12645 if (run.height)
12646 {
12647 update_begin (f);
12648 rif->update_window_begin_hook (w);
12649 rif->clear_window_mouse_face (w);
12650 rif->scroll_run_hook (w, &run);
12651 rif->update_window_end_hook (w, 0, 0);
12652 update_end (f);
12653 }
12654
12655 /* Adjust Y positions of reused rows. */
12656 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12657 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12658 max_y = it.last_visible_y;
12659 for (row = first_reusable_row; row < first_row_to_display; ++row)
12660 {
12661 row->y -= dy;
12662 row->visible_height = row->height;
12663 if (row->y < min_y)
12664 row->visible_height -= min_y - row->y;
12665 if (row->y + row->height > max_y)
12666 row->visible_height -= row->y + row->height - max_y;
12667 row->redraw_fringe_bitmaps_p = 1;
12668 }
12669
12670 /* Scroll the current matrix. */
12671 xassert (nrows_scrolled > 0);
12672 rotate_matrix (w->current_matrix,
12673 start_vpos,
12674 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12675 -nrows_scrolled);
12676
12677 /* Disable rows not reused. */
12678 for (row -= nrows_scrolled; row < bottom_row; ++row)
12679 row->enabled_p = 0;
12680
12681 /* Point may have moved to a different line, so we cannot assume that
12682 the previous cursor position is valid; locate the correct row. */
12683 if (pt_row)
12684 {
12685 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12686 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12687 row++)
12688 {
12689 w->cursor.vpos++;
12690 w->cursor.y = row->y;
12691 }
12692 if (row < bottom_row)
12693 {
12694 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12695 while (glyph->charpos < PT)
12696 {
12697 w->cursor.hpos++;
12698 w->cursor.x += glyph->pixel_width;
12699 glyph++;
12700 }
12701 }
12702 }
12703
12704 /* Adjust window end. A null value of last_text_row means that
12705 the window end is in reused rows which in turn means that
12706 only its vpos can have changed. */
12707 if (last_text_row)
12708 {
12709 w->window_end_bytepos
12710 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12711 w->window_end_pos
12712 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12713 w->window_end_vpos
12714 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12715 }
12716 else
12717 {
12718 w->window_end_vpos
12719 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12720 }
12721
12722 w->window_end_valid = Qnil;
12723 w->desired_matrix->no_scrolling_p = 1;
12724
12725 #if GLYPH_DEBUG
12726 debug_method_add (w, "try_window_reusing_current_matrix 2");
12727 #endif
12728 return 1;
12729 }
12730
12731 return 0;
12732 }
12733
12734
12735 \f
12736 /************************************************************************
12737 Window redisplay reusing current matrix when buffer has changed
12738 ************************************************************************/
12739
12740 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12741 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12742 int *, int *));
12743 static struct glyph_row *
12744 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12745 struct glyph_row *));
12746
12747
12748 /* Return the last row in MATRIX displaying text. If row START is
12749 non-null, start searching with that row. IT gives the dimensions
12750 of the display. Value is null if matrix is empty; otherwise it is
12751 a pointer to the row found. */
12752
12753 static struct glyph_row *
12754 find_last_row_displaying_text (matrix, it, start)
12755 struct glyph_matrix *matrix;
12756 struct it *it;
12757 struct glyph_row *start;
12758 {
12759 struct glyph_row *row, *row_found;
12760
12761 /* Set row_found to the last row in IT->w's current matrix
12762 displaying text. The loop looks funny but think of partially
12763 visible lines. */
12764 row_found = NULL;
12765 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12766 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12767 {
12768 xassert (row->enabled_p);
12769 row_found = row;
12770 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12771 break;
12772 ++row;
12773 }
12774
12775 return row_found;
12776 }
12777
12778
12779 /* Return the last row in the current matrix of W that is not affected
12780 by changes at the start of current_buffer that occurred since W's
12781 current matrix was built. Value is null if no such row exists.
12782
12783 BEG_UNCHANGED us the number of characters unchanged at the start of
12784 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12785 first changed character in current_buffer. Characters at positions <
12786 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12787 when the current matrix was built. */
12788
12789 static struct glyph_row *
12790 find_last_unchanged_at_beg_row (w)
12791 struct window *w;
12792 {
12793 int first_changed_pos = BEG + BEG_UNCHANGED;
12794 struct glyph_row *row;
12795 struct glyph_row *row_found = NULL;
12796 int yb = window_text_bottom_y (w);
12797
12798 /* Find the last row displaying unchanged text. */
12799 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12800 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12801 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12802 {
12803 if (/* If row ends before first_changed_pos, it is unchanged,
12804 except in some case. */
12805 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12806 /* When row ends in ZV and we write at ZV it is not
12807 unchanged. */
12808 && !row->ends_at_zv_p
12809 /* When first_changed_pos is the end of a continued line,
12810 row is not unchanged because it may be no longer
12811 continued. */
12812 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12813 && (row->continued_p
12814 || row->exact_window_width_line_p)))
12815 row_found = row;
12816
12817 /* Stop if last visible row. */
12818 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12819 break;
12820
12821 ++row;
12822 }
12823
12824 return row_found;
12825 }
12826
12827
12828 /* Find the first glyph row in the current matrix of W that is not
12829 affected by changes at the end of current_buffer since the
12830 time W's current matrix was built.
12831
12832 Return in *DELTA the number of chars by which buffer positions in
12833 unchanged text at the end of current_buffer must be adjusted.
12834
12835 Return in *DELTA_BYTES the corresponding number of bytes.
12836
12837 Value is null if no such row exists, i.e. all rows are affected by
12838 changes. */
12839
12840 static struct glyph_row *
12841 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12842 struct window *w;
12843 int *delta, *delta_bytes;
12844 {
12845 struct glyph_row *row;
12846 struct glyph_row *row_found = NULL;
12847
12848 *delta = *delta_bytes = 0;
12849
12850 /* Display must not have been paused, otherwise the current matrix
12851 is not up to date. */
12852 if (NILP (w->window_end_valid))
12853 abort ();
12854
12855 /* A value of window_end_pos >= END_UNCHANGED means that the window
12856 end is in the range of changed text. If so, there is no
12857 unchanged row at the end of W's current matrix. */
12858 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12859 return NULL;
12860
12861 /* Set row to the last row in W's current matrix displaying text. */
12862 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12863
12864 /* If matrix is entirely empty, no unchanged row exists. */
12865 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12866 {
12867 /* The value of row is the last glyph row in the matrix having a
12868 meaningful buffer position in it. The end position of row
12869 corresponds to window_end_pos. This allows us to translate
12870 buffer positions in the current matrix to current buffer
12871 positions for characters not in changed text. */
12872 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12873 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12874 int last_unchanged_pos, last_unchanged_pos_old;
12875 struct glyph_row *first_text_row
12876 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12877
12878 *delta = Z - Z_old;
12879 *delta_bytes = Z_BYTE - Z_BYTE_old;
12880
12881 /* Set last_unchanged_pos to the buffer position of the last
12882 character in the buffer that has not been changed. Z is the
12883 index + 1 of the last character in current_buffer, i.e. by
12884 subtracting END_UNCHANGED we get the index of the last
12885 unchanged character, and we have to add BEG to get its buffer
12886 position. */
12887 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12888 last_unchanged_pos_old = last_unchanged_pos - *delta;
12889
12890 /* Search backward from ROW for a row displaying a line that
12891 starts at a minimum position >= last_unchanged_pos_old. */
12892 for (; row > first_text_row; --row)
12893 {
12894 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12895 abort ();
12896
12897 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12898 row_found = row;
12899 }
12900 }
12901
12902 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12903 abort ();
12904
12905 return row_found;
12906 }
12907
12908
12909 /* Make sure that glyph rows in the current matrix of window W
12910 reference the same glyph memory as corresponding rows in the
12911 frame's frame matrix. This function is called after scrolling W's
12912 current matrix on a terminal frame in try_window_id and
12913 try_window_reusing_current_matrix. */
12914
12915 static void
12916 sync_frame_with_window_matrix_rows (w)
12917 struct window *w;
12918 {
12919 struct frame *f = XFRAME (w->frame);
12920 struct glyph_row *window_row, *window_row_end, *frame_row;
12921
12922 /* Preconditions: W must be a leaf window and full-width. Its frame
12923 must have a frame matrix. */
12924 xassert (NILP (w->hchild) && NILP (w->vchild));
12925 xassert (WINDOW_FULL_WIDTH_P (w));
12926 xassert (!FRAME_WINDOW_P (f));
12927
12928 /* If W is a full-width window, glyph pointers in W's current matrix
12929 have, by definition, to be the same as glyph pointers in the
12930 corresponding frame matrix. Note that frame matrices have no
12931 marginal areas (see build_frame_matrix). */
12932 window_row = w->current_matrix->rows;
12933 window_row_end = window_row + w->current_matrix->nrows;
12934 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12935 while (window_row < window_row_end)
12936 {
12937 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12938 struct glyph *end = window_row->glyphs[LAST_AREA];
12939
12940 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12941 frame_row->glyphs[TEXT_AREA] = start;
12942 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12943 frame_row->glyphs[LAST_AREA] = end;
12944
12945 /* Disable frame rows whose corresponding window rows have
12946 been disabled in try_window_id. */
12947 if (!window_row->enabled_p)
12948 frame_row->enabled_p = 0;
12949
12950 ++window_row, ++frame_row;
12951 }
12952 }
12953
12954
12955 /* Find the glyph row in window W containing CHARPOS. Consider all
12956 rows between START and END (not inclusive). END null means search
12957 all rows to the end of the display area of W. Value is the row
12958 containing CHARPOS or null. */
12959
12960 struct glyph_row *
12961 row_containing_pos (w, charpos, start, end, dy)
12962 struct window *w;
12963 int charpos;
12964 struct glyph_row *start, *end;
12965 int dy;
12966 {
12967 struct glyph_row *row = start;
12968 int last_y;
12969
12970 /* If we happen to start on a header-line, skip that. */
12971 if (row->mode_line_p)
12972 ++row;
12973
12974 if ((end && row >= end) || !row->enabled_p)
12975 return NULL;
12976
12977 last_y = window_text_bottom_y (w) - dy;
12978
12979 while (1)
12980 {
12981 /* Give up if we have gone too far. */
12982 if (end && row >= end)
12983 return NULL;
12984 /* This formerly returned if they were equal.
12985 I think that both quantities are of a "last plus one" type;
12986 if so, when they are equal, the row is within the screen. -- rms. */
12987 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12988 return NULL;
12989
12990 /* If it is in this row, return this row. */
12991 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12992 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12993 /* The end position of a row equals the start
12994 position of the next row. If CHARPOS is there, we
12995 would rather display it in the next line, except
12996 when this line ends in ZV. */
12997 && !row->ends_at_zv_p
12998 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12999 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13000 return row;
13001 ++row;
13002 }
13003 }
13004
13005
13006 /* Try to redisplay window W by reusing its existing display. W's
13007 current matrix must be up to date when this function is called,
13008 i.e. window_end_valid must not be nil.
13009
13010 Value is
13011
13012 1 if display has been updated
13013 0 if otherwise unsuccessful
13014 -1 if redisplay with same window start is known not to succeed
13015
13016 The following steps are performed:
13017
13018 1. Find the last row in the current matrix of W that is not
13019 affected by changes at the start of current_buffer. If no such row
13020 is found, give up.
13021
13022 2. Find the first row in W's current matrix that is not affected by
13023 changes at the end of current_buffer. Maybe there is no such row.
13024
13025 3. Display lines beginning with the row + 1 found in step 1 to the
13026 row found in step 2 or, if step 2 didn't find a row, to the end of
13027 the window.
13028
13029 4. If cursor is not known to appear on the window, give up.
13030
13031 5. If display stopped at the row found in step 2, scroll the
13032 display and current matrix as needed.
13033
13034 6. Maybe display some lines at the end of W, if we must. This can
13035 happen under various circumstances, like a partially visible line
13036 becoming fully visible, or because newly displayed lines are displayed
13037 in smaller font sizes.
13038
13039 7. Update W's window end information. */
13040
13041 static int
13042 try_window_id (w)
13043 struct window *w;
13044 {
13045 struct frame *f = XFRAME (w->frame);
13046 struct glyph_matrix *current_matrix = w->current_matrix;
13047 struct glyph_matrix *desired_matrix = w->desired_matrix;
13048 struct glyph_row *last_unchanged_at_beg_row;
13049 struct glyph_row *first_unchanged_at_end_row;
13050 struct glyph_row *row;
13051 struct glyph_row *bottom_row;
13052 int bottom_vpos;
13053 struct it it;
13054 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13055 struct text_pos start_pos;
13056 struct run run;
13057 int first_unchanged_at_end_vpos = 0;
13058 struct glyph_row *last_text_row, *last_text_row_at_end;
13059 struct text_pos start;
13060 int first_changed_charpos, last_changed_charpos;
13061
13062 #if GLYPH_DEBUG
13063 if (inhibit_try_window_id)
13064 return 0;
13065 #endif
13066
13067 /* This is handy for debugging. */
13068 #if 0
13069 #define GIVE_UP(X) \
13070 do { \
13071 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13072 return 0; \
13073 } while (0)
13074 #else
13075 #define GIVE_UP(X) return 0
13076 #endif
13077
13078 SET_TEXT_POS_FROM_MARKER (start, w->start);
13079
13080 /* Don't use this for mini-windows because these can show
13081 messages and mini-buffers, and we don't handle that here. */
13082 if (MINI_WINDOW_P (w))
13083 GIVE_UP (1);
13084
13085 /* This flag is used to prevent redisplay optimizations. */
13086 if (windows_or_buffers_changed || cursor_type_changed)
13087 GIVE_UP (2);
13088
13089 /* Verify that narrowing has not changed.
13090 Also verify that we were not told to prevent redisplay optimizations.
13091 It would be nice to further
13092 reduce the number of cases where this prevents try_window_id. */
13093 if (current_buffer->clip_changed
13094 || current_buffer->prevent_redisplay_optimizations_p)
13095 GIVE_UP (3);
13096
13097 /* Window must either use window-based redisplay or be full width. */
13098 if (!FRAME_WINDOW_P (f)
13099 && (!line_ins_del_ok
13100 || !WINDOW_FULL_WIDTH_P (w)))
13101 GIVE_UP (4);
13102
13103 /* Give up if point is not known NOT to appear in W. */
13104 if (PT < CHARPOS (start))
13105 GIVE_UP (5);
13106
13107 /* Another way to prevent redisplay optimizations. */
13108 if (XFASTINT (w->last_modified) == 0)
13109 GIVE_UP (6);
13110
13111 /* Verify that window is not hscrolled. */
13112 if (XFASTINT (w->hscroll) != 0)
13113 GIVE_UP (7);
13114
13115 /* Verify that display wasn't paused. */
13116 if (NILP (w->window_end_valid))
13117 GIVE_UP (8);
13118
13119 /* Can't use this if highlighting a region because a cursor movement
13120 will do more than just set the cursor. */
13121 if (!NILP (Vtransient_mark_mode)
13122 && !NILP (current_buffer->mark_active))
13123 GIVE_UP (9);
13124
13125 /* Likewise if highlighting trailing whitespace. */
13126 if (!NILP (Vshow_trailing_whitespace))
13127 GIVE_UP (11);
13128
13129 /* Likewise if showing a region. */
13130 if (!NILP (w->region_showing))
13131 GIVE_UP (10);
13132
13133 /* Can use this if overlay arrow position and or string have changed. */
13134 if (overlay_arrows_changed_p ())
13135 GIVE_UP (12);
13136
13137
13138 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13139 only if buffer has really changed. The reason is that the gap is
13140 initially at Z for freshly visited files. The code below would
13141 set end_unchanged to 0 in that case. */
13142 if (MODIFF > SAVE_MODIFF
13143 /* This seems to happen sometimes after saving a buffer. */
13144 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13145 {
13146 if (GPT - BEG < BEG_UNCHANGED)
13147 BEG_UNCHANGED = GPT - BEG;
13148 if (Z - GPT < END_UNCHANGED)
13149 END_UNCHANGED = Z - GPT;
13150 }
13151
13152 /* The position of the first and last character that has been changed. */
13153 first_changed_charpos = BEG + BEG_UNCHANGED;
13154 last_changed_charpos = Z - END_UNCHANGED;
13155
13156 /* If window starts after a line end, and the last change is in
13157 front of that newline, then changes don't affect the display.
13158 This case happens with stealth-fontification. Note that although
13159 the display is unchanged, glyph positions in the matrix have to
13160 be adjusted, of course. */
13161 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13162 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13163 && ((last_changed_charpos < CHARPOS (start)
13164 && CHARPOS (start) == BEGV)
13165 || (last_changed_charpos < CHARPOS (start) - 1
13166 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13167 {
13168 int Z_old, delta, Z_BYTE_old, delta_bytes;
13169 struct glyph_row *r0;
13170
13171 /* Compute how many chars/bytes have been added to or removed
13172 from the buffer. */
13173 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13174 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13175 delta = Z - Z_old;
13176 delta_bytes = Z_BYTE - Z_BYTE_old;
13177
13178 /* Give up if PT is not in the window. Note that it already has
13179 been checked at the start of try_window_id that PT is not in
13180 front of the window start. */
13181 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13182 GIVE_UP (13);
13183
13184 /* If window start is unchanged, we can reuse the whole matrix
13185 as is, after adjusting glyph positions. No need to compute
13186 the window end again, since its offset from Z hasn't changed. */
13187 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13188 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13189 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13190 /* PT must not be in a partially visible line. */
13191 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13192 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13193 {
13194 /* Adjust positions in the glyph matrix. */
13195 if (delta || delta_bytes)
13196 {
13197 struct glyph_row *r1
13198 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13199 increment_matrix_positions (w->current_matrix,
13200 MATRIX_ROW_VPOS (r0, current_matrix),
13201 MATRIX_ROW_VPOS (r1, current_matrix),
13202 delta, delta_bytes);
13203 }
13204
13205 /* Set the cursor. */
13206 row = row_containing_pos (w, PT, r0, NULL, 0);
13207 if (row)
13208 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13209 else
13210 abort ();
13211 return 1;
13212 }
13213 }
13214
13215 /* Handle the case that changes are all below what is displayed in
13216 the window, and that PT is in the window. This shortcut cannot
13217 be taken if ZV is visible in the window, and text has been added
13218 there that is visible in the window. */
13219 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13220 /* ZV is not visible in the window, or there are no
13221 changes at ZV, actually. */
13222 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13223 || first_changed_charpos == last_changed_charpos))
13224 {
13225 struct glyph_row *r0;
13226
13227 /* Give up if PT is not in the window. Note that it already has
13228 been checked at the start of try_window_id that PT is not in
13229 front of the window start. */
13230 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13231 GIVE_UP (14);
13232
13233 /* If window start is unchanged, we can reuse the whole matrix
13234 as is, without changing glyph positions since no text has
13235 been added/removed in front of the window end. */
13236 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13237 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13238 /* PT must not be in a partially visible line. */
13239 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13240 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13241 {
13242 /* We have to compute the window end anew since text
13243 can have been added/removed after it. */
13244 w->window_end_pos
13245 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13246 w->window_end_bytepos
13247 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13248
13249 /* Set the cursor. */
13250 row = row_containing_pos (w, PT, r0, NULL, 0);
13251 if (row)
13252 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13253 else
13254 abort ();
13255 return 2;
13256 }
13257 }
13258
13259 /* Give up if window start is in the changed area.
13260
13261 The condition used to read
13262
13263 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13264
13265 but why that was tested escapes me at the moment. */
13266 if (CHARPOS (start) >= first_changed_charpos
13267 && CHARPOS (start) <= last_changed_charpos)
13268 GIVE_UP (15);
13269
13270 /* Check that window start agrees with the start of the first glyph
13271 row in its current matrix. Check this after we know the window
13272 start is not in changed text, otherwise positions would not be
13273 comparable. */
13274 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13275 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13276 GIVE_UP (16);
13277
13278 /* Give up if the window ends in strings. Overlay strings
13279 at the end are difficult to handle, so don't try. */
13280 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13281 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13282 GIVE_UP (20);
13283
13284 /* Compute the position at which we have to start displaying new
13285 lines. Some of the lines at the top of the window might be
13286 reusable because they are not displaying changed text. Find the
13287 last row in W's current matrix not affected by changes at the
13288 start of current_buffer. Value is null if changes start in the
13289 first line of window. */
13290 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13291 if (last_unchanged_at_beg_row)
13292 {
13293 /* Avoid starting to display in the moddle of a character, a TAB
13294 for instance. This is easier than to set up the iterator
13295 exactly, and it's not a frequent case, so the additional
13296 effort wouldn't really pay off. */
13297 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13298 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13299 && last_unchanged_at_beg_row > w->current_matrix->rows)
13300 --last_unchanged_at_beg_row;
13301
13302 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13303 GIVE_UP (17);
13304
13305 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13306 GIVE_UP (18);
13307 start_pos = it.current.pos;
13308
13309 /* Start displaying new lines in the desired matrix at the same
13310 vpos we would use in the current matrix, i.e. below
13311 last_unchanged_at_beg_row. */
13312 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13313 current_matrix);
13314 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13315 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13316
13317 xassert (it.hpos == 0 && it.current_x == 0);
13318 }
13319 else
13320 {
13321 /* There are no reusable lines at the start of the window.
13322 Start displaying in the first text line. */
13323 start_display (&it, w, start);
13324 it.vpos = it.first_vpos;
13325 start_pos = it.current.pos;
13326 }
13327
13328 /* Find the first row that is not affected by changes at the end of
13329 the buffer. Value will be null if there is no unchanged row, in
13330 which case we must redisplay to the end of the window. delta
13331 will be set to the value by which buffer positions beginning with
13332 first_unchanged_at_end_row have to be adjusted due to text
13333 changes. */
13334 first_unchanged_at_end_row
13335 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13336 IF_DEBUG (debug_delta = delta);
13337 IF_DEBUG (debug_delta_bytes = delta_bytes);
13338
13339 /* Set stop_pos to the buffer position up to which we will have to
13340 display new lines. If first_unchanged_at_end_row != NULL, this
13341 is the buffer position of the start of the line displayed in that
13342 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13343 that we don't stop at a buffer position. */
13344 stop_pos = 0;
13345 if (first_unchanged_at_end_row)
13346 {
13347 xassert (last_unchanged_at_beg_row == NULL
13348 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13349
13350 /* If this is a continuation line, move forward to the next one
13351 that isn't. Changes in lines above affect this line.
13352 Caution: this may move first_unchanged_at_end_row to a row
13353 not displaying text. */
13354 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13355 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13356 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13357 < it.last_visible_y))
13358 ++first_unchanged_at_end_row;
13359
13360 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13361 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13362 >= it.last_visible_y))
13363 first_unchanged_at_end_row = NULL;
13364 else
13365 {
13366 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13367 + delta);
13368 first_unchanged_at_end_vpos
13369 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13370 xassert (stop_pos >= Z - END_UNCHANGED);
13371 }
13372 }
13373 else if (last_unchanged_at_beg_row == NULL)
13374 GIVE_UP (19);
13375
13376
13377 #if GLYPH_DEBUG
13378
13379 /* Either there is no unchanged row at the end, or the one we have
13380 now displays text. This is a necessary condition for the window
13381 end pos calculation at the end of this function. */
13382 xassert (first_unchanged_at_end_row == NULL
13383 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13384
13385 debug_last_unchanged_at_beg_vpos
13386 = (last_unchanged_at_beg_row
13387 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13388 : -1);
13389 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13390
13391 #endif /* GLYPH_DEBUG != 0 */
13392
13393
13394 /* Display new lines. Set last_text_row to the last new line
13395 displayed which has text on it, i.e. might end up as being the
13396 line where the window_end_vpos is. */
13397 w->cursor.vpos = -1;
13398 last_text_row = NULL;
13399 overlay_arrow_seen = 0;
13400 while (it.current_y < it.last_visible_y
13401 && !fonts_changed_p
13402 && (first_unchanged_at_end_row == NULL
13403 || IT_CHARPOS (it) < stop_pos))
13404 {
13405 if (display_line (&it))
13406 last_text_row = it.glyph_row - 1;
13407 }
13408
13409 if (fonts_changed_p)
13410 return -1;
13411
13412
13413 /* Compute differences in buffer positions, y-positions etc. for
13414 lines reused at the bottom of the window. Compute what we can
13415 scroll. */
13416 if (first_unchanged_at_end_row
13417 /* No lines reused because we displayed everything up to the
13418 bottom of the window. */
13419 && it.current_y < it.last_visible_y)
13420 {
13421 dvpos = (it.vpos
13422 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13423 current_matrix));
13424 dy = it.current_y - first_unchanged_at_end_row->y;
13425 run.current_y = first_unchanged_at_end_row->y;
13426 run.desired_y = run.current_y + dy;
13427 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13428 }
13429 else
13430 {
13431 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13432 first_unchanged_at_end_row = NULL;
13433 }
13434 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13435
13436
13437 /* Find the cursor if not already found. We have to decide whether
13438 PT will appear on this window (it sometimes doesn't, but this is
13439 not a very frequent case.) This decision has to be made before
13440 the current matrix is altered. A value of cursor.vpos < 0 means
13441 that PT is either in one of the lines beginning at
13442 first_unchanged_at_end_row or below the window. Don't care for
13443 lines that might be displayed later at the window end; as
13444 mentioned, this is not a frequent case. */
13445 if (w->cursor.vpos < 0)
13446 {
13447 /* Cursor in unchanged rows at the top? */
13448 if (PT < CHARPOS (start_pos)
13449 && last_unchanged_at_beg_row)
13450 {
13451 row = row_containing_pos (w, PT,
13452 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13453 last_unchanged_at_beg_row + 1, 0);
13454 if (row)
13455 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13456 }
13457
13458 /* Start from first_unchanged_at_end_row looking for PT. */
13459 else if (first_unchanged_at_end_row)
13460 {
13461 row = row_containing_pos (w, PT - delta,
13462 first_unchanged_at_end_row, NULL, 0);
13463 if (row)
13464 set_cursor_from_row (w, row, w->current_matrix, delta,
13465 delta_bytes, dy, dvpos);
13466 }
13467
13468 /* Give up if cursor was not found. */
13469 if (w->cursor.vpos < 0)
13470 {
13471 clear_glyph_matrix (w->desired_matrix);
13472 return -1;
13473 }
13474 }
13475
13476 /* Don't let the cursor end in the scroll margins. */
13477 {
13478 int this_scroll_margin, cursor_height;
13479
13480 this_scroll_margin = max (0, scroll_margin);
13481 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13482 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13483 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13484
13485 if ((w->cursor.y < this_scroll_margin
13486 && CHARPOS (start) > BEGV)
13487 /* Old redisplay didn't take scroll margin into account at the bottom,
13488 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13489 || w->cursor.y + cursor_height + this_scroll_margin > it.last_visible_y)
13490 {
13491 w->cursor.vpos = -1;
13492 clear_glyph_matrix (w->desired_matrix);
13493 return -1;
13494 }
13495 }
13496
13497 /* Scroll the display. Do it before changing the current matrix so
13498 that xterm.c doesn't get confused about where the cursor glyph is
13499 found. */
13500 if (dy && run.height)
13501 {
13502 update_begin (f);
13503
13504 if (FRAME_WINDOW_P (f))
13505 {
13506 rif->update_window_begin_hook (w);
13507 rif->clear_window_mouse_face (w);
13508 rif->scroll_run_hook (w, &run);
13509 rif->update_window_end_hook (w, 0, 0);
13510 }
13511 else
13512 {
13513 /* Terminal frame. In this case, dvpos gives the number of
13514 lines to scroll by; dvpos < 0 means scroll up. */
13515 int first_unchanged_at_end_vpos
13516 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13517 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13518 int end = (WINDOW_TOP_EDGE_LINE (w)
13519 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13520 + window_internal_height (w));
13521
13522 /* Perform the operation on the screen. */
13523 if (dvpos > 0)
13524 {
13525 /* Scroll last_unchanged_at_beg_row to the end of the
13526 window down dvpos lines. */
13527 set_terminal_window (end);
13528
13529 /* On dumb terminals delete dvpos lines at the end
13530 before inserting dvpos empty lines. */
13531 if (!scroll_region_ok)
13532 ins_del_lines (end - dvpos, -dvpos);
13533
13534 /* Insert dvpos empty lines in front of
13535 last_unchanged_at_beg_row. */
13536 ins_del_lines (from, dvpos);
13537 }
13538 else if (dvpos < 0)
13539 {
13540 /* Scroll up last_unchanged_at_beg_vpos to the end of
13541 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13542 set_terminal_window (end);
13543
13544 /* Delete dvpos lines in front of
13545 last_unchanged_at_beg_vpos. ins_del_lines will set
13546 the cursor to the given vpos and emit |dvpos| delete
13547 line sequences. */
13548 ins_del_lines (from + dvpos, dvpos);
13549
13550 /* On a dumb terminal insert dvpos empty lines at the
13551 end. */
13552 if (!scroll_region_ok)
13553 ins_del_lines (end + dvpos, -dvpos);
13554 }
13555
13556 set_terminal_window (0);
13557 }
13558
13559 update_end (f);
13560 }
13561
13562 /* Shift reused rows of the current matrix to the right position.
13563 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13564 text. */
13565 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13566 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13567 if (dvpos < 0)
13568 {
13569 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13570 bottom_vpos, dvpos);
13571 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13572 bottom_vpos, 0);
13573 }
13574 else if (dvpos > 0)
13575 {
13576 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13577 bottom_vpos, dvpos);
13578 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13579 first_unchanged_at_end_vpos + dvpos, 0);
13580 }
13581
13582 /* For frame-based redisplay, make sure that current frame and window
13583 matrix are in sync with respect to glyph memory. */
13584 if (!FRAME_WINDOW_P (f))
13585 sync_frame_with_window_matrix_rows (w);
13586
13587 /* Adjust buffer positions in reused rows. */
13588 if (delta)
13589 increment_matrix_positions (current_matrix,
13590 first_unchanged_at_end_vpos + dvpos,
13591 bottom_vpos, delta, delta_bytes);
13592
13593 /* Adjust Y positions. */
13594 if (dy)
13595 shift_glyph_matrix (w, current_matrix,
13596 first_unchanged_at_end_vpos + dvpos,
13597 bottom_vpos, dy);
13598
13599 if (first_unchanged_at_end_row)
13600 first_unchanged_at_end_row += dvpos;
13601
13602 /* If scrolling up, there may be some lines to display at the end of
13603 the window. */
13604 last_text_row_at_end = NULL;
13605 if (dy < 0)
13606 {
13607 /* Scrolling up can leave for example a partially visible line
13608 at the end of the window to be redisplayed. */
13609 /* Set last_row to the glyph row in the current matrix where the
13610 window end line is found. It has been moved up or down in
13611 the matrix by dvpos. */
13612 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13613 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13614
13615 /* If last_row is the window end line, it should display text. */
13616 xassert (last_row->displays_text_p);
13617
13618 /* If window end line was partially visible before, begin
13619 displaying at that line. Otherwise begin displaying with the
13620 line following it. */
13621 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13622 {
13623 init_to_row_start (&it, w, last_row);
13624 it.vpos = last_vpos;
13625 it.current_y = last_row->y;
13626 }
13627 else
13628 {
13629 init_to_row_end (&it, w, last_row);
13630 it.vpos = 1 + last_vpos;
13631 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13632 ++last_row;
13633 }
13634
13635 /* We may start in a continuation line. If so, we have to
13636 get the right continuation_lines_width and current_x. */
13637 it.continuation_lines_width = last_row->continuation_lines_width;
13638 it.hpos = it.current_x = 0;
13639
13640 /* Display the rest of the lines at the window end. */
13641 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13642 while (it.current_y < it.last_visible_y
13643 && !fonts_changed_p)
13644 {
13645 /* Is it always sure that the display agrees with lines in
13646 the current matrix? I don't think so, so we mark rows
13647 displayed invalid in the current matrix by setting their
13648 enabled_p flag to zero. */
13649 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13650 if (display_line (&it))
13651 last_text_row_at_end = it.glyph_row - 1;
13652 }
13653 }
13654
13655 /* Update window_end_pos and window_end_vpos. */
13656 if (first_unchanged_at_end_row
13657 && first_unchanged_at_end_row->y < it.last_visible_y
13658 && !last_text_row_at_end)
13659 {
13660 /* Window end line if one of the preserved rows from the current
13661 matrix. Set row to the last row displaying text in current
13662 matrix starting at first_unchanged_at_end_row, after
13663 scrolling. */
13664 xassert (first_unchanged_at_end_row->displays_text_p);
13665 row = find_last_row_displaying_text (w->current_matrix, &it,
13666 first_unchanged_at_end_row);
13667 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13668
13669 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13670 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13671 w->window_end_vpos
13672 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13673 xassert (w->window_end_bytepos >= 0);
13674 IF_DEBUG (debug_method_add (w, "A"));
13675 }
13676 else if (last_text_row_at_end)
13677 {
13678 w->window_end_pos
13679 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13680 w->window_end_bytepos
13681 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13682 w->window_end_vpos
13683 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13684 xassert (w->window_end_bytepos >= 0);
13685 IF_DEBUG (debug_method_add (w, "B"));
13686 }
13687 else if (last_text_row)
13688 {
13689 /* We have displayed either to the end of the window or at the
13690 end of the window, i.e. the last row with text is to be found
13691 in the desired matrix. */
13692 w->window_end_pos
13693 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13694 w->window_end_bytepos
13695 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13696 w->window_end_vpos
13697 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13698 xassert (w->window_end_bytepos >= 0);
13699 }
13700 else if (first_unchanged_at_end_row == NULL
13701 && last_text_row == NULL
13702 && last_text_row_at_end == NULL)
13703 {
13704 /* Displayed to end of window, but no line containing text was
13705 displayed. Lines were deleted at the end of the window. */
13706 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13707 int vpos = XFASTINT (w->window_end_vpos);
13708 struct glyph_row *current_row = current_matrix->rows + vpos;
13709 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13710
13711 for (row = NULL;
13712 row == NULL && vpos >= first_vpos;
13713 --vpos, --current_row, --desired_row)
13714 {
13715 if (desired_row->enabled_p)
13716 {
13717 if (desired_row->displays_text_p)
13718 row = desired_row;
13719 }
13720 else if (current_row->displays_text_p)
13721 row = current_row;
13722 }
13723
13724 xassert (row != NULL);
13725 w->window_end_vpos = make_number (vpos + 1);
13726 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13727 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13728 xassert (w->window_end_bytepos >= 0);
13729 IF_DEBUG (debug_method_add (w, "C"));
13730 }
13731 else
13732 abort ();
13733
13734 #if 0 /* This leads to problems, for instance when the cursor is
13735 at ZV, and the cursor line displays no text. */
13736 /* Disable rows below what's displayed in the window. This makes
13737 debugging easier. */
13738 enable_glyph_matrix_rows (current_matrix,
13739 XFASTINT (w->window_end_vpos) + 1,
13740 bottom_vpos, 0);
13741 #endif
13742
13743 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13744 debug_end_vpos = XFASTINT (w->window_end_vpos));
13745
13746 /* Record that display has not been completed. */
13747 w->window_end_valid = Qnil;
13748 w->desired_matrix->no_scrolling_p = 1;
13749 return 3;
13750
13751 #undef GIVE_UP
13752 }
13753
13754
13755 \f
13756 /***********************************************************************
13757 More debugging support
13758 ***********************************************************************/
13759
13760 #if GLYPH_DEBUG
13761
13762 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13763 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13764 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13765
13766
13767 /* Dump the contents of glyph matrix MATRIX on stderr.
13768
13769 GLYPHS 0 means don't show glyph contents.
13770 GLYPHS 1 means show glyphs in short form
13771 GLYPHS > 1 means show glyphs in long form. */
13772
13773 void
13774 dump_glyph_matrix (matrix, glyphs)
13775 struct glyph_matrix *matrix;
13776 int glyphs;
13777 {
13778 int i;
13779 for (i = 0; i < matrix->nrows; ++i)
13780 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13781 }
13782
13783
13784 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13785 the glyph row and area where the glyph comes from. */
13786
13787 void
13788 dump_glyph (row, glyph, area)
13789 struct glyph_row *row;
13790 struct glyph *glyph;
13791 int area;
13792 {
13793 if (glyph->type == CHAR_GLYPH)
13794 {
13795 fprintf (stderr,
13796 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13797 glyph - row->glyphs[TEXT_AREA],
13798 'C',
13799 glyph->charpos,
13800 (BUFFERP (glyph->object)
13801 ? 'B'
13802 : (STRINGP (glyph->object)
13803 ? 'S'
13804 : '-')),
13805 glyph->pixel_width,
13806 glyph->u.ch,
13807 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13808 ? glyph->u.ch
13809 : '.'),
13810 glyph->face_id,
13811 glyph->left_box_line_p,
13812 glyph->right_box_line_p);
13813 }
13814 else if (glyph->type == STRETCH_GLYPH)
13815 {
13816 fprintf (stderr,
13817 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13818 glyph - row->glyphs[TEXT_AREA],
13819 'S',
13820 glyph->charpos,
13821 (BUFFERP (glyph->object)
13822 ? 'B'
13823 : (STRINGP (glyph->object)
13824 ? 'S'
13825 : '-')),
13826 glyph->pixel_width,
13827 0,
13828 '.',
13829 glyph->face_id,
13830 glyph->left_box_line_p,
13831 glyph->right_box_line_p);
13832 }
13833 else if (glyph->type == IMAGE_GLYPH)
13834 {
13835 fprintf (stderr,
13836 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13837 glyph - row->glyphs[TEXT_AREA],
13838 'I',
13839 glyph->charpos,
13840 (BUFFERP (glyph->object)
13841 ? 'B'
13842 : (STRINGP (glyph->object)
13843 ? 'S'
13844 : '-')),
13845 glyph->pixel_width,
13846 glyph->u.img_id,
13847 '.',
13848 glyph->face_id,
13849 glyph->left_box_line_p,
13850 glyph->right_box_line_p);
13851 }
13852 }
13853
13854
13855 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13856 GLYPHS 0 means don't show glyph contents.
13857 GLYPHS 1 means show glyphs in short form
13858 GLYPHS > 1 means show glyphs in long form. */
13859
13860 void
13861 dump_glyph_row (row, vpos, glyphs)
13862 struct glyph_row *row;
13863 int vpos, glyphs;
13864 {
13865 if (glyphs != 1)
13866 {
13867 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13868 fprintf (stderr, "=======================================================================\n");
13869
13870 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13871 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13872 vpos,
13873 MATRIX_ROW_START_CHARPOS (row),
13874 MATRIX_ROW_END_CHARPOS (row),
13875 row->used[TEXT_AREA],
13876 row->contains_overlapping_glyphs_p,
13877 row->enabled_p,
13878 row->truncated_on_left_p,
13879 row->truncated_on_right_p,
13880 row->overlay_arrow_p,
13881 row->continued_p,
13882 MATRIX_ROW_CONTINUATION_LINE_P (row),
13883 row->displays_text_p,
13884 row->ends_at_zv_p,
13885 row->fill_line_p,
13886 row->ends_in_middle_of_char_p,
13887 row->starts_in_middle_of_char_p,
13888 row->mouse_face_p,
13889 row->x,
13890 row->y,
13891 row->pixel_width,
13892 row->height,
13893 row->visible_height,
13894 row->ascent,
13895 row->phys_ascent);
13896 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13897 row->end.overlay_string_index,
13898 row->continuation_lines_width);
13899 fprintf (stderr, "%9d %5d\n",
13900 CHARPOS (row->start.string_pos),
13901 CHARPOS (row->end.string_pos));
13902 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13903 row->end.dpvec_index);
13904 }
13905
13906 if (glyphs > 1)
13907 {
13908 int area;
13909
13910 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13911 {
13912 struct glyph *glyph = row->glyphs[area];
13913 struct glyph *glyph_end = glyph + row->used[area];
13914
13915 /* Glyph for a line end in text. */
13916 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13917 ++glyph_end;
13918
13919 if (glyph < glyph_end)
13920 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13921
13922 for (; glyph < glyph_end; ++glyph)
13923 dump_glyph (row, glyph, area);
13924 }
13925 }
13926 else if (glyphs == 1)
13927 {
13928 int area;
13929
13930 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13931 {
13932 char *s = (char *) alloca (row->used[area] + 1);
13933 int i;
13934
13935 for (i = 0; i < row->used[area]; ++i)
13936 {
13937 struct glyph *glyph = row->glyphs[area] + i;
13938 if (glyph->type == CHAR_GLYPH
13939 && glyph->u.ch < 0x80
13940 && glyph->u.ch >= ' ')
13941 s[i] = glyph->u.ch;
13942 else
13943 s[i] = '.';
13944 }
13945
13946 s[i] = '\0';
13947 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13948 }
13949 }
13950 }
13951
13952
13953 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13954 Sdump_glyph_matrix, 0, 1, "p",
13955 doc: /* Dump the current matrix of the selected window to stderr.
13956 Shows contents of glyph row structures. With non-nil
13957 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13958 glyphs in short form, otherwise show glyphs in long form. */)
13959 (glyphs)
13960 Lisp_Object glyphs;
13961 {
13962 struct window *w = XWINDOW (selected_window);
13963 struct buffer *buffer = XBUFFER (w->buffer);
13964
13965 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13966 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13967 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13968 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13969 fprintf (stderr, "=============================================\n");
13970 dump_glyph_matrix (w->current_matrix,
13971 NILP (glyphs) ? 0 : XINT (glyphs));
13972 return Qnil;
13973 }
13974
13975
13976 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13977 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13978 ()
13979 {
13980 struct frame *f = XFRAME (selected_frame);
13981 dump_glyph_matrix (f->current_matrix, 1);
13982 return Qnil;
13983 }
13984
13985
13986 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13987 doc: /* Dump glyph row ROW to stderr.
13988 GLYPH 0 means don't dump glyphs.
13989 GLYPH 1 means dump glyphs in short form.
13990 GLYPH > 1 or omitted means dump glyphs in long form. */)
13991 (row, glyphs)
13992 Lisp_Object row, glyphs;
13993 {
13994 struct glyph_matrix *matrix;
13995 int vpos;
13996
13997 CHECK_NUMBER (row);
13998 matrix = XWINDOW (selected_window)->current_matrix;
13999 vpos = XINT (row);
14000 if (vpos >= 0 && vpos < matrix->nrows)
14001 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14002 vpos,
14003 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14004 return Qnil;
14005 }
14006
14007
14008 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14009 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14010 GLYPH 0 means don't dump glyphs.
14011 GLYPH 1 means dump glyphs in short form.
14012 GLYPH > 1 or omitted means dump glyphs in long form. */)
14013 (row, glyphs)
14014 Lisp_Object row, glyphs;
14015 {
14016 struct frame *sf = SELECTED_FRAME ();
14017 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14018 int vpos;
14019
14020 CHECK_NUMBER (row);
14021 vpos = XINT (row);
14022 if (vpos >= 0 && vpos < m->nrows)
14023 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14024 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14025 return Qnil;
14026 }
14027
14028
14029 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14030 doc: /* Toggle tracing of redisplay.
14031 With ARG, turn tracing on if and only if ARG is positive. */)
14032 (arg)
14033 Lisp_Object arg;
14034 {
14035 if (NILP (arg))
14036 trace_redisplay_p = !trace_redisplay_p;
14037 else
14038 {
14039 arg = Fprefix_numeric_value (arg);
14040 trace_redisplay_p = XINT (arg) > 0;
14041 }
14042
14043 return Qnil;
14044 }
14045
14046
14047 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14048 doc: /* Like `format', but print result to stderr.
14049 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14050 (nargs, args)
14051 int nargs;
14052 Lisp_Object *args;
14053 {
14054 Lisp_Object s = Fformat (nargs, args);
14055 fprintf (stderr, "%s", SDATA (s));
14056 return Qnil;
14057 }
14058
14059 #endif /* GLYPH_DEBUG */
14060
14061
14062 \f
14063 /***********************************************************************
14064 Building Desired Matrix Rows
14065 ***********************************************************************/
14066
14067 /* Return a temporary glyph row holding the glyphs of an overlay
14068 arrow. Only used for non-window-redisplay windows. */
14069
14070 static struct glyph_row *
14071 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14072 struct window *w;
14073 Lisp_Object overlay_arrow_string;
14074 {
14075 struct frame *f = XFRAME (WINDOW_FRAME (w));
14076 struct buffer *buffer = XBUFFER (w->buffer);
14077 struct buffer *old = current_buffer;
14078 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14079 int arrow_len = SCHARS (overlay_arrow_string);
14080 const unsigned char *arrow_end = arrow_string + arrow_len;
14081 const unsigned char *p;
14082 struct it it;
14083 int multibyte_p;
14084 int n_glyphs_before;
14085
14086 set_buffer_temp (buffer);
14087 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14088 it.glyph_row->used[TEXT_AREA] = 0;
14089 SET_TEXT_POS (it.position, 0, 0);
14090
14091 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14092 p = arrow_string;
14093 while (p < arrow_end)
14094 {
14095 Lisp_Object face, ilisp;
14096
14097 /* Get the next character. */
14098 if (multibyte_p)
14099 it.c = string_char_and_length (p, arrow_len, &it.len);
14100 else
14101 it.c = *p, it.len = 1;
14102 p += it.len;
14103
14104 /* Get its face. */
14105 ilisp = make_number (p - arrow_string);
14106 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14107 it.face_id = compute_char_face (f, it.c, face);
14108
14109 /* Compute its width, get its glyphs. */
14110 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14111 SET_TEXT_POS (it.position, -1, -1);
14112 PRODUCE_GLYPHS (&it);
14113
14114 /* If this character doesn't fit any more in the line, we have
14115 to remove some glyphs. */
14116 if (it.current_x > it.last_visible_x)
14117 {
14118 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14119 break;
14120 }
14121 }
14122
14123 set_buffer_temp (old);
14124 return it.glyph_row;
14125 }
14126
14127
14128 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14129 glyphs are only inserted for terminal frames since we can't really
14130 win with truncation glyphs when partially visible glyphs are
14131 involved. Which glyphs to insert is determined by
14132 produce_special_glyphs. */
14133
14134 static void
14135 insert_left_trunc_glyphs (it)
14136 struct it *it;
14137 {
14138 struct it truncate_it;
14139 struct glyph *from, *end, *to, *toend;
14140
14141 xassert (!FRAME_WINDOW_P (it->f));
14142
14143 /* Get the truncation glyphs. */
14144 truncate_it = *it;
14145 truncate_it.current_x = 0;
14146 truncate_it.face_id = DEFAULT_FACE_ID;
14147 truncate_it.glyph_row = &scratch_glyph_row;
14148 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14149 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14150 truncate_it.object = make_number (0);
14151 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14152
14153 /* Overwrite glyphs from IT with truncation glyphs. */
14154 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14155 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14156 to = it->glyph_row->glyphs[TEXT_AREA];
14157 toend = to + it->glyph_row->used[TEXT_AREA];
14158
14159 while (from < end)
14160 *to++ = *from++;
14161
14162 /* There may be padding glyphs left over. Overwrite them too. */
14163 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14164 {
14165 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14166 while (from < end)
14167 *to++ = *from++;
14168 }
14169
14170 if (to > toend)
14171 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14172 }
14173
14174
14175 /* Compute the pixel height and width of IT->glyph_row.
14176
14177 Most of the time, ascent and height of a display line will be equal
14178 to the max_ascent and max_height values of the display iterator
14179 structure. This is not the case if
14180
14181 1. We hit ZV without displaying anything. In this case, max_ascent
14182 and max_height will be zero.
14183
14184 2. We have some glyphs that don't contribute to the line height.
14185 (The glyph row flag contributes_to_line_height_p is for future
14186 pixmap extensions).
14187
14188 The first case is easily covered by using default values because in
14189 these cases, the line height does not really matter, except that it
14190 must not be zero. */
14191
14192 static void
14193 compute_line_metrics (it)
14194 struct it *it;
14195 {
14196 struct glyph_row *row = it->glyph_row;
14197 int area, i;
14198
14199 if (FRAME_WINDOW_P (it->f))
14200 {
14201 int i, min_y, max_y;
14202
14203 /* The line may consist of one space only, that was added to
14204 place the cursor on it. If so, the row's height hasn't been
14205 computed yet. */
14206 if (row->height == 0)
14207 {
14208 if (it->max_ascent + it->max_descent == 0)
14209 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14210 row->ascent = it->max_ascent;
14211 row->height = it->max_ascent + it->max_descent;
14212 row->phys_ascent = it->max_phys_ascent;
14213 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14214 }
14215
14216 /* Compute the width of this line. */
14217 row->pixel_width = row->x;
14218 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14219 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14220
14221 xassert (row->pixel_width >= 0);
14222 xassert (row->ascent >= 0 && row->height > 0);
14223
14224 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14225 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14226
14227 /* If first line's physical ascent is larger than its logical
14228 ascent, use the physical ascent, and make the row taller.
14229 This makes accented characters fully visible. */
14230 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14231 && row->phys_ascent > row->ascent)
14232 {
14233 row->height += row->phys_ascent - row->ascent;
14234 row->ascent = row->phys_ascent;
14235 }
14236
14237 /* Compute how much of the line is visible. */
14238 row->visible_height = row->height;
14239
14240 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14241 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14242
14243 if (row->y < min_y)
14244 row->visible_height -= min_y - row->y;
14245 if (row->y + row->height > max_y)
14246 row->visible_height -= row->y + row->height - max_y;
14247 }
14248 else
14249 {
14250 row->pixel_width = row->used[TEXT_AREA];
14251 if (row->continued_p)
14252 row->pixel_width -= it->continuation_pixel_width;
14253 else if (row->truncated_on_right_p)
14254 row->pixel_width -= it->truncation_pixel_width;
14255 row->ascent = row->phys_ascent = 0;
14256 row->height = row->phys_height = row->visible_height = 1;
14257 }
14258
14259 /* Compute a hash code for this row. */
14260 row->hash = 0;
14261 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14262 for (i = 0; i < row->used[area]; ++i)
14263 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14264 + row->glyphs[area][i].u.val
14265 + row->glyphs[area][i].face_id
14266 + row->glyphs[area][i].padding_p
14267 + (row->glyphs[area][i].type << 2));
14268
14269 it->max_ascent = it->max_descent = 0;
14270 it->max_phys_ascent = it->max_phys_descent = 0;
14271 }
14272
14273
14274 /* Append one space to the glyph row of iterator IT if doing a
14275 window-based redisplay. The space has the same face as
14276 IT->face_id. Value is non-zero if a space was added.
14277
14278 This function is called to make sure that there is always one glyph
14279 at the end of a glyph row that the cursor can be set on under
14280 window-systems. (If there weren't such a glyph we would not know
14281 how wide and tall a box cursor should be displayed).
14282
14283 At the same time this space let's a nicely handle clearing to the
14284 end of the line if the row ends in italic text. */
14285
14286 static int
14287 append_space_for_newline (it, default_face_p)
14288 struct it *it;
14289 int default_face_p;
14290 {
14291 if (FRAME_WINDOW_P (it->f))
14292 {
14293 int n = it->glyph_row->used[TEXT_AREA];
14294
14295 if (it->glyph_row->glyphs[TEXT_AREA] + n
14296 < it->glyph_row->glyphs[1 + TEXT_AREA])
14297 {
14298 /* Save some values that must not be changed.
14299 Must save IT->c and IT->len because otherwise
14300 ITERATOR_AT_END_P wouldn't work anymore after
14301 append_space_for_newline has been called. */
14302 enum display_element_type saved_what = it->what;
14303 int saved_c = it->c, saved_len = it->len;
14304 int saved_x = it->current_x;
14305 int saved_face_id = it->face_id;
14306 struct text_pos saved_pos;
14307 Lisp_Object saved_object;
14308 struct face *face;
14309
14310 saved_object = it->object;
14311 saved_pos = it->position;
14312
14313 it->what = IT_CHARACTER;
14314 bzero (&it->position, sizeof it->position);
14315 it->object = make_number (0);
14316 it->c = ' ';
14317 it->len = 1;
14318
14319 if (default_face_p)
14320 it->face_id = DEFAULT_FACE_ID;
14321 else if (it->face_before_selective_p)
14322 it->face_id = it->saved_face_id;
14323 face = FACE_FROM_ID (it->f, it->face_id);
14324 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14325
14326 PRODUCE_GLYPHS (it);
14327
14328 it->override_ascent = -1;
14329 it->constrain_row_ascent_descent_p = 0;
14330 it->current_x = saved_x;
14331 it->object = saved_object;
14332 it->position = saved_pos;
14333 it->what = saved_what;
14334 it->face_id = saved_face_id;
14335 it->len = saved_len;
14336 it->c = saved_c;
14337 return 1;
14338 }
14339 }
14340
14341 return 0;
14342 }
14343
14344
14345 /* Extend the face of the last glyph in the text area of IT->glyph_row
14346 to the end of the display line. Called from display_line.
14347 If the glyph row is empty, add a space glyph to it so that we
14348 know the face to draw. Set the glyph row flag fill_line_p. */
14349
14350 static void
14351 extend_face_to_end_of_line (it)
14352 struct it *it;
14353 {
14354 struct face *face;
14355 struct frame *f = it->f;
14356
14357 /* If line is already filled, do nothing. */
14358 if (it->current_x >= it->last_visible_x)
14359 return;
14360
14361 /* Face extension extends the background and box of IT->face_id
14362 to the end of the line. If the background equals the background
14363 of the frame, we don't have to do anything. */
14364 if (it->face_before_selective_p)
14365 face = FACE_FROM_ID (it->f, it->saved_face_id);
14366 else
14367 face = FACE_FROM_ID (f, it->face_id);
14368
14369 if (FRAME_WINDOW_P (f)
14370 && face->box == FACE_NO_BOX
14371 && face->background == FRAME_BACKGROUND_PIXEL (f)
14372 && !face->stipple)
14373 return;
14374
14375 /* Set the glyph row flag indicating that the face of the last glyph
14376 in the text area has to be drawn to the end of the text area. */
14377 it->glyph_row->fill_line_p = 1;
14378
14379 /* If current character of IT is not ASCII, make sure we have the
14380 ASCII face. This will be automatically undone the next time
14381 get_next_display_element returns a multibyte character. Note
14382 that the character will always be single byte in unibyte text. */
14383 if (!SINGLE_BYTE_CHAR_P (it->c))
14384 {
14385 it->face_id = FACE_FOR_CHAR (f, face, 0);
14386 }
14387
14388 if (FRAME_WINDOW_P (f))
14389 {
14390 /* If the row is empty, add a space with the current face of IT,
14391 so that we know which face to draw. */
14392 if (it->glyph_row->used[TEXT_AREA] == 0)
14393 {
14394 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14395 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14396 it->glyph_row->used[TEXT_AREA] = 1;
14397 }
14398 }
14399 else
14400 {
14401 /* Save some values that must not be changed. */
14402 int saved_x = it->current_x;
14403 struct text_pos saved_pos;
14404 Lisp_Object saved_object;
14405 enum display_element_type saved_what = it->what;
14406 int saved_face_id = it->face_id;
14407
14408 saved_object = it->object;
14409 saved_pos = it->position;
14410
14411 it->what = IT_CHARACTER;
14412 bzero (&it->position, sizeof it->position);
14413 it->object = make_number (0);
14414 it->c = ' ';
14415 it->len = 1;
14416 it->face_id = face->id;
14417
14418 PRODUCE_GLYPHS (it);
14419
14420 while (it->current_x <= it->last_visible_x)
14421 PRODUCE_GLYPHS (it);
14422
14423 /* Don't count these blanks really. It would let us insert a left
14424 truncation glyph below and make us set the cursor on them, maybe. */
14425 it->current_x = saved_x;
14426 it->object = saved_object;
14427 it->position = saved_pos;
14428 it->what = saved_what;
14429 it->face_id = saved_face_id;
14430 }
14431 }
14432
14433
14434 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14435 trailing whitespace. */
14436
14437 static int
14438 trailing_whitespace_p (charpos)
14439 int charpos;
14440 {
14441 int bytepos = CHAR_TO_BYTE (charpos);
14442 int c = 0;
14443
14444 while (bytepos < ZV_BYTE
14445 && (c = FETCH_CHAR (bytepos),
14446 c == ' ' || c == '\t'))
14447 ++bytepos;
14448
14449 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14450 {
14451 if (bytepos != PT_BYTE)
14452 return 1;
14453 }
14454 return 0;
14455 }
14456
14457
14458 /* Highlight trailing whitespace, if any, in ROW. */
14459
14460 void
14461 highlight_trailing_whitespace (f, row)
14462 struct frame *f;
14463 struct glyph_row *row;
14464 {
14465 int used = row->used[TEXT_AREA];
14466
14467 if (used)
14468 {
14469 struct glyph *start = row->glyphs[TEXT_AREA];
14470 struct glyph *glyph = start + used - 1;
14471
14472 /* Skip over glyphs inserted to display the cursor at the
14473 end of a line, for extending the face of the last glyph
14474 to the end of the line on terminals, and for truncation
14475 and continuation glyphs. */
14476 while (glyph >= start
14477 && glyph->type == CHAR_GLYPH
14478 && INTEGERP (glyph->object))
14479 --glyph;
14480
14481 /* If last glyph is a space or stretch, and it's trailing
14482 whitespace, set the face of all trailing whitespace glyphs in
14483 IT->glyph_row to `trailing-whitespace'. */
14484 if (glyph >= start
14485 && BUFFERP (glyph->object)
14486 && (glyph->type == STRETCH_GLYPH
14487 || (glyph->type == CHAR_GLYPH
14488 && glyph->u.ch == ' '))
14489 && trailing_whitespace_p (glyph->charpos))
14490 {
14491 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14492
14493 while (glyph >= start
14494 && BUFFERP (glyph->object)
14495 && (glyph->type == STRETCH_GLYPH
14496 || (glyph->type == CHAR_GLYPH
14497 && glyph->u.ch == ' ')))
14498 (glyph--)->face_id = face_id;
14499 }
14500 }
14501 }
14502
14503
14504 /* Value is non-zero if glyph row ROW in window W should be
14505 used to hold the cursor. */
14506
14507 static int
14508 cursor_row_p (w, row)
14509 struct window *w;
14510 struct glyph_row *row;
14511 {
14512 int cursor_row_p = 1;
14513
14514 if (PT == MATRIX_ROW_END_CHARPOS (row))
14515 {
14516 /* If the row ends with a newline from a string, we don't want
14517 the cursor there (if the row is continued it doesn't end in a
14518 newline). */
14519 if (CHARPOS (row->end.string_pos) >= 0
14520 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14521 cursor_row_p = row->continued_p;
14522
14523 /* If the row ends at ZV, display the cursor at the end of that
14524 row instead of at the start of the row below. */
14525 else if (row->ends_at_zv_p)
14526 cursor_row_p = 1;
14527 else
14528 cursor_row_p = 0;
14529 }
14530
14531 return cursor_row_p;
14532 }
14533
14534
14535 /* Construct the glyph row IT->glyph_row in the desired matrix of
14536 IT->w from text at the current position of IT. See dispextern.h
14537 for an overview of struct it. Value is non-zero if
14538 IT->glyph_row displays text, as opposed to a line displaying ZV
14539 only. */
14540
14541 static int
14542 display_line (it)
14543 struct it *it;
14544 {
14545 struct glyph_row *row = it->glyph_row;
14546 int overlay_arrow_bitmap;
14547 Lisp_Object overlay_arrow_string;
14548
14549 /* We always start displaying at hpos zero even if hscrolled. */
14550 xassert (it->hpos == 0 && it->current_x == 0);
14551
14552 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14553 >= it->w->desired_matrix->nrows)
14554 {
14555 it->w->nrows_scale_factor++;
14556 fonts_changed_p = 1;
14557 return 0;
14558 }
14559
14560 /* Is IT->w showing the region? */
14561 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14562
14563 /* Clear the result glyph row and enable it. */
14564 prepare_desired_row (row);
14565
14566 row->y = it->current_y;
14567 row->start = it->start;
14568 row->continuation_lines_width = it->continuation_lines_width;
14569 row->displays_text_p = 1;
14570 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14571 it->starts_in_middle_of_char_p = 0;
14572
14573 /* Arrange the overlays nicely for our purposes. Usually, we call
14574 display_line on only one line at a time, in which case this
14575 can't really hurt too much, or we call it on lines which appear
14576 one after another in the buffer, in which case all calls to
14577 recenter_overlay_lists but the first will be pretty cheap. */
14578 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14579
14580 /* Move over display elements that are not visible because we are
14581 hscrolled. This may stop at an x-position < IT->first_visible_x
14582 if the first glyph is partially visible or if we hit a line end. */
14583 if (it->current_x < it->first_visible_x)
14584 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14585 MOVE_TO_POS | MOVE_TO_X);
14586
14587 /* Get the initial row height. This is either the height of the
14588 text hscrolled, if there is any, or zero. */
14589 row->ascent = it->max_ascent;
14590 row->height = it->max_ascent + it->max_descent;
14591 row->phys_ascent = it->max_phys_ascent;
14592 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14593
14594 /* Loop generating characters. The loop is left with IT on the next
14595 character to display. */
14596 while (1)
14597 {
14598 int n_glyphs_before, hpos_before, x_before;
14599 int x, i, nglyphs;
14600 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14601
14602 /* Retrieve the next thing to display. Value is zero if end of
14603 buffer reached. */
14604 if (!get_next_display_element (it))
14605 {
14606 /* Maybe add a space at the end of this line that is used to
14607 display the cursor there under X. Set the charpos of the
14608 first glyph of blank lines not corresponding to any text
14609 to -1. */
14610 #ifdef HAVE_WINDOW_SYSTEM
14611 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14612 row->exact_window_width_line_p = 1;
14613 else
14614 #endif /* HAVE_WINDOW_SYSTEM */
14615 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14616 || row->used[TEXT_AREA] == 0)
14617 {
14618 row->glyphs[TEXT_AREA]->charpos = -1;
14619 row->displays_text_p = 0;
14620
14621 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14622 && (!MINI_WINDOW_P (it->w)
14623 || (minibuf_level && EQ (it->window, minibuf_window))))
14624 row->indicate_empty_line_p = 1;
14625 }
14626
14627 it->continuation_lines_width = 0;
14628 row->ends_at_zv_p = 1;
14629 break;
14630 }
14631
14632 /* Now, get the metrics of what we want to display. This also
14633 generates glyphs in `row' (which is IT->glyph_row). */
14634 n_glyphs_before = row->used[TEXT_AREA];
14635 x = it->current_x;
14636
14637 /* Remember the line height so far in case the next element doesn't
14638 fit on the line. */
14639 if (!it->truncate_lines_p)
14640 {
14641 ascent = it->max_ascent;
14642 descent = it->max_descent;
14643 phys_ascent = it->max_phys_ascent;
14644 phys_descent = it->max_phys_descent;
14645 }
14646
14647 PRODUCE_GLYPHS (it);
14648
14649 /* If this display element was in marginal areas, continue with
14650 the next one. */
14651 if (it->area != TEXT_AREA)
14652 {
14653 row->ascent = max (row->ascent, it->max_ascent);
14654 row->height = max (row->height, it->max_ascent + it->max_descent);
14655 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14656 row->phys_height = max (row->phys_height,
14657 it->max_phys_ascent + it->max_phys_descent);
14658 set_iterator_to_next (it, 1);
14659 continue;
14660 }
14661
14662 /* Does the display element fit on the line? If we truncate
14663 lines, we should draw past the right edge of the window. If
14664 we don't truncate, we want to stop so that we can display the
14665 continuation glyph before the right margin. If lines are
14666 continued, there are two possible strategies for characters
14667 resulting in more than 1 glyph (e.g. tabs): Display as many
14668 glyphs as possible in this line and leave the rest for the
14669 continuation line, or display the whole element in the next
14670 line. Original redisplay did the former, so we do it also. */
14671 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14672 hpos_before = it->hpos;
14673 x_before = x;
14674
14675 if (/* Not a newline. */
14676 nglyphs > 0
14677 /* Glyphs produced fit entirely in the line. */
14678 && it->current_x < it->last_visible_x)
14679 {
14680 it->hpos += nglyphs;
14681 row->ascent = max (row->ascent, it->max_ascent);
14682 row->height = max (row->height, it->max_ascent + it->max_descent);
14683 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14684 row->phys_height = max (row->phys_height,
14685 it->max_phys_ascent + it->max_phys_descent);
14686 if (it->current_x - it->pixel_width < it->first_visible_x)
14687 row->x = x - it->first_visible_x;
14688 }
14689 else
14690 {
14691 int new_x;
14692 struct glyph *glyph;
14693
14694 for (i = 0; i < nglyphs; ++i, x = new_x)
14695 {
14696 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14697 new_x = x + glyph->pixel_width;
14698
14699 if (/* Lines are continued. */
14700 !it->truncate_lines_p
14701 && (/* Glyph doesn't fit on the line. */
14702 new_x > it->last_visible_x
14703 /* Or it fits exactly on a window system frame. */
14704 || (new_x == it->last_visible_x
14705 && FRAME_WINDOW_P (it->f))))
14706 {
14707 /* End of a continued line. */
14708
14709 if (it->hpos == 0
14710 || (new_x == it->last_visible_x
14711 && FRAME_WINDOW_P (it->f)))
14712 {
14713 /* Current glyph is the only one on the line or
14714 fits exactly on the line. We must continue
14715 the line because we can't draw the cursor
14716 after the glyph. */
14717 row->continued_p = 1;
14718 it->current_x = new_x;
14719 it->continuation_lines_width += new_x;
14720 ++it->hpos;
14721 if (i == nglyphs - 1)
14722 {
14723 set_iterator_to_next (it, 1);
14724 #ifdef HAVE_WINDOW_SYSTEM
14725 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14726 {
14727 if (!get_next_display_element (it))
14728 {
14729 row->exact_window_width_line_p = 1;
14730 it->continuation_lines_width = 0;
14731 row->continued_p = 0;
14732 row->ends_at_zv_p = 1;
14733 }
14734 else if (ITERATOR_AT_END_OF_LINE_P (it))
14735 {
14736 row->continued_p = 0;
14737 row->exact_window_width_line_p = 1;
14738 }
14739 }
14740 #endif /* HAVE_WINDOW_SYSTEM */
14741 }
14742 }
14743 else if (CHAR_GLYPH_PADDING_P (*glyph)
14744 && !FRAME_WINDOW_P (it->f))
14745 {
14746 /* A padding glyph that doesn't fit on this line.
14747 This means the whole character doesn't fit
14748 on the line. */
14749 row->used[TEXT_AREA] = n_glyphs_before;
14750
14751 /* Fill the rest of the row with continuation
14752 glyphs like in 20.x. */
14753 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14754 < row->glyphs[1 + TEXT_AREA])
14755 produce_special_glyphs (it, IT_CONTINUATION);
14756
14757 row->continued_p = 1;
14758 it->current_x = x_before;
14759 it->continuation_lines_width += x_before;
14760
14761 /* Restore the height to what it was before the
14762 element not fitting on the line. */
14763 it->max_ascent = ascent;
14764 it->max_descent = descent;
14765 it->max_phys_ascent = phys_ascent;
14766 it->max_phys_descent = phys_descent;
14767 }
14768 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14769 {
14770 /* A TAB that extends past the right edge of the
14771 window. This produces a single glyph on
14772 window system frames. We leave the glyph in
14773 this row and let it fill the row, but don't
14774 consume the TAB. */
14775 it->continuation_lines_width += it->last_visible_x;
14776 row->ends_in_middle_of_char_p = 1;
14777 row->continued_p = 1;
14778 glyph->pixel_width = it->last_visible_x - x;
14779 it->starts_in_middle_of_char_p = 1;
14780 }
14781 else
14782 {
14783 /* Something other than a TAB that draws past
14784 the right edge of the window. Restore
14785 positions to values before the element. */
14786 row->used[TEXT_AREA] = n_glyphs_before + i;
14787
14788 /* Display continuation glyphs. */
14789 if (!FRAME_WINDOW_P (it->f))
14790 produce_special_glyphs (it, IT_CONTINUATION);
14791 row->continued_p = 1;
14792
14793 it->continuation_lines_width += x;
14794
14795 if (nglyphs > 1 && i > 0)
14796 {
14797 row->ends_in_middle_of_char_p = 1;
14798 it->starts_in_middle_of_char_p = 1;
14799 }
14800
14801 /* Restore the height to what it was before the
14802 element not fitting on the line. */
14803 it->max_ascent = ascent;
14804 it->max_descent = descent;
14805 it->max_phys_ascent = phys_ascent;
14806 it->max_phys_descent = phys_descent;
14807 }
14808
14809 break;
14810 }
14811 else if (new_x > it->first_visible_x)
14812 {
14813 /* Increment number of glyphs actually displayed. */
14814 ++it->hpos;
14815
14816 if (x < it->first_visible_x)
14817 /* Glyph is partially visible, i.e. row starts at
14818 negative X position. */
14819 row->x = x - it->first_visible_x;
14820 }
14821 else
14822 {
14823 /* Glyph is completely off the left margin of the
14824 window. This should not happen because of the
14825 move_it_in_display_line at the start of this
14826 function, unless the text display area of the
14827 window is empty. */
14828 xassert (it->first_visible_x <= it->last_visible_x);
14829 }
14830 }
14831
14832 row->ascent = max (row->ascent, it->max_ascent);
14833 row->height = max (row->height, it->max_ascent + it->max_descent);
14834 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14835 row->phys_height = max (row->phys_height,
14836 it->max_phys_ascent + it->max_phys_descent);
14837
14838 /* End of this display line if row is continued. */
14839 if (row->continued_p || row->ends_at_zv_p)
14840 break;
14841 }
14842
14843 at_end_of_line:
14844 /* Is this a line end? If yes, we're also done, after making
14845 sure that a non-default face is extended up to the right
14846 margin of the window. */
14847 if (ITERATOR_AT_END_OF_LINE_P (it))
14848 {
14849 int used_before = row->used[TEXT_AREA];
14850
14851 row->ends_in_newline_from_string_p = STRINGP (it->object);
14852
14853 #ifdef HAVE_WINDOW_SYSTEM
14854 /* Add a space at the end of the line that is used to
14855 display the cursor there. */
14856 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14857 append_space_for_newline (it, 0);
14858 #endif /* HAVE_WINDOW_SYSTEM */
14859
14860 /* Extend the face to the end of the line. */
14861 extend_face_to_end_of_line (it);
14862
14863 /* Make sure we have the position. */
14864 if (used_before == 0)
14865 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14866
14867 /* Consume the line end. This skips over invisible lines. */
14868 set_iterator_to_next (it, 1);
14869 it->continuation_lines_width = 0;
14870 break;
14871 }
14872
14873 /* Proceed with next display element. Note that this skips
14874 over lines invisible because of selective display. */
14875 set_iterator_to_next (it, 1);
14876
14877 /* If we truncate lines, we are done when the last displayed
14878 glyphs reach past the right margin of the window. */
14879 if (it->truncate_lines_p
14880 && (FRAME_WINDOW_P (it->f)
14881 ? (it->current_x >= it->last_visible_x)
14882 : (it->current_x > it->last_visible_x)))
14883 {
14884 /* Maybe add truncation glyphs. */
14885 if (!FRAME_WINDOW_P (it->f))
14886 {
14887 int i, n;
14888
14889 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14890 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14891 break;
14892
14893 for (n = row->used[TEXT_AREA]; i < n; ++i)
14894 {
14895 row->used[TEXT_AREA] = i;
14896 produce_special_glyphs (it, IT_TRUNCATION);
14897 }
14898 }
14899 #ifdef HAVE_WINDOW_SYSTEM
14900 else
14901 {
14902 /* Don't truncate if we can overflow newline into fringe. */
14903 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14904 {
14905 if (!get_next_display_element (it))
14906 {
14907 #ifdef HAVE_WINDOW_SYSTEM
14908 it->continuation_lines_width = 0;
14909 row->ends_at_zv_p = 1;
14910 row->exact_window_width_line_p = 1;
14911 break;
14912 #endif /* HAVE_WINDOW_SYSTEM */
14913 }
14914 if (ITERATOR_AT_END_OF_LINE_P (it))
14915 {
14916 row->exact_window_width_line_p = 1;
14917 goto at_end_of_line;
14918 }
14919 }
14920 }
14921 #endif /* HAVE_WINDOW_SYSTEM */
14922
14923 row->truncated_on_right_p = 1;
14924 it->continuation_lines_width = 0;
14925 reseat_at_next_visible_line_start (it, 0);
14926 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14927 it->hpos = hpos_before;
14928 it->current_x = x_before;
14929 break;
14930 }
14931 }
14932
14933 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14934 at the left window margin. */
14935 if (it->first_visible_x
14936 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14937 {
14938 if (!FRAME_WINDOW_P (it->f))
14939 insert_left_trunc_glyphs (it);
14940 row->truncated_on_left_p = 1;
14941 }
14942
14943 /* If the start of this line is the overlay arrow-position, then
14944 mark this glyph row as the one containing the overlay arrow.
14945 This is clearly a mess with variable size fonts. It would be
14946 better to let it be displayed like cursors under X. */
14947 if (! overlay_arrow_seen
14948 && (overlay_arrow_string
14949 = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
14950 !NILP (overlay_arrow_string)))
14951 {
14952 /* Overlay arrow in window redisplay is a fringe bitmap. */
14953 if (!FRAME_WINDOW_P (it->f))
14954 {
14955 struct glyph_row *arrow_row
14956 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14957 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14958 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14959 struct glyph *p = row->glyphs[TEXT_AREA];
14960 struct glyph *p2, *end;
14961
14962 /* Copy the arrow glyphs. */
14963 while (glyph < arrow_end)
14964 *p++ = *glyph++;
14965
14966 /* Throw away padding glyphs. */
14967 p2 = p;
14968 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14969 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14970 ++p2;
14971 if (p2 > p)
14972 {
14973 while (p2 < end)
14974 *p++ = *p2++;
14975 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14976 }
14977 }
14978
14979 overlay_arrow_seen = 1;
14980 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
14981 row->overlay_arrow_p = 1;
14982 }
14983
14984 /* Compute pixel dimensions of this line. */
14985 compute_line_metrics (it);
14986
14987 /* Remember the position at which this line ends. */
14988 row->end = it->current;
14989
14990 /* Save fringe bitmaps in this row. */
14991 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14992 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14993 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14994 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14995
14996 it->left_user_fringe_bitmap = 0;
14997 it->left_user_fringe_face_id = 0;
14998 it->right_user_fringe_bitmap = 0;
14999 it->right_user_fringe_face_id = 0;
15000
15001 /* Maybe set the cursor. */
15002 if (it->w->cursor.vpos < 0
15003 && PT >= MATRIX_ROW_START_CHARPOS (row)
15004 && PT <= MATRIX_ROW_END_CHARPOS (row)
15005 && cursor_row_p (it->w, row))
15006 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15007
15008 /* Highlight trailing whitespace. */
15009 if (!NILP (Vshow_trailing_whitespace))
15010 highlight_trailing_whitespace (it->f, it->glyph_row);
15011
15012 /* Prepare for the next line. This line starts horizontally at (X
15013 HPOS) = (0 0). Vertical positions are incremented. As a
15014 convenience for the caller, IT->glyph_row is set to the next
15015 row to be used. */
15016 it->current_x = it->hpos = 0;
15017 it->current_y += row->height;
15018 ++it->vpos;
15019 ++it->glyph_row;
15020 it->start = it->current;
15021 return row->displays_text_p;
15022 }
15023
15024
15025 \f
15026 /***********************************************************************
15027 Menu Bar
15028 ***********************************************************************/
15029
15030 /* Redisplay the menu bar in the frame for window W.
15031
15032 The menu bar of X frames that don't have X toolkit support is
15033 displayed in a special window W->frame->menu_bar_window.
15034
15035 The menu bar of terminal frames is treated specially as far as
15036 glyph matrices are concerned. Menu bar lines are not part of
15037 windows, so the update is done directly on the frame matrix rows
15038 for the menu bar. */
15039
15040 static void
15041 display_menu_bar (w)
15042 struct window *w;
15043 {
15044 struct frame *f = XFRAME (WINDOW_FRAME (w));
15045 struct it it;
15046 Lisp_Object items;
15047 int i;
15048
15049 /* Don't do all this for graphical frames. */
15050 #ifdef HAVE_NTGUI
15051 if (!NILP (Vwindow_system))
15052 return;
15053 #endif
15054 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15055 if (FRAME_X_P (f))
15056 return;
15057 #endif
15058 #ifdef MAC_OS
15059 if (FRAME_MAC_P (f))
15060 return;
15061 #endif
15062
15063 #ifdef USE_X_TOOLKIT
15064 xassert (!FRAME_WINDOW_P (f));
15065 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15066 it.first_visible_x = 0;
15067 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15068 #else /* not USE_X_TOOLKIT */
15069 if (FRAME_WINDOW_P (f))
15070 {
15071 /* Menu bar lines are displayed in the desired matrix of the
15072 dummy window menu_bar_window. */
15073 struct window *menu_w;
15074 xassert (WINDOWP (f->menu_bar_window));
15075 menu_w = XWINDOW (f->menu_bar_window);
15076 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15077 MENU_FACE_ID);
15078 it.first_visible_x = 0;
15079 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15080 }
15081 else
15082 {
15083 /* This is a TTY frame, i.e. character hpos/vpos are used as
15084 pixel x/y. */
15085 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15086 MENU_FACE_ID);
15087 it.first_visible_x = 0;
15088 it.last_visible_x = FRAME_COLS (f);
15089 }
15090 #endif /* not USE_X_TOOLKIT */
15091
15092 if (! mode_line_inverse_video)
15093 /* Force the menu-bar to be displayed in the default face. */
15094 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15095
15096 /* Clear all rows of the menu bar. */
15097 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15098 {
15099 struct glyph_row *row = it.glyph_row + i;
15100 clear_glyph_row (row);
15101 row->enabled_p = 1;
15102 row->full_width_p = 1;
15103 }
15104
15105 /* Display all items of the menu bar. */
15106 items = FRAME_MENU_BAR_ITEMS (it.f);
15107 for (i = 0; i < XVECTOR (items)->size; i += 4)
15108 {
15109 Lisp_Object string;
15110
15111 /* Stop at nil string. */
15112 string = AREF (items, i + 1);
15113 if (NILP (string))
15114 break;
15115
15116 /* Remember where item was displayed. */
15117 AREF (items, i + 3) = make_number (it.hpos);
15118
15119 /* Display the item, pad with one space. */
15120 if (it.current_x < it.last_visible_x)
15121 display_string (NULL, string, Qnil, 0, 0, &it,
15122 SCHARS (string) + 1, 0, 0, -1);
15123 }
15124
15125 /* Fill out the line with spaces. */
15126 if (it.current_x < it.last_visible_x)
15127 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15128
15129 /* Compute the total height of the lines. */
15130 compute_line_metrics (&it);
15131 }
15132
15133
15134 \f
15135 /***********************************************************************
15136 Mode Line
15137 ***********************************************************************/
15138
15139 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15140 FORCE is non-zero, redisplay mode lines unconditionally.
15141 Otherwise, redisplay only mode lines that are garbaged. Value is
15142 the number of windows whose mode lines were redisplayed. */
15143
15144 static int
15145 redisplay_mode_lines (window, force)
15146 Lisp_Object window;
15147 int force;
15148 {
15149 int nwindows = 0;
15150
15151 while (!NILP (window))
15152 {
15153 struct window *w = XWINDOW (window);
15154
15155 if (WINDOWP (w->hchild))
15156 nwindows += redisplay_mode_lines (w->hchild, force);
15157 else if (WINDOWP (w->vchild))
15158 nwindows += redisplay_mode_lines (w->vchild, force);
15159 else if (force
15160 || FRAME_GARBAGED_P (XFRAME (w->frame))
15161 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15162 {
15163 struct text_pos lpoint;
15164 struct buffer *old = current_buffer;
15165
15166 /* Set the window's buffer for the mode line display. */
15167 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15168 set_buffer_internal_1 (XBUFFER (w->buffer));
15169
15170 /* Point refers normally to the selected window. For any
15171 other window, set up appropriate value. */
15172 if (!EQ (window, selected_window))
15173 {
15174 struct text_pos pt;
15175
15176 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15177 if (CHARPOS (pt) < BEGV)
15178 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15179 else if (CHARPOS (pt) > (ZV - 1))
15180 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15181 else
15182 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15183 }
15184
15185 /* Display mode lines. */
15186 clear_glyph_matrix (w->desired_matrix);
15187 if (display_mode_lines (w))
15188 {
15189 ++nwindows;
15190 w->must_be_updated_p = 1;
15191 }
15192
15193 /* Restore old settings. */
15194 set_buffer_internal_1 (old);
15195 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15196 }
15197
15198 window = w->next;
15199 }
15200
15201 return nwindows;
15202 }
15203
15204
15205 /* Display the mode and/or top line of window W. Value is the number
15206 of mode lines displayed. */
15207
15208 static int
15209 display_mode_lines (w)
15210 struct window *w;
15211 {
15212 Lisp_Object old_selected_window, old_selected_frame;
15213 int n = 0;
15214
15215 old_selected_frame = selected_frame;
15216 selected_frame = w->frame;
15217 old_selected_window = selected_window;
15218 XSETWINDOW (selected_window, w);
15219
15220 /* These will be set while the mode line specs are processed. */
15221 line_number_displayed = 0;
15222 w->column_number_displayed = Qnil;
15223
15224 if (WINDOW_WANTS_MODELINE_P (w))
15225 {
15226 struct window *sel_w = XWINDOW (old_selected_window);
15227
15228 /* Select mode line face based on the real selected window. */
15229 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15230 current_buffer->mode_line_format);
15231 ++n;
15232 }
15233
15234 if (WINDOW_WANTS_HEADER_LINE_P (w))
15235 {
15236 display_mode_line (w, HEADER_LINE_FACE_ID,
15237 current_buffer->header_line_format);
15238 ++n;
15239 }
15240
15241 selected_frame = old_selected_frame;
15242 selected_window = old_selected_window;
15243 return n;
15244 }
15245
15246
15247 /* Display mode or top line of window W. FACE_ID specifies which line
15248 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15249 FORMAT is the mode line format to display. Value is the pixel
15250 height of the mode line displayed. */
15251
15252 static int
15253 display_mode_line (w, face_id, format)
15254 struct window *w;
15255 enum face_id face_id;
15256 Lisp_Object format;
15257 {
15258 struct it it;
15259 struct face *face;
15260
15261 init_iterator (&it, w, -1, -1, NULL, face_id);
15262 prepare_desired_row (it.glyph_row);
15263
15264 it.glyph_row->mode_line_p = 1;
15265
15266 if (! mode_line_inverse_video)
15267 /* Force the mode-line to be displayed in the default face. */
15268 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15269
15270 /* Temporarily make frame's keyboard the current kboard so that
15271 kboard-local variables in the mode_line_format will get the right
15272 values. */
15273 push_frame_kboard (it.f);
15274 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15275 pop_frame_kboard ();
15276
15277 /* Fill up with spaces. */
15278 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15279
15280 compute_line_metrics (&it);
15281 it.glyph_row->full_width_p = 1;
15282 it.glyph_row->continued_p = 0;
15283 it.glyph_row->truncated_on_left_p = 0;
15284 it.glyph_row->truncated_on_right_p = 0;
15285
15286 /* Make a 3D mode-line have a shadow at its right end. */
15287 face = FACE_FROM_ID (it.f, face_id);
15288 extend_face_to_end_of_line (&it);
15289 if (face->box != FACE_NO_BOX)
15290 {
15291 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15292 + it.glyph_row->used[TEXT_AREA] - 1);
15293 last->right_box_line_p = 1;
15294 }
15295
15296 return it.glyph_row->height;
15297 }
15298
15299 /* Alist that caches the results of :propertize.
15300 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15301 Lisp_Object mode_line_proptrans_alist;
15302
15303 /* List of strings making up the mode-line. */
15304 Lisp_Object mode_line_string_list;
15305
15306 /* Base face property when building propertized mode line string. */
15307 static Lisp_Object mode_line_string_face;
15308 static Lisp_Object mode_line_string_face_prop;
15309
15310
15311 /* Contribute ELT to the mode line for window IT->w. How it
15312 translates into text depends on its data type.
15313
15314 IT describes the display environment in which we display, as usual.
15315
15316 DEPTH is the depth in recursion. It is used to prevent
15317 infinite recursion here.
15318
15319 FIELD_WIDTH is the number of characters the display of ELT should
15320 occupy in the mode line, and PRECISION is the maximum number of
15321 characters to display from ELT's representation. See
15322 display_string for details.
15323
15324 Returns the hpos of the end of the text generated by ELT.
15325
15326 PROPS is a property list to add to any string we encounter.
15327
15328 If RISKY is nonzero, remove (disregard) any properties in any string
15329 we encounter, and ignore :eval and :propertize.
15330
15331 If the global variable `frame_title_ptr' is non-NULL, then the output
15332 is passed to `store_frame_title' instead of `display_string'. */
15333
15334 static int
15335 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15336 struct it *it;
15337 int depth;
15338 int field_width, precision;
15339 Lisp_Object elt, props;
15340 int risky;
15341 {
15342 int n = 0, field, prec;
15343 int literal = 0;
15344
15345 tail_recurse:
15346 if (depth > 100)
15347 elt = build_string ("*too-deep*");
15348
15349 depth++;
15350
15351 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15352 {
15353 case Lisp_String:
15354 {
15355 /* A string: output it and check for %-constructs within it. */
15356 unsigned char c;
15357 const unsigned char *this, *lisp_string;
15358
15359 if (!NILP (props) || risky)
15360 {
15361 Lisp_Object oprops, aelt;
15362 oprops = Ftext_properties_at (make_number (0), elt);
15363
15364 /* If the starting string's properties are not what
15365 we want, translate the string. Also, if the string
15366 is risky, do that anyway. */
15367
15368 if (NILP (Fequal (props, oprops)) || risky)
15369 {
15370 /* If the starting string has properties,
15371 merge the specified ones onto the existing ones. */
15372 if (! NILP (oprops) && !risky)
15373 {
15374 Lisp_Object tem;
15375
15376 oprops = Fcopy_sequence (oprops);
15377 tem = props;
15378 while (CONSP (tem))
15379 {
15380 oprops = Fplist_put (oprops, XCAR (tem),
15381 XCAR (XCDR (tem)));
15382 tem = XCDR (XCDR (tem));
15383 }
15384 props = oprops;
15385 }
15386
15387 aelt = Fassoc (elt, mode_line_proptrans_alist);
15388 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15389 {
15390 mode_line_proptrans_alist
15391 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15392 elt = XCAR (aelt);
15393 }
15394 else
15395 {
15396 Lisp_Object tem;
15397
15398 elt = Fcopy_sequence (elt);
15399 Fset_text_properties (make_number (0), Flength (elt),
15400 props, elt);
15401 /* Add this item to mode_line_proptrans_alist. */
15402 mode_line_proptrans_alist
15403 = Fcons (Fcons (elt, props),
15404 mode_line_proptrans_alist);
15405 /* Truncate mode_line_proptrans_alist
15406 to at most 50 elements. */
15407 tem = Fnthcdr (make_number (50),
15408 mode_line_proptrans_alist);
15409 if (! NILP (tem))
15410 XSETCDR (tem, Qnil);
15411 }
15412 }
15413 }
15414
15415 this = SDATA (elt);
15416 lisp_string = this;
15417
15418 if (literal)
15419 {
15420 prec = precision - n;
15421 if (frame_title_ptr)
15422 n += store_frame_title (SDATA (elt), -1, prec);
15423 else if (!NILP (mode_line_string_list))
15424 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15425 else
15426 n += display_string (NULL, elt, Qnil, 0, 0, it,
15427 0, prec, 0, STRING_MULTIBYTE (elt));
15428
15429 break;
15430 }
15431
15432 while ((precision <= 0 || n < precision)
15433 && *this
15434 && (frame_title_ptr
15435 || !NILP (mode_line_string_list)
15436 || it->current_x < it->last_visible_x))
15437 {
15438 const unsigned char *last = this;
15439
15440 /* Advance to end of string or next format specifier. */
15441 while ((c = *this++) != '\0' && c != '%')
15442 ;
15443
15444 if (this - 1 != last)
15445 {
15446 /* Output to end of string or up to '%'. Field width
15447 is length of string. Don't output more than
15448 PRECISION allows us. */
15449 --this;
15450
15451 prec = chars_in_text (last, this - last);
15452 if (precision > 0 && prec > precision - n)
15453 prec = precision - n;
15454
15455 if (frame_title_ptr)
15456 n += store_frame_title (last, 0, prec);
15457 else if (!NILP (mode_line_string_list))
15458 {
15459 int bytepos = last - lisp_string;
15460 int charpos = string_byte_to_char (elt, bytepos);
15461 n += store_mode_line_string (NULL,
15462 Fsubstring (elt, make_number (charpos),
15463 make_number (charpos + prec)),
15464 0, 0, 0, Qnil);
15465 }
15466 else
15467 {
15468 int bytepos = last - lisp_string;
15469 int charpos = string_byte_to_char (elt, bytepos);
15470 n += display_string (NULL, elt, Qnil, 0, charpos,
15471 it, 0, prec, 0,
15472 STRING_MULTIBYTE (elt));
15473 }
15474 }
15475 else /* c == '%' */
15476 {
15477 const unsigned char *percent_position = this;
15478
15479 /* Get the specified minimum width. Zero means
15480 don't pad. */
15481 field = 0;
15482 while ((c = *this++) >= '0' && c <= '9')
15483 field = field * 10 + c - '0';
15484
15485 /* Don't pad beyond the total padding allowed. */
15486 if (field_width - n > 0 && field > field_width - n)
15487 field = field_width - n;
15488
15489 /* Note that either PRECISION <= 0 or N < PRECISION. */
15490 prec = precision - n;
15491
15492 if (c == 'M')
15493 n += display_mode_element (it, depth, field, prec,
15494 Vglobal_mode_string, props,
15495 risky);
15496 else if (c != 0)
15497 {
15498 int multibyte;
15499 int bytepos, charpos;
15500 unsigned char *spec;
15501
15502 bytepos = percent_position - lisp_string;
15503 charpos = (STRING_MULTIBYTE (elt)
15504 ? string_byte_to_char (elt, bytepos)
15505 : bytepos);
15506
15507 spec
15508 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15509
15510 if (frame_title_ptr)
15511 n += store_frame_title (spec, field, prec);
15512 else if (!NILP (mode_line_string_list))
15513 {
15514 int len = strlen (spec);
15515 Lisp_Object tem = make_string (spec, len);
15516 props = Ftext_properties_at (make_number (charpos), elt);
15517 /* Should only keep face property in props */
15518 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15519 }
15520 else
15521 {
15522 int nglyphs_before, nwritten;
15523
15524 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15525 nwritten = display_string (spec, Qnil, elt,
15526 charpos, 0, it,
15527 field, prec, 0,
15528 multibyte);
15529
15530 /* Assign to the glyphs written above the
15531 string where the `%x' came from, position
15532 of the `%'. */
15533 if (nwritten > 0)
15534 {
15535 struct glyph *glyph
15536 = (it->glyph_row->glyphs[TEXT_AREA]
15537 + nglyphs_before);
15538 int i;
15539
15540 for (i = 0; i < nwritten; ++i)
15541 {
15542 glyph[i].object = elt;
15543 glyph[i].charpos = charpos;
15544 }
15545
15546 n += nwritten;
15547 }
15548 }
15549 }
15550 else /* c == 0 */
15551 break;
15552 }
15553 }
15554 }
15555 break;
15556
15557 case Lisp_Symbol:
15558 /* A symbol: process the value of the symbol recursively
15559 as if it appeared here directly. Avoid error if symbol void.
15560 Special case: if value of symbol is a string, output the string
15561 literally. */
15562 {
15563 register Lisp_Object tem;
15564
15565 /* If the variable is not marked as risky to set
15566 then its contents are risky to use. */
15567 if (NILP (Fget (elt, Qrisky_local_variable)))
15568 risky = 1;
15569
15570 tem = Fboundp (elt);
15571 if (!NILP (tem))
15572 {
15573 tem = Fsymbol_value (elt);
15574 /* If value is a string, output that string literally:
15575 don't check for % within it. */
15576 if (STRINGP (tem))
15577 literal = 1;
15578
15579 if (!EQ (tem, elt))
15580 {
15581 /* Give up right away for nil or t. */
15582 elt = tem;
15583 goto tail_recurse;
15584 }
15585 }
15586 }
15587 break;
15588
15589 case Lisp_Cons:
15590 {
15591 register Lisp_Object car, tem;
15592
15593 /* A cons cell: five distinct cases.
15594 If first element is :eval or :propertize, do something special.
15595 If first element is a string or a cons, process all the elements
15596 and effectively concatenate them.
15597 If first element is a negative number, truncate displaying cdr to
15598 at most that many characters. If positive, pad (with spaces)
15599 to at least that many characters.
15600 If first element is a symbol, process the cadr or caddr recursively
15601 according to whether the symbol's value is non-nil or nil. */
15602 car = XCAR (elt);
15603 if (EQ (car, QCeval))
15604 {
15605 /* An element of the form (:eval FORM) means evaluate FORM
15606 and use the result as mode line elements. */
15607
15608 if (risky)
15609 break;
15610
15611 if (CONSP (XCDR (elt)))
15612 {
15613 Lisp_Object spec;
15614 spec = safe_eval (XCAR (XCDR (elt)));
15615 n += display_mode_element (it, depth, field_width - n,
15616 precision - n, spec, props,
15617 risky);
15618 }
15619 }
15620 else if (EQ (car, QCpropertize))
15621 {
15622 /* An element of the form (:propertize ELT PROPS...)
15623 means display ELT but applying properties PROPS. */
15624
15625 if (risky)
15626 break;
15627
15628 if (CONSP (XCDR (elt)))
15629 n += display_mode_element (it, depth, field_width - n,
15630 precision - n, XCAR (XCDR (elt)),
15631 XCDR (XCDR (elt)), risky);
15632 }
15633 else if (SYMBOLP (car))
15634 {
15635 tem = Fboundp (car);
15636 elt = XCDR (elt);
15637 if (!CONSP (elt))
15638 goto invalid;
15639 /* elt is now the cdr, and we know it is a cons cell.
15640 Use its car if CAR has a non-nil value. */
15641 if (!NILP (tem))
15642 {
15643 tem = Fsymbol_value (car);
15644 if (!NILP (tem))
15645 {
15646 elt = XCAR (elt);
15647 goto tail_recurse;
15648 }
15649 }
15650 /* Symbol's value is nil (or symbol is unbound)
15651 Get the cddr of the original list
15652 and if possible find the caddr and use that. */
15653 elt = XCDR (elt);
15654 if (NILP (elt))
15655 break;
15656 else if (!CONSP (elt))
15657 goto invalid;
15658 elt = XCAR (elt);
15659 goto tail_recurse;
15660 }
15661 else if (INTEGERP (car))
15662 {
15663 register int lim = XINT (car);
15664 elt = XCDR (elt);
15665 if (lim < 0)
15666 {
15667 /* Negative int means reduce maximum width. */
15668 if (precision <= 0)
15669 precision = -lim;
15670 else
15671 precision = min (precision, -lim);
15672 }
15673 else if (lim > 0)
15674 {
15675 /* Padding specified. Don't let it be more than
15676 current maximum. */
15677 if (precision > 0)
15678 lim = min (precision, lim);
15679
15680 /* If that's more padding than already wanted, queue it.
15681 But don't reduce padding already specified even if
15682 that is beyond the current truncation point. */
15683 field_width = max (lim, field_width);
15684 }
15685 goto tail_recurse;
15686 }
15687 else if (STRINGP (car) || CONSP (car))
15688 {
15689 register int limit = 50;
15690 /* Limit is to protect against circular lists. */
15691 while (CONSP (elt)
15692 && --limit > 0
15693 && (precision <= 0 || n < precision))
15694 {
15695 n += display_mode_element (it, depth, field_width - n,
15696 precision - n, XCAR (elt),
15697 props, risky);
15698 elt = XCDR (elt);
15699 }
15700 }
15701 }
15702 break;
15703
15704 default:
15705 invalid:
15706 elt = build_string ("*invalid*");
15707 goto tail_recurse;
15708 }
15709
15710 /* Pad to FIELD_WIDTH. */
15711 if (field_width > 0 && n < field_width)
15712 {
15713 if (frame_title_ptr)
15714 n += store_frame_title ("", field_width - n, 0);
15715 else if (!NILP (mode_line_string_list))
15716 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15717 else
15718 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15719 0, 0, 0);
15720 }
15721
15722 return n;
15723 }
15724
15725 /* Store a mode-line string element in mode_line_string_list.
15726
15727 If STRING is non-null, display that C string. Otherwise, the Lisp
15728 string LISP_STRING is displayed.
15729
15730 FIELD_WIDTH is the minimum number of output glyphs to produce.
15731 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15732 with spaces. FIELD_WIDTH <= 0 means don't pad.
15733
15734 PRECISION is the maximum number of characters to output from
15735 STRING. PRECISION <= 0 means don't truncate the string.
15736
15737 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15738 properties to the string.
15739
15740 PROPS are the properties to add to the string.
15741 The mode_line_string_face face property is always added to the string.
15742 */
15743
15744 static int
15745 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15746 char *string;
15747 Lisp_Object lisp_string;
15748 int copy_string;
15749 int field_width;
15750 int precision;
15751 Lisp_Object props;
15752 {
15753 int len;
15754 int n = 0;
15755
15756 if (string != NULL)
15757 {
15758 len = strlen (string);
15759 if (precision > 0 && len > precision)
15760 len = precision;
15761 lisp_string = make_string (string, len);
15762 if (NILP (props))
15763 props = mode_line_string_face_prop;
15764 else if (!NILP (mode_line_string_face))
15765 {
15766 Lisp_Object face = Fplist_get (props, Qface);
15767 props = Fcopy_sequence (props);
15768 if (NILP (face))
15769 face = mode_line_string_face;
15770 else
15771 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15772 props = Fplist_put (props, Qface, face);
15773 }
15774 Fadd_text_properties (make_number (0), make_number (len),
15775 props, lisp_string);
15776 }
15777 else
15778 {
15779 len = XFASTINT (Flength (lisp_string));
15780 if (precision > 0 && len > precision)
15781 {
15782 len = precision;
15783 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15784 precision = -1;
15785 }
15786 if (!NILP (mode_line_string_face))
15787 {
15788 Lisp_Object face;
15789 if (NILP (props))
15790 props = Ftext_properties_at (make_number (0), lisp_string);
15791 face = Fplist_get (props, Qface);
15792 if (NILP (face))
15793 face = mode_line_string_face;
15794 else
15795 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15796 props = Fcons (Qface, Fcons (face, Qnil));
15797 if (copy_string)
15798 lisp_string = Fcopy_sequence (lisp_string);
15799 }
15800 if (!NILP (props))
15801 Fadd_text_properties (make_number (0), make_number (len),
15802 props, lisp_string);
15803 }
15804
15805 if (len > 0)
15806 {
15807 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15808 n += len;
15809 }
15810
15811 if (field_width > len)
15812 {
15813 field_width -= len;
15814 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15815 if (!NILP (props))
15816 Fadd_text_properties (make_number (0), make_number (field_width),
15817 props, lisp_string);
15818 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15819 n += field_width;
15820 }
15821
15822 return n;
15823 }
15824
15825
15826 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15827 0, 4, 0,
15828 doc: /* Return the mode-line of selected window as a string.
15829 First optional arg FORMAT specifies a different format string (see
15830 `mode-line-format' for details) to use. If FORMAT is t, return
15831 the buffer's header-line. Second optional arg WINDOW specifies a
15832 different window to use as the context for the formatting.
15833 If third optional arg NO-PROPS is non-nil, string is not propertized.
15834 Fourth optional arg BUFFER specifies which buffer to use. */)
15835 (format, window, no_props, buffer)
15836 Lisp_Object format, window, no_props, buffer;
15837 {
15838 struct it it;
15839 int len;
15840 struct window *w;
15841 struct buffer *old_buffer = NULL;
15842 enum face_id face_id = DEFAULT_FACE_ID;
15843
15844 if (NILP (window))
15845 window = selected_window;
15846 CHECK_WINDOW (window);
15847 w = XWINDOW (window);
15848
15849 if (NILP (buffer))
15850 buffer = w->buffer;
15851
15852 CHECK_BUFFER (buffer);
15853
15854 if (XBUFFER (buffer) != current_buffer)
15855 {
15856 old_buffer = current_buffer;
15857 set_buffer_internal_1 (XBUFFER (buffer));
15858 }
15859
15860 if (NILP (format) || EQ (format, Qt))
15861 {
15862 face_id = (NILP (format)
15863 ? CURRENT_MODE_LINE_FACE_ID (w)
15864 : HEADER_LINE_FACE_ID);
15865 format = (NILP (format)
15866 ? current_buffer->mode_line_format
15867 : current_buffer->header_line_format);
15868 }
15869
15870 init_iterator (&it, w, -1, -1, NULL, face_id);
15871
15872 if (NILP (no_props))
15873 {
15874 mode_line_string_face
15875 = (face_id == MODE_LINE_FACE_ID ? Qmode_line
15876 : face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive
15877 : face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15878
15879 mode_line_string_face_prop
15880 = (NILP (mode_line_string_face) ? Qnil
15881 : Fcons (Qface, Fcons (mode_line_string_face, Qnil)));
15882
15883 /* We need a dummy last element in mode_line_string_list to
15884 indicate we are building the propertized mode-line string.
15885 Using mode_line_string_face_prop here GC protects it. */
15886 mode_line_string_list
15887 = Fcons (mode_line_string_face_prop, Qnil);
15888 frame_title_ptr = NULL;
15889 }
15890 else
15891 {
15892 mode_line_string_face_prop = Qnil;
15893 mode_line_string_list = Qnil;
15894 frame_title_ptr = frame_title_buf;
15895 }
15896
15897 push_frame_kboard (it.f);
15898 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15899 pop_frame_kboard ();
15900
15901 if (old_buffer)
15902 set_buffer_internal_1 (old_buffer);
15903
15904 if (NILP (no_props))
15905 {
15906 Lisp_Object str;
15907 mode_line_string_list = Fnreverse (mode_line_string_list);
15908 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15909 make_string ("", 0));
15910 mode_line_string_face_prop = Qnil;
15911 mode_line_string_list = Qnil;
15912 return str;
15913 }
15914
15915 len = frame_title_ptr - frame_title_buf;
15916 if (len > 0 && frame_title_ptr[-1] == '-')
15917 {
15918 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15919 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15920 ;
15921 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15922 if (len > frame_title_ptr - frame_title_buf)
15923 len = frame_title_ptr - frame_title_buf;
15924 }
15925
15926 frame_title_ptr = NULL;
15927 return make_string (frame_title_buf, len);
15928 }
15929
15930 /* Write a null-terminated, right justified decimal representation of
15931 the positive integer D to BUF using a minimal field width WIDTH. */
15932
15933 static void
15934 pint2str (buf, width, d)
15935 register char *buf;
15936 register int width;
15937 register int d;
15938 {
15939 register char *p = buf;
15940
15941 if (d <= 0)
15942 *p++ = '0';
15943 else
15944 {
15945 while (d > 0)
15946 {
15947 *p++ = d % 10 + '0';
15948 d /= 10;
15949 }
15950 }
15951
15952 for (width -= (int) (p - buf); width > 0; --width)
15953 *p++ = ' ';
15954 *p-- = '\0';
15955 while (p > buf)
15956 {
15957 d = *buf;
15958 *buf++ = *p;
15959 *p-- = d;
15960 }
15961 }
15962
15963 /* Write a null-terminated, right justified decimal and "human
15964 readable" representation of the nonnegative integer D to BUF using
15965 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15966
15967 static const char power_letter[] =
15968 {
15969 0, /* not used */
15970 'k', /* kilo */
15971 'M', /* mega */
15972 'G', /* giga */
15973 'T', /* tera */
15974 'P', /* peta */
15975 'E', /* exa */
15976 'Z', /* zetta */
15977 'Y' /* yotta */
15978 };
15979
15980 static void
15981 pint2hrstr (buf, width, d)
15982 char *buf;
15983 int width;
15984 int d;
15985 {
15986 /* We aim to represent the nonnegative integer D as
15987 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15988 int quotient = d;
15989 int remainder = 0;
15990 /* -1 means: do not use TENTHS. */
15991 int tenths = -1;
15992 int exponent = 0;
15993
15994 /* Length of QUOTIENT.TENTHS as a string. */
15995 int length;
15996
15997 char * psuffix;
15998 char * p;
15999
16000 if (1000 <= quotient)
16001 {
16002 /* Scale to the appropriate EXPONENT. */
16003 do
16004 {
16005 remainder = quotient % 1000;
16006 quotient /= 1000;
16007 exponent++;
16008 }
16009 while (1000 <= quotient);
16010
16011 /* Round to nearest and decide whether to use TENTHS or not. */
16012 if (quotient <= 9)
16013 {
16014 tenths = remainder / 100;
16015 if (50 <= remainder % 100)
16016 if (tenths < 9)
16017 tenths++;
16018 else
16019 {
16020 quotient++;
16021 if (quotient == 10)
16022 tenths = -1;
16023 else
16024 tenths = 0;
16025 }
16026 }
16027 else
16028 if (500 <= remainder)
16029 if (quotient < 999)
16030 quotient++;
16031 else
16032 {
16033 quotient = 1;
16034 exponent++;
16035 tenths = 0;
16036 }
16037 }
16038
16039 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16040 if (tenths == -1 && quotient <= 99)
16041 if (quotient <= 9)
16042 length = 1;
16043 else
16044 length = 2;
16045 else
16046 length = 3;
16047 p = psuffix = buf + max (width, length);
16048
16049 /* Print EXPONENT. */
16050 if (exponent)
16051 *psuffix++ = power_letter[exponent];
16052 *psuffix = '\0';
16053
16054 /* Print TENTHS. */
16055 if (tenths >= 0)
16056 {
16057 *--p = '0' + tenths;
16058 *--p = '.';
16059 }
16060
16061 /* Print QUOTIENT. */
16062 do
16063 {
16064 int digit = quotient % 10;
16065 *--p = '0' + digit;
16066 }
16067 while ((quotient /= 10) != 0);
16068
16069 /* Print leading spaces. */
16070 while (buf < p)
16071 *--p = ' ';
16072 }
16073
16074 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16075 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16076 type of CODING_SYSTEM. Return updated pointer into BUF. */
16077
16078 static unsigned char invalid_eol_type[] = "(*invalid*)";
16079
16080 static char *
16081 decode_mode_spec_coding (coding_system, buf, eol_flag)
16082 Lisp_Object coding_system;
16083 register char *buf;
16084 int eol_flag;
16085 {
16086 Lisp_Object val;
16087 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16088 const unsigned char *eol_str;
16089 int eol_str_len;
16090 /* The EOL conversion we are using. */
16091 Lisp_Object eoltype;
16092
16093 val = Fget (coding_system, Qcoding_system);
16094 eoltype = Qnil;
16095
16096 if (!VECTORP (val)) /* Not yet decided. */
16097 {
16098 if (multibyte)
16099 *buf++ = '-';
16100 if (eol_flag)
16101 eoltype = eol_mnemonic_undecided;
16102 /* Don't mention EOL conversion if it isn't decided. */
16103 }
16104 else
16105 {
16106 Lisp_Object eolvalue;
16107
16108 eolvalue = Fget (coding_system, Qeol_type);
16109
16110 if (multibyte)
16111 *buf++ = XFASTINT (AREF (val, 1));
16112
16113 if (eol_flag)
16114 {
16115 /* The EOL conversion that is normal on this system. */
16116
16117 if (NILP (eolvalue)) /* Not yet decided. */
16118 eoltype = eol_mnemonic_undecided;
16119 else if (VECTORP (eolvalue)) /* Not yet decided. */
16120 eoltype = eol_mnemonic_undecided;
16121 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16122 eoltype = (XFASTINT (eolvalue) == 0
16123 ? eol_mnemonic_unix
16124 : (XFASTINT (eolvalue) == 1
16125 ? eol_mnemonic_dos : eol_mnemonic_mac));
16126 }
16127 }
16128
16129 if (eol_flag)
16130 {
16131 /* Mention the EOL conversion if it is not the usual one. */
16132 if (STRINGP (eoltype))
16133 {
16134 eol_str = SDATA (eoltype);
16135 eol_str_len = SBYTES (eoltype);
16136 }
16137 else if (INTEGERP (eoltype)
16138 && CHAR_VALID_P (XINT (eoltype), 0))
16139 {
16140 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16141 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16142 eol_str = tmp;
16143 }
16144 else
16145 {
16146 eol_str = invalid_eol_type;
16147 eol_str_len = sizeof (invalid_eol_type) - 1;
16148 }
16149 bcopy (eol_str, buf, eol_str_len);
16150 buf += eol_str_len;
16151 }
16152
16153 return buf;
16154 }
16155
16156 /* Return a string for the output of a mode line %-spec for window W,
16157 generated by character C. PRECISION >= 0 means don't return a
16158 string longer than that value. FIELD_WIDTH > 0 means pad the
16159 string returned with spaces to that value. Return 1 in *MULTIBYTE
16160 if the result is multibyte text.
16161
16162 Note we operate on the current buffer for most purposes,
16163 the exception being w->base_line_pos. */
16164
16165 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16166
16167 static char *
16168 decode_mode_spec (w, c, field_width, precision, multibyte)
16169 struct window *w;
16170 register int c;
16171 int field_width, precision;
16172 int *multibyte;
16173 {
16174 Lisp_Object obj;
16175 struct frame *f = XFRAME (WINDOW_FRAME (w));
16176 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16177 struct buffer *b = current_buffer;
16178
16179 obj = Qnil;
16180 *multibyte = 0;
16181
16182 switch (c)
16183 {
16184 case '*':
16185 if (!NILP (b->read_only))
16186 return "%";
16187 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16188 return "*";
16189 return "-";
16190
16191 case '+':
16192 /* This differs from %* only for a modified read-only buffer. */
16193 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16194 return "*";
16195 if (!NILP (b->read_only))
16196 return "%";
16197 return "-";
16198
16199 case '&':
16200 /* This differs from %* in ignoring read-only-ness. */
16201 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16202 return "*";
16203 return "-";
16204
16205 case '%':
16206 return "%";
16207
16208 case '[':
16209 {
16210 int i;
16211 char *p;
16212
16213 if (command_loop_level > 5)
16214 return "[[[... ";
16215 p = decode_mode_spec_buf;
16216 for (i = 0; i < command_loop_level; i++)
16217 *p++ = '[';
16218 *p = 0;
16219 return decode_mode_spec_buf;
16220 }
16221
16222 case ']':
16223 {
16224 int i;
16225 char *p;
16226
16227 if (command_loop_level > 5)
16228 return " ...]]]";
16229 p = decode_mode_spec_buf;
16230 for (i = 0; i < command_loop_level; i++)
16231 *p++ = ']';
16232 *p = 0;
16233 return decode_mode_spec_buf;
16234 }
16235
16236 case '-':
16237 {
16238 register int i;
16239
16240 /* Let lots_of_dashes be a string of infinite length. */
16241 if (!NILP (mode_line_string_list))
16242 return "--";
16243 if (field_width <= 0
16244 || field_width > sizeof (lots_of_dashes))
16245 {
16246 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16247 decode_mode_spec_buf[i] = '-';
16248 decode_mode_spec_buf[i] = '\0';
16249 return decode_mode_spec_buf;
16250 }
16251 else
16252 return lots_of_dashes;
16253 }
16254
16255 case 'b':
16256 obj = b->name;
16257 break;
16258
16259 case 'c':
16260 {
16261 int col = (int) current_column (); /* iftc */
16262 w->column_number_displayed = make_number (col);
16263 pint2str (decode_mode_spec_buf, field_width, col);
16264 return decode_mode_spec_buf;
16265 }
16266
16267 case 'F':
16268 /* %F displays the frame name. */
16269 if (!NILP (f->title))
16270 return (char *) SDATA (f->title);
16271 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16272 return (char *) SDATA (f->name);
16273 return "Emacs";
16274
16275 case 'f':
16276 obj = b->filename;
16277 break;
16278
16279 case 'i':
16280 {
16281 int size = ZV - BEGV;
16282 pint2str (decode_mode_spec_buf, field_width, size);
16283 return decode_mode_spec_buf;
16284 }
16285
16286 case 'I':
16287 {
16288 int size = ZV - BEGV;
16289 pint2hrstr (decode_mode_spec_buf, field_width, size);
16290 return decode_mode_spec_buf;
16291 }
16292
16293 case 'l':
16294 {
16295 int startpos = XMARKER (w->start)->charpos;
16296 int startpos_byte = marker_byte_position (w->start);
16297 int line, linepos, linepos_byte, topline;
16298 int nlines, junk;
16299 int height = WINDOW_TOTAL_LINES (w);
16300
16301 /* If we decided that this buffer isn't suitable for line numbers,
16302 don't forget that too fast. */
16303 if (EQ (w->base_line_pos, w->buffer))
16304 goto no_value;
16305 /* But do forget it, if the window shows a different buffer now. */
16306 else if (BUFFERP (w->base_line_pos))
16307 w->base_line_pos = Qnil;
16308
16309 /* If the buffer is very big, don't waste time. */
16310 if (INTEGERP (Vline_number_display_limit)
16311 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16312 {
16313 w->base_line_pos = Qnil;
16314 w->base_line_number = Qnil;
16315 goto no_value;
16316 }
16317
16318 if (!NILP (w->base_line_number)
16319 && !NILP (w->base_line_pos)
16320 && XFASTINT (w->base_line_pos) <= startpos)
16321 {
16322 line = XFASTINT (w->base_line_number);
16323 linepos = XFASTINT (w->base_line_pos);
16324 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16325 }
16326 else
16327 {
16328 line = 1;
16329 linepos = BUF_BEGV (b);
16330 linepos_byte = BUF_BEGV_BYTE (b);
16331 }
16332
16333 /* Count lines from base line to window start position. */
16334 nlines = display_count_lines (linepos, linepos_byte,
16335 startpos_byte,
16336 startpos, &junk);
16337
16338 topline = nlines + line;
16339
16340 /* Determine a new base line, if the old one is too close
16341 or too far away, or if we did not have one.
16342 "Too close" means it's plausible a scroll-down would
16343 go back past it. */
16344 if (startpos == BUF_BEGV (b))
16345 {
16346 w->base_line_number = make_number (topline);
16347 w->base_line_pos = make_number (BUF_BEGV (b));
16348 }
16349 else if (nlines < height + 25 || nlines > height * 3 + 50
16350 || linepos == BUF_BEGV (b))
16351 {
16352 int limit = BUF_BEGV (b);
16353 int limit_byte = BUF_BEGV_BYTE (b);
16354 int position;
16355 int distance = (height * 2 + 30) * line_number_display_limit_width;
16356
16357 if (startpos - distance > limit)
16358 {
16359 limit = startpos - distance;
16360 limit_byte = CHAR_TO_BYTE (limit);
16361 }
16362
16363 nlines = display_count_lines (startpos, startpos_byte,
16364 limit_byte,
16365 - (height * 2 + 30),
16366 &position);
16367 /* If we couldn't find the lines we wanted within
16368 line_number_display_limit_width chars per line,
16369 give up on line numbers for this window. */
16370 if (position == limit_byte && limit == startpos - distance)
16371 {
16372 w->base_line_pos = w->buffer;
16373 w->base_line_number = Qnil;
16374 goto no_value;
16375 }
16376
16377 w->base_line_number = make_number (topline - nlines);
16378 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16379 }
16380
16381 /* Now count lines from the start pos to point. */
16382 nlines = display_count_lines (startpos, startpos_byte,
16383 PT_BYTE, PT, &junk);
16384
16385 /* Record that we did display the line number. */
16386 line_number_displayed = 1;
16387
16388 /* Make the string to show. */
16389 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16390 return decode_mode_spec_buf;
16391 no_value:
16392 {
16393 char* p = decode_mode_spec_buf;
16394 int pad = field_width - 2;
16395 while (pad-- > 0)
16396 *p++ = ' ';
16397 *p++ = '?';
16398 *p++ = '?';
16399 *p = '\0';
16400 return decode_mode_spec_buf;
16401 }
16402 }
16403 break;
16404
16405 case 'm':
16406 obj = b->mode_name;
16407 break;
16408
16409 case 'n':
16410 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16411 return " Narrow";
16412 break;
16413
16414 case 'p':
16415 {
16416 int pos = marker_position (w->start);
16417 int total = BUF_ZV (b) - BUF_BEGV (b);
16418
16419 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16420 {
16421 if (pos <= BUF_BEGV (b))
16422 return "All";
16423 else
16424 return "Bottom";
16425 }
16426 else if (pos <= BUF_BEGV (b))
16427 return "Top";
16428 else
16429 {
16430 if (total > 1000000)
16431 /* Do it differently for a large value, to avoid overflow. */
16432 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16433 else
16434 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16435 /* We can't normally display a 3-digit number,
16436 so get us a 2-digit number that is close. */
16437 if (total == 100)
16438 total = 99;
16439 sprintf (decode_mode_spec_buf, "%2d%%", total);
16440 return decode_mode_spec_buf;
16441 }
16442 }
16443
16444 /* Display percentage of size above the bottom of the screen. */
16445 case 'P':
16446 {
16447 int toppos = marker_position (w->start);
16448 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16449 int total = BUF_ZV (b) - BUF_BEGV (b);
16450
16451 if (botpos >= BUF_ZV (b))
16452 {
16453 if (toppos <= BUF_BEGV (b))
16454 return "All";
16455 else
16456 return "Bottom";
16457 }
16458 else
16459 {
16460 if (total > 1000000)
16461 /* Do it differently for a large value, to avoid overflow. */
16462 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16463 else
16464 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16465 /* We can't normally display a 3-digit number,
16466 so get us a 2-digit number that is close. */
16467 if (total == 100)
16468 total = 99;
16469 if (toppos <= BUF_BEGV (b))
16470 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16471 else
16472 sprintf (decode_mode_spec_buf, "%2d%%", total);
16473 return decode_mode_spec_buf;
16474 }
16475 }
16476
16477 case 's':
16478 /* status of process */
16479 obj = Fget_buffer_process (Fcurrent_buffer ());
16480 if (NILP (obj))
16481 return "no process";
16482 #ifdef subprocesses
16483 obj = Fsymbol_name (Fprocess_status (obj));
16484 #endif
16485 break;
16486
16487 case 't': /* indicate TEXT or BINARY */
16488 #ifdef MODE_LINE_BINARY_TEXT
16489 return MODE_LINE_BINARY_TEXT (b);
16490 #else
16491 return "T";
16492 #endif
16493
16494 case 'z':
16495 /* coding-system (not including end-of-line format) */
16496 case 'Z':
16497 /* coding-system (including end-of-line type) */
16498 {
16499 int eol_flag = (c == 'Z');
16500 char *p = decode_mode_spec_buf;
16501
16502 if (! FRAME_WINDOW_P (f))
16503 {
16504 /* No need to mention EOL here--the terminal never needs
16505 to do EOL conversion. */
16506 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16507 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16508 }
16509 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16510 p, eol_flag);
16511
16512 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16513 #ifdef subprocesses
16514 obj = Fget_buffer_process (Fcurrent_buffer ());
16515 if (PROCESSP (obj))
16516 {
16517 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16518 p, eol_flag);
16519 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16520 p, eol_flag);
16521 }
16522 #endif /* subprocesses */
16523 #endif /* 0 */
16524 *p = 0;
16525 return decode_mode_spec_buf;
16526 }
16527 }
16528
16529 if (STRINGP (obj))
16530 {
16531 *multibyte = STRING_MULTIBYTE (obj);
16532 return (char *) SDATA (obj);
16533 }
16534 else
16535 return "";
16536 }
16537
16538
16539 /* Count up to COUNT lines starting from START / START_BYTE.
16540 But don't go beyond LIMIT_BYTE.
16541 Return the number of lines thus found (always nonnegative).
16542
16543 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16544
16545 static int
16546 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16547 int start, start_byte, limit_byte, count;
16548 int *byte_pos_ptr;
16549 {
16550 register unsigned char *cursor;
16551 unsigned char *base;
16552
16553 register int ceiling;
16554 register unsigned char *ceiling_addr;
16555 int orig_count = count;
16556
16557 /* If we are not in selective display mode,
16558 check only for newlines. */
16559 int selective_display = (!NILP (current_buffer->selective_display)
16560 && !INTEGERP (current_buffer->selective_display));
16561
16562 if (count > 0)
16563 {
16564 while (start_byte < limit_byte)
16565 {
16566 ceiling = BUFFER_CEILING_OF (start_byte);
16567 ceiling = min (limit_byte - 1, ceiling);
16568 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16569 base = (cursor = BYTE_POS_ADDR (start_byte));
16570 while (1)
16571 {
16572 if (selective_display)
16573 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16574 ;
16575 else
16576 while (*cursor != '\n' && ++cursor != ceiling_addr)
16577 ;
16578
16579 if (cursor != ceiling_addr)
16580 {
16581 if (--count == 0)
16582 {
16583 start_byte += cursor - base + 1;
16584 *byte_pos_ptr = start_byte;
16585 return orig_count;
16586 }
16587 else
16588 if (++cursor == ceiling_addr)
16589 break;
16590 }
16591 else
16592 break;
16593 }
16594 start_byte += cursor - base;
16595 }
16596 }
16597 else
16598 {
16599 while (start_byte > limit_byte)
16600 {
16601 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16602 ceiling = max (limit_byte, ceiling);
16603 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16604 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16605 while (1)
16606 {
16607 if (selective_display)
16608 while (--cursor != ceiling_addr
16609 && *cursor != '\n' && *cursor != 015)
16610 ;
16611 else
16612 while (--cursor != ceiling_addr && *cursor != '\n')
16613 ;
16614
16615 if (cursor != ceiling_addr)
16616 {
16617 if (++count == 0)
16618 {
16619 start_byte += cursor - base + 1;
16620 *byte_pos_ptr = start_byte;
16621 /* When scanning backwards, we should
16622 not count the newline posterior to which we stop. */
16623 return - orig_count - 1;
16624 }
16625 }
16626 else
16627 break;
16628 }
16629 /* Here we add 1 to compensate for the last decrement
16630 of CURSOR, which took it past the valid range. */
16631 start_byte += cursor - base + 1;
16632 }
16633 }
16634
16635 *byte_pos_ptr = limit_byte;
16636
16637 if (count < 0)
16638 return - orig_count + count;
16639 return orig_count - count;
16640
16641 }
16642
16643
16644 \f
16645 /***********************************************************************
16646 Displaying strings
16647 ***********************************************************************/
16648
16649 /* Display a NUL-terminated string, starting with index START.
16650
16651 If STRING is non-null, display that C string. Otherwise, the Lisp
16652 string LISP_STRING is displayed.
16653
16654 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16655 FACE_STRING. Display STRING or LISP_STRING with the face at
16656 FACE_STRING_POS in FACE_STRING:
16657
16658 Display the string in the environment given by IT, but use the
16659 standard display table, temporarily.
16660
16661 FIELD_WIDTH is the minimum number of output glyphs to produce.
16662 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16663 with spaces. If STRING has more characters, more than FIELD_WIDTH
16664 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16665
16666 PRECISION is the maximum number of characters to output from
16667 STRING. PRECISION < 0 means don't truncate the string.
16668
16669 This is roughly equivalent to printf format specifiers:
16670
16671 FIELD_WIDTH PRECISION PRINTF
16672 ----------------------------------------
16673 -1 -1 %s
16674 -1 10 %.10s
16675 10 -1 %10s
16676 20 10 %20.10s
16677
16678 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16679 display them, and < 0 means obey the current buffer's value of
16680 enable_multibyte_characters.
16681
16682 Value is the number of glyphs produced. */
16683
16684 static int
16685 display_string (string, lisp_string, face_string, face_string_pos,
16686 start, it, field_width, precision, max_x, multibyte)
16687 unsigned char *string;
16688 Lisp_Object lisp_string;
16689 Lisp_Object face_string;
16690 int face_string_pos;
16691 int start;
16692 struct it *it;
16693 int field_width, precision, max_x;
16694 int multibyte;
16695 {
16696 int hpos_at_start = it->hpos;
16697 int saved_face_id = it->face_id;
16698 struct glyph_row *row = it->glyph_row;
16699
16700 /* Initialize the iterator IT for iteration over STRING beginning
16701 with index START. */
16702 reseat_to_string (it, string, lisp_string, start,
16703 precision, field_width, multibyte);
16704
16705 /* If displaying STRING, set up the face of the iterator
16706 from LISP_STRING, if that's given. */
16707 if (STRINGP (face_string))
16708 {
16709 int endptr;
16710 struct face *face;
16711
16712 it->face_id
16713 = face_at_string_position (it->w, face_string, face_string_pos,
16714 0, it->region_beg_charpos,
16715 it->region_end_charpos,
16716 &endptr, it->base_face_id, 0);
16717 face = FACE_FROM_ID (it->f, it->face_id);
16718 it->face_box_p = face->box != FACE_NO_BOX;
16719 }
16720
16721 /* Set max_x to the maximum allowed X position. Don't let it go
16722 beyond the right edge of the window. */
16723 if (max_x <= 0)
16724 max_x = it->last_visible_x;
16725 else
16726 max_x = min (max_x, it->last_visible_x);
16727
16728 /* Skip over display elements that are not visible. because IT->w is
16729 hscrolled. */
16730 if (it->current_x < it->first_visible_x)
16731 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16732 MOVE_TO_POS | MOVE_TO_X);
16733
16734 row->ascent = it->max_ascent;
16735 row->height = it->max_ascent + it->max_descent;
16736 row->phys_ascent = it->max_phys_ascent;
16737 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16738
16739 /* This condition is for the case that we are called with current_x
16740 past last_visible_x. */
16741 while (it->current_x < max_x)
16742 {
16743 int x_before, x, n_glyphs_before, i, nglyphs;
16744
16745 /* Get the next display element. */
16746 if (!get_next_display_element (it))
16747 break;
16748
16749 /* Produce glyphs. */
16750 x_before = it->current_x;
16751 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16752 PRODUCE_GLYPHS (it);
16753
16754 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16755 i = 0;
16756 x = x_before;
16757 while (i < nglyphs)
16758 {
16759 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16760
16761 if (!it->truncate_lines_p
16762 && x + glyph->pixel_width > max_x)
16763 {
16764 /* End of continued line or max_x reached. */
16765 if (CHAR_GLYPH_PADDING_P (*glyph))
16766 {
16767 /* A wide character is unbreakable. */
16768 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16769 it->current_x = x_before;
16770 }
16771 else
16772 {
16773 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16774 it->current_x = x;
16775 }
16776 break;
16777 }
16778 else if (x + glyph->pixel_width > it->first_visible_x)
16779 {
16780 /* Glyph is at least partially visible. */
16781 ++it->hpos;
16782 if (x < it->first_visible_x)
16783 it->glyph_row->x = x - it->first_visible_x;
16784 }
16785 else
16786 {
16787 /* Glyph is off the left margin of the display area.
16788 Should not happen. */
16789 abort ();
16790 }
16791
16792 row->ascent = max (row->ascent, it->max_ascent);
16793 row->height = max (row->height, it->max_ascent + it->max_descent);
16794 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16795 row->phys_height = max (row->phys_height,
16796 it->max_phys_ascent + it->max_phys_descent);
16797 x += glyph->pixel_width;
16798 ++i;
16799 }
16800
16801 /* Stop if max_x reached. */
16802 if (i < nglyphs)
16803 break;
16804
16805 /* Stop at line ends. */
16806 if (ITERATOR_AT_END_OF_LINE_P (it))
16807 {
16808 it->continuation_lines_width = 0;
16809 break;
16810 }
16811
16812 set_iterator_to_next (it, 1);
16813
16814 /* Stop if truncating at the right edge. */
16815 if (it->truncate_lines_p
16816 && it->current_x >= it->last_visible_x)
16817 {
16818 /* Add truncation mark, but don't do it if the line is
16819 truncated at a padding space. */
16820 if (IT_CHARPOS (*it) < it->string_nchars)
16821 {
16822 if (!FRAME_WINDOW_P (it->f))
16823 {
16824 int i, n;
16825
16826 if (it->current_x > it->last_visible_x)
16827 {
16828 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16829 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16830 break;
16831 for (n = row->used[TEXT_AREA]; i < n; ++i)
16832 {
16833 row->used[TEXT_AREA] = i;
16834 produce_special_glyphs (it, IT_TRUNCATION);
16835 }
16836 }
16837 produce_special_glyphs (it, IT_TRUNCATION);
16838 }
16839 it->glyph_row->truncated_on_right_p = 1;
16840 }
16841 break;
16842 }
16843 }
16844
16845 /* Maybe insert a truncation at the left. */
16846 if (it->first_visible_x
16847 && IT_CHARPOS (*it) > 0)
16848 {
16849 if (!FRAME_WINDOW_P (it->f))
16850 insert_left_trunc_glyphs (it);
16851 it->glyph_row->truncated_on_left_p = 1;
16852 }
16853
16854 it->face_id = saved_face_id;
16855
16856 /* Value is number of columns displayed. */
16857 return it->hpos - hpos_at_start;
16858 }
16859
16860
16861 \f
16862 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16863 appears as an element of LIST or as the car of an element of LIST.
16864 If PROPVAL is a list, compare each element against LIST in that
16865 way, and return 1/2 if any element of PROPVAL is found in LIST.
16866 Otherwise return 0. This function cannot quit.
16867 The return value is 2 if the text is invisible but with an ellipsis
16868 and 1 if it's invisible and without an ellipsis. */
16869
16870 int
16871 invisible_p (propval, list)
16872 register Lisp_Object propval;
16873 Lisp_Object list;
16874 {
16875 register Lisp_Object tail, proptail;
16876
16877 for (tail = list; CONSP (tail); tail = XCDR (tail))
16878 {
16879 register Lisp_Object tem;
16880 tem = XCAR (tail);
16881 if (EQ (propval, tem))
16882 return 1;
16883 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16884 return NILP (XCDR (tem)) ? 1 : 2;
16885 }
16886
16887 if (CONSP (propval))
16888 {
16889 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16890 {
16891 Lisp_Object propelt;
16892 propelt = XCAR (proptail);
16893 for (tail = list; CONSP (tail); tail = XCDR (tail))
16894 {
16895 register Lisp_Object tem;
16896 tem = XCAR (tail);
16897 if (EQ (propelt, tem))
16898 return 1;
16899 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16900 return NILP (XCDR (tem)) ? 1 : 2;
16901 }
16902 }
16903 }
16904
16905 return 0;
16906 }
16907
16908 /* Calculate a width or height in pixels from a specification using
16909 the following elements:
16910
16911 SPEC ::=
16912 NUM - a (fractional) multiple of the default font width/height
16913 (NUM) - specifies exactly NUM pixels
16914 UNIT - a fixed number of pixels, see below.
16915 ELEMENT - size of a display element in pixels, see below.
16916 (NUM . SPEC) - equals NUM * SPEC
16917 (+ SPEC SPEC ...) - add pixel values
16918 (- SPEC SPEC ...) - subtract pixel values
16919 (- SPEC) - negate pixel value
16920
16921 NUM ::=
16922 INT or FLOAT - a number constant
16923 SYMBOL - use symbol's (buffer local) variable binding.
16924
16925 UNIT ::=
16926 in - pixels per inch *)
16927 mm - pixels per 1/1000 meter *)
16928 cm - pixels per 1/100 meter *)
16929 width - width of current font in pixels.
16930 height - height of current font in pixels.
16931
16932 *) using the ratio(s) defined in display-pixels-per-inch.
16933
16934 ELEMENT ::=
16935
16936 left-fringe - left fringe width in pixels
16937 right-fringe - right fringe width in pixels
16938
16939 left-margin - left margin width in pixels
16940 right-margin - right margin width in pixels
16941
16942 scroll-bar - scroll-bar area width in pixels
16943
16944 Examples:
16945
16946 Pixels corresponding to 5 inches:
16947 (5 . in)
16948
16949 Total width of non-text areas on left side of window (if scroll-bar is on left):
16950 '(space :width (+ left-fringe left-margin scroll-bar))
16951
16952 Align to first text column (in header line):
16953 '(space :align-to 0)
16954
16955 Align to middle of text area minus half the width of variable `my-image'
16956 containing a loaded image:
16957 '(space :align-to (0.5 . (- text my-image)))
16958
16959 Width of left margin minus width of 1 character in the default font:
16960 '(space :width (- left-margin 1))
16961
16962 Width of left margin minus width of 2 characters in the current font:
16963 '(space :width (- left-margin (2 . width)))
16964
16965 Center 1 character over left-margin (in header line):
16966 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16967
16968 Different ways to express width of left fringe plus left margin minus one pixel:
16969 '(space :width (- (+ left-fringe left-margin) (1)))
16970 '(space :width (+ left-fringe left-margin (- (1))))
16971 '(space :width (+ left-fringe left-margin (-1)))
16972
16973 */
16974
16975 #define NUMVAL(X) \
16976 ((INTEGERP (X) || FLOATP (X)) \
16977 ? XFLOATINT (X) \
16978 : - 1)
16979
16980 int
16981 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
16982 double *res;
16983 struct it *it;
16984 Lisp_Object prop;
16985 void *font;
16986 int width_p, *align_to;
16987 {
16988 double pixels;
16989
16990 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16991 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16992
16993 if (NILP (prop))
16994 return OK_PIXELS (0);
16995
16996 if (SYMBOLP (prop))
16997 {
16998 if (SCHARS (SYMBOL_NAME (prop)) == 2)
16999 {
17000 char *unit = SDATA (SYMBOL_NAME (prop));
17001
17002 if (unit[0] == 'i' && unit[1] == 'n')
17003 pixels = 1.0;
17004 else if (unit[0] == 'm' && unit[1] == 'm')
17005 pixels = 25.4;
17006 else if (unit[0] == 'c' && unit[1] == 'm')
17007 pixels = 2.54;
17008 else
17009 pixels = 0;
17010 if (pixels > 0)
17011 {
17012 double ppi;
17013 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17014 || (CONSP (Vdisplay_pixels_per_inch)
17015 && (ppi = (width_p
17016 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17017 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17018 ppi > 0)))
17019 return OK_PIXELS (ppi / pixels);
17020
17021 return 0;
17022 }
17023 }
17024
17025 #ifdef HAVE_WINDOW_SYSTEM
17026 if (EQ (prop, Qheight))
17027 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17028 if (EQ (prop, Qwidth))
17029 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17030 #else
17031 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17032 return OK_PIXELS (1);
17033 #endif
17034
17035 if (EQ (prop, Qtext))
17036 return OK_PIXELS (width_p
17037 ? window_box_width (it->w, TEXT_AREA)
17038 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17039
17040 if (align_to && *align_to < 0)
17041 {
17042 *res = 0;
17043 if (EQ (prop, Qleft))
17044 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17045 if (EQ (prop, Qright))
17046 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17047 if (EQ (prop, Qcenter))
17048 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17049 + window_box_width (it->w, TEXT_AREA) / 2);
17050 if (EQ (prop, Qleft_fringe))
17051 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17052 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17053 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17054 if (EQ (prop, Qright_fringe))
17055 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17056 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17057 : window_box_right_offset (it->w, TEXT_AREA));
17058 if (EQ (prop, Qleft_margin))
17059 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17060 if (EQ (prop, Qright_margin))
17061 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17062 if (EQ (prop, Qscroll_bar))
17063 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17064 ? 0
17065 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17066 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17067 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17068 : 0)));
17069 }
17070 else
17071 {
17072 if (EQ (prop, Qleft_fringe))
17073 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17074 if (EQ (prop, Qright_fringe))
17075 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17076 if (EQ (prop, Qleft_margin))
17077 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17078 if (EQ (prop, Qright_margin))
17079 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17080 if (EQ (prop, Qscroll_bar))
17081 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17082 }
17083
17084 prop = Fbuffer_local_value (prop, it->w->buffer);
17085 }
17086
17087 if (INTEGERP (prop) || FLOATP (prop))
17088 {
17089 int base_unit = (width_p
17090 ? FRAME_COLUMN_WIDTH (it->f)
17091 : FRAME_LINE_HEIGHT (it->f));
17092 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17093 }
17094
17095 if (CONSP (prop))
17096 {
17097 Lisp_Object car = XCAR (prop);
17098 Lisp_Object cdr = XCDR (prop);
17099
17100 if (SYMBOLP (car))
17101 {
17102 #ifdef HAVE_WINDOW_SYSTEM
17103 if (valid_image_p (prop))
17104 {
17105 int id = lookup_image (it->f, prop);
17106 struct image *img = IMAGE_FROM_ID (it->f, id);
17107
17108 return OK_PIXELS (width_p ? img->width : img->height);
17109 }
17110 #endif
17111 if (EQ (car, Qplus) || EQ (car, Qminus))
17112 {
17113 int first = 1;
17114 double px;
17115
17116 pixels = 0;
17117 while (CONSP (cdr))
17118 {
17119 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17120 font, width_p, align_to))
17121 return 0;
17122 if (first)
17123 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17124 else
17125 pixels += px;
17126 cdr = XCDR (cdr);
17127 }
17128 if (EQ (car, Qminus))
17129 pixels = -pixels;
17130 return OK_PIXELS (pixels);
17131 }
17132
17133 car = Fbuffer_local_value (car, it->w->buffer);
17134 }
17135
17136 if (INTEGERP (car) || FLOATP (car))
17137 {
17138 double fact;
17139 pixels = XFLOATINT (car);
17140 if (NILP (cdr))
17141 return OK_PIXELS (pixels);
17142 if (calc_pixel_width_or_height (&fact, it, cdr,
17143 font, width_p, align_to))
17144 return OK_PIXELS (pixels * fact);
17145 return 0;
17146 }
17147
17148 return 0;
17149 }
17150
17151 return 0;
17152 }
17153
17154 \f
17155 /***********************************************************************
17156 Glyph Display
17157 ***********************************************************************/
17158
17159 #ifdef HAVE_WINDOW_SYSTEM
17160
17161 #if GLYPH_DEBUG
17162
17163 void
17164 dump_glyph_string (s)
17165 struct glyph_string *s;
17166 {
17167 fprintf (stderr, "glyph string\n");
17168 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17169 s->x, s->y, s->width, s->height);
17170 fprintf (stderr, " ybase = %d\n", s->ybase);
17171 fprintf (stderr, " hl = %d\n", s->hl);
17172 fprintf (stderr, " left overhang = %d, right = %d\n",
17173 s->left_overhang, s->right_overhang);
17174 fprintf (stderr, " nchars = %d\n", s->nchars);
17175 fprintf (stderr, " extends to end of line = %d\n",
17176 s->extends_to_end_of_line_p);
17177 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17178 fprintf (stderr, " bg width = %d\n", s->background_width);
17179 }
17180
17181 #endif /* GLYPH_DEBUG */
17182
17183 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17184 of XChar2b structures for S; it can't be allocated in
17185 init_glyph_string because it must be allocated via `alloca'. W
17186 is the window on which S is drawn. ROW and AREA are the glyph row
17187 and area within the row from which S is constructed. START is the
17188 index of the first glyph structure covered by S. HL is a
17189 face-override for drawing S. */
17190
17191 #ifdef HAVE_NTGUI
17192 #define OPTIONAL_HDC(hdc) hdc,
17193 #define DECLARE_HDC(hdc) HDC hdc;
17194 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17195 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17196 #endif
17197
17198 #ifndef OPTIONAL_HDC
17199 #define OPTIONAL_HDC(hdc)
17200 #define DECLARE_HDC(hdc)
17201 #define ALLOCATE_HDC(hdc, f)
17202 #define RELEASE_HDC(hdc, f)
17203 #endif
17204
17205 static void
17206 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17207 struct glyph_string *s;
17208 DECLARE_HDC (hdc)
17209 XChar2b *char2b;
17210 struct window *w;
17211 struct glyph_row *row;
17212 enum glyph_row_area area;
17213 int start;
17214 enum draw_glyphs_face hl;
17215 {
17216 bzero (s, sizeof *s);
17217 s->w = w;
17218 s->f = XFRAME (w->frame);
17219 #ifdef HAVE_NTGUI
17220 s->hdc = hdc;
17221 #endif
17222 s->display = FRAME_X_DISPLAY (s->f);
17223 s->window = FRAME_X_WINDOW (s->f);
17224 s->char2b = char2b;
17225 s->hl = hl;
17226 s->row = row;
17227 s->area = area;
17228 s->first_glyph = row->glyphs[area] + start;
17229 s->height = row->height;
17230 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17231
17232 /* Display the internal border below the tool-bar window. */
17233 if (s->w == XWINDOW (s->f->tool_bar_window))
17234 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17235
17236 s->ybase = s->y + row->ascent;
17237 }
17238
17239
17240 /* Append the list of glyph strings with head H and tail T to the list
17241 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17242
17243 static INLINE void
17244 append_glyph_string_lists (head, tail, h, t)
17245 struct glyph_string **head, **tail;
17246 struct glyph_string *h, *t;
17247 {
17248 if (h)
17249 {
17250 if (*head)
17251 (*tail)->next = h;
17252 else
17253 *head = h;
17254 h->prev = *tail;
17255 *tail = t;
17256 }
17257 }
17258
17259
17260 /* Prepend the list of glyph strings with head H and tail T to the
17261 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17262 result. */
17263
17264 static INLINE void
17265 prepend_glyph_string_lists (head, tail, h, t)
17266 struct glyph_string **head, **tail;
17267 struct glyph_string *h, *t;
17268 {
17269 if (h)
17270 {
17271 if (*head)
17272 (*head)->prev = t;
17273 else
17274 *tail = t;
17275 t->next = *head;
17276 *head = h;
17277 }
17278 }
17279
17280
17281 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17282 Set *HEAD and *TAIL to the resulting list. */
17283
17284 static INLINE void
17285 append_glyph_string (head, tail, s)
17286 struct glyph_string **head, **tail;
17287 struct glyph_string *s;
17288 {
17289 s->next = s->prev = NULL;
17290 append_glyph_string_lists (head, tail, s, s);
17291 }
17292
17293
17294 /* Get face and two-byte form of character glyph GLYPH on frame F.
17295 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17296 a pointer to a realized face that is ready for display. */
17297
17298 static INLINE struct face *
17299 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17300 struct frame *f;
17301 struct glyph *glyph;
17302 XChar2b *char2b;
17303 int *two_byte_p;
17304 {
17305 struct face *face;
17306
17307 xassert (glyph->type == CHAR_GLYPH);
17308 face = FACE_FROM_ID (f, glyph->face_id);
17309
17310 if (two_byte_p)
17311 *two_byte_p = 0;
17312
17313 if (!glyph->multibyte_p)
17314 {
17315 /* Unibyte case. We don't have to encode, but we have to make
17316 sure to use a face suitable for unibyte. */
17317 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17318 }
17319 else if (glyph->u.ch < 128
17320 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17321 {
17322 /* Case of ASCII in a face known to fit ASCII. */
17323 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17324 }
17325 else
17326 {
17327 int c1, c2, charset;
17328
17329 /* Split characters into bytes. If c2 is -1 afterwards, C is
17330 really a one-byte character so that byte1 is zero. */
17331 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17332 if (c2 > 0)
17333 STORE_XCHAR2B (char2b, c1, c2);
17334 else
17335 STORE_XCHAR2B (char2b, 0, c1);
17336
17337 /* Maybe encode the character in *CHAR2B. */
17338 if (charset != CHARSET_ASCII)
17339 {
17340 struct font_info *font_info
17341 = FONT_INFO_FROM_ID (f, face->font_info_id);
17342 if (font_info)
17343 glyph->font_type
17344 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17345 }
17346 }
17347
17348 /* Make sure X resources of the face are allocated. */
17349 xassert (face != NULL);
17350 PREPARE_FACE_FOR_DISPLAY (f, face);
17351 return face;
17352 }
17353
17354
17355 /* Fill glyph string S with composition components specified by S->cmp.
17356
17357 FACES is an array of faces for all components of this composition.
17358 S->gidx is the index of the first component for S.
17359 OVERLAPS_P non-zero means S should draw the foreground only, and
17360 use its physical height for clipping.
17361
17362 Value is the index of a component not in S. */
17363
17364 static int
17365 fill_composite_glyph_string (s, faces, overlaps_p)
17366 struct glyph_string *s;
17367 struct face **faces;
17368 int overlaps_p;
17369 {
17370 int i;
17371
17372 xassert (s);
17373
17374 s->for_overlaps_p = overlaps_p;
17375
17376 s->face = faces[s->gidx];
17377 s->font = s->face->font;
17378 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17379
17380 /* For all glyphs of this composition, starting at the offset
17381 S->gidx, until we reach the end of the definition or encounter a
17382 glyph that requires the different face, add it to S. */
17383 ++s->nchars;
17384 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17385 ++s->nchars;
17386
17387 /* All glyph strings for the same composition has the same width,
17388 i.e. the width set for the first component of the composition. */
17389
17390 s->width = s->first_glyph->pixel_width;
17391
17392 /* If the specified font could not be loaded, use the frame's
17393 default font, but record the fact that we couldn't load it in
17394 the glyph string so that we can draw rectangles for the
17395 characters of the glyph string. */
17396 if (s->font == NULL)
17397 {
17398 s->font_not_found_p = 1;
17399 s->font = FRAME_FONT (s->f);
17400 }
17401
17402 /* Adjust base line for subscript/superscript text. */
17403 s->ybase += s->first_glyph->voffset;
17404
17405 xassert (s->face && s->face->gc);
17406
17407 /* This glyph string must always be drawn with 16-bit functions. */
17408 s->two_byte_p = 1;
17409
17410 return s->gidx + s->nchars;
17411 }
17412
17413
17414 /* Fill glyph string S from a sequence of character glyphs.
17415
17416 FACE_ID is the face id of the string. START is the index of the
17417 first glyph to consider, END is the index of the last + 1.
17418 OVERLAPS_P non-zero means S should draw the foreground only, and
17419 use its physical height for clipping.
17420
17421 Value is the index of the first glyph not in S. */
17422
17423 static int
17424 fill_glyph_string (s, face_id, start, end, overlaps_p)
17425 struct glyph_string *s;
17426 int face_id;
17427 int start, end, overlaps_p;
17428 {
17429 struct glyph *glyph, *last;
17430 int voffset;
17431 int glyph_not_available_p;
17432
17433 xassert (s->f == XFRAME (s->w->frame));
17434 xassert (s->nchars == 0);
17435 xassert (start >= 0 && end > start);
17436
17437 s->for_overlaps_p = overlaps_p,
17438 glyph = s->row->glyphs[s->area] + start;
17439 last = s->row->glyphs[s->area] + end;
17440 voffset = glyph->voffset;
17441
17442 glyph_not_available_p = glyph->glyph_not_available_p;
17443
17444 while (glyph < last
17445 && glyph->type == CHAR_GLYPH
17446 && glyph->voffset == voffset
17447 /* Same face id implies same font, nowadays. */
17448 && glyph->face_id == face_id
17449 && glyph->glyph_not_available_p == glyph_not_available_p)
17450 {
17451 int two_byte_p;
17452
17453 s->face = get_glyph_face_and_encoding (s->f, glyph,
17454 s->char2b + s->nchars,
17455 &two_byte_p);
17456 s->two_byte_p = two_byte_p;
17457 ++s->nchars;
17458 xassert (s->nchars <= end - start);
17459 s->width += glyph->pixel_width;
17460 ++glyph;
17461 }
17462
17463 s->font = s->face->font;
17464 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17465
17466 /* If the specified font could not be loaded, use the frame's font,
17467 but record the fact that we couldn't load it in
17468 S->font_not_found_p so that we can draw rectangles for the
17469 characters of the glyph string. */
17470 if (s->font == NULL || glyph_not_available_p)
17471 {
17472 s->font_not_found_p = 1;
17473 s->font = FRAME_FONT (s->f);
17474 }
17475
17476 /* Adjust base line for subscript/superscript text. */
17477 s->ybase += voffset;
17478
17479 xassert (s->face && s->face->gc);
17480 return glyph - s->row->glyphs[s->area];
17481 }
17482
17483
17484 /* Fill glyph string S from image glyph S->first_glyph. */
17485
17486 static void
17487 fill_image_glyph_string (s)
17488 struct glyph_string *s;
17489 {
17490 xassert (s->first_glyph->type == IMAGE_GLYPH);
17491 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17492 xassert (s->img);
17493 s->slice = s->first_glyph->slice;
17494 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17495 s->font = s->face->font;
17496 s->width = s->first_glyph->pixel_width;
17497
17498 /* Adjust base line for subscript/superscript text. */
17499 s->ybase += s->first_glyph->voffset;
17500 }
17501
17502
17503 /* Fill glyph string S from a sequence of stretch glyphs.
17504
17505 ROW is the glyph row in which the glyphs are found, AREA is the
17506 area within the row. START is the index of the first glyph to
17507 consider, END is the index of the last + 1.
17508
17509 Value is the index of the first glyph not in S. */
17510
17511 static int
17512 fill_stretch_glyph_string (s, row, area, start, end)
17513 struct glyph_string *s;
17514 struct glyph_row *row;
17515 enum glyph_row_area area;
17516 int start, end;
17517 {
17518 struct glyph *glyph, *last;
17519 int voffset, face_id;
17520
17521 xassert (s->first_glyph->type == STRETCH_GLYPH);
17522
17523 glyph = s->row->glyphs[s->area] + start;
17524 last = s->row->glyphs[s->area] + end;
17525 face_id = glyph->face_id;
17526 s->face = FACE_FROM_ID (s->f, face_id);
17527 s->font = s->face->font;
17528 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17529 s->width = glyph->pixel_width;
17530 voffset = glyph->voffset;
17531
17532 for (++glyph;
17533 (glyph < last
17534 && glyph->type == STRETCH_GLYPH
17535 && glyph->voffset == voffset
17536 && glyph->face_id == face_id);
17537 ++glyph)
17538 s->width += glyph->pixel_width;
17539
17540 /* Adjust base line for subscript/superscript text. */
17541 s->ybase += voffset;
17542
17543 /* The case that face->gc == 0 is handled when drawing the glyph
17544 string by calling PREPARE_FACE_FOR_DISPLAY. */
17545 xassert (s->face);
17546 return glyph - s->row->glyphs[s->area];
17547 }
17548
17549
17550 /* EXPORT for RIF:
17551 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17552 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17553 assumed to be zero. */
17554
17555 void
17556 x_get_glyph_overhangs (glyph, f, left, right)
17557 struct glyph *glyph;
17558 struct frame *f;
17559 int *left, *right;
17560 {
17561 *left = *right = 0;
17562
17563 if (glyph->type == CHAR_GLYPH)
17564 {
17565 XFontStruct *font;
17566 struct face *face;
17567 struct font_info *font_info;
17568 XChar2b char2b;
17569 XCharStruct *pcm;
17570
17571 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17572 font = face->font;
17573 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17574 if (font /* ++KFS: Should this be font_info ? */
17575 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17576 {
17577 if (pcm->rbearing > pcm->width)
17578 *right = pcm->rbearing - pcm->width;
17579 if (pcm->lbearing < 0)
17580 *left = -pcm->lbearing;
17581 }
17582 }
17583 }
17584
17585
17586 /* Return the index of the first glyph preceding glyph string S that
17587 is overwritten by S because of S's left overhang. Value is -1
17588 if no glyphs are overwritten. */
17589
17590 static int
17591 left_overwritten (s)
17592 struct glyph_string *s;
17593 {
17594 int k;
17595
17596 if (s->left_overhang)
17597 {
17598 int x = 0, i;
17599 struct glyph *glyphs = s->row->glyphs[s->area];
17600 int first = s->first_glyph - glyphs;
17601
17602 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17603 x -= glyphs[i].pixel_width;
17604
17605 k = i + 1;
17606 }
17607 else
17608 k = -1;
17609
17610 return k;
17611 }
17612
17613
17614 /* Return the index of the first glyph preceding glyph string S that
17615 is overwriting S because of its right overhang. Value is -1 if no
17616 glyph in front of S overwrites S. */
17617
17618 static int
17619 left_overwriting (s)
17620 struct glyph_string *s;
17621 {
17622 int i, k, x;
17623 struct glyph *glyphs = s->row->glyphs[s->area];
17624 int first = s->first_glyph - glyphs;
17625
17626 k = -1;
17627 x = 0;
17628 for (i = first - 1; i >= 0; --i)
17629 {
17630 int left, right;
17631 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17632 if (x + right > 0)
17633 k = i;
17634 x -= glyphs[i].pixel_width;
17635 }
17636
17637 return k;
17638 }
17639
17640
17641 /* Return the index of the last glyph following glyph string S that is
17642 not overwritten by S because of S's right overhang. Value is -1 if
17643 no such glyph is found. */
17644
17645 static int
17646 right_overwritten (s)
17647 struct glyph_string *s;
17648 {
17649 int k = -1;
17650
17651 if (s->right_overhang)
17652 {
17653 int x = 0, i;
17654 struct glyph *glyphs = s->row->glyphs[s->area];
17655 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17656 int end = s->row->used[s->area];
17657
17658 for (i = first; i < end && s->right_overhang > x; ++i)
17659 x += glyphs[i].pixel_width;
17660
17661 k = i;
17662 }
17663
17664 return k;
17665 }
17666
17667
17668 /* Return the index of the last glyph following glyph string S that
17669 overwrites S because of its left overhang. Value is negative
17670 if no such glyph is found. */
17671
17672 static int
17673 right_overwriting (s)
17674 struct glyph_string *s;
17675 {
17676 int i, k, x;
17677 int end = s->row->used[s->area];
17678 struct glyph *glyphs = s->row->glyphs[s->area];
17679 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17680
17681 k = -1;
17682 x = 0;
17683 for (i = first; i < end; ++i)
17684 {
17685 int left, right;
17686 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17687 if (x - left < 0)
17688 k = i;
17689 x += glyphs[i].pixel_width;
17690 }
17691
17692 return k;
17693 }
17694
17695
17696 /* Get face and two-byte form of character C in face FACE_ID on frame
17697 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17698 means we want to display multibyte text. DISPLAY_P non-zero means
17699 make sure that X resources for the face returned are allocated.
17700 Value is a pointer to a realized face that is ready for display if
17701 DISPLAY_P is non-zero. */
17702
17703 static INLINE struct face *
17704 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17705 struct frame *f;
17706 int c, face_id;
17707 XChar2b *char2b;
17708 int multibyte_p, display_p;
17709 {
17710 struct face *face = FACE_FROM_ID (f, face_id);
17711
17712 if (!multibyte_p)
17713 {
17714 /* Unibyte case. We don't have to encode, but we have to make
17715 sure to use a face suitable for unibyte. */
17716 STORE_XCHAR2B (char2b, 0, c);
17717 face_id = FACE_FOR_CHAR (f, face, c);
17718 face = FACE_FROM_ID (f, face_id);
17719 }
17720 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17721 {
17722 /* Case of ASCII in a face known to fit ASCII. */
17723 STORE_XCHAR2B (char2b, 0, c);
17724 }
17725 else
17726 {
17727 int c1, c2, charset;
17728
17729 /* Split characters into bytes. If c2 is -1 afterwards, C is
17730 really a one-byte character so that byte1 is zero. */
17731 SPLIT_CHAR (c, charset, c1, c2);
17732 if (c2 > 0)
17733 STORE_XCHAR2B (char2b, c1, c2);
17734 else
17735 STORE_XCHAR2B (char2b, 0, c1);
17736
17737 /* Maybe encode the character in *CHAR2B. */
17738 if (face->font != NULL)
17739 {
17740 struct font_info *font_info
17741 = FONT_INFO_FROM_ID (f, face->font_info_id);
17742 if (font_info)
17743 rif->encode_char (c, char2b, font_info, 0);
17744 }
17745 }
17746
17747 /* Make sure X resources of the face are allocated. */
17748 #ifdef HAVE_X_WINDOWS
17749 if (display_p)
17750 #endif
17751 {
17752 xassert (face != NULL);
17753 PREPARE_FACE_FOR_DISPLAY (f, face);
17754 }
17755
17756 return face;
17757 }
17758
17759
17760 /* Set background width of glyph string S. START is the index of the
17761 first glyph following S. LAST_X is the right-most x-position + 1
17762 in the drawing area. */
17763
17764 static INLINE void
17765 set_glyph_string_background_width (s, start, last_x)
17766 struct glyph_string *s;
17767 int start;
17768 int last_x;
17769 {
17770 /* If the face of this glyph string has to be drawn to the end of
17771 the drawing area, set S->extends_to_end_of_line_p. */
17772 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17773
17774 if (start == s->row->used[s->area]
17775 && s->area == TEXT_AREA
17776 && ((s->hl == DRAW_NORMAL_TEXT
17777 && (s->row->fill_line_p
17778 || s->face->background != default_face->background
17779 || s->face->stipple != default_face->stipple
17780 || s->row->mouse_face_p))
17781 || s->hl == DRAW_MOUSE_FACE
17782 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17783 && s->row->fill_line_p)))
17784 s->extends_to_end_of_line_p = 1;
17785
17786 /* If S extends its face to the end of the line, set its
17787 background_width to the distance to the right edge of the drawing
17788 area. */
17789 if (s->extends_to_end_of_line_p)
17790 s->background_width = last_x - s->x + 1;
17791 else
17792 s->background_width = s->width;
17793 }
17794
17795
17796 /* Compute overhangs and x-positions for glyph string S and its
17797 predecessors, or successors. X is the starting x-position for S.
17798 BACKWARD_P non-zero means process predecessors. */
17799
17800 static void
17801 compute_overhangs_and_x (s, x, backward_p)
17802 struct glyph_string *s;
17803 int x;
17804 int backward_p;
17805 {
17806 if (backward_p)
17807 {
17808 while (s)
17809 {
17810 if (rif->compute_glyph_string_overhangs)
17811 rif->compute_glyph_string_overhangs (s);
17812 x -= s->width;
17813 s->x = x;
17814 s = s->prev;
17815 }
17816 }
17817 else
17818 {
17819 while (s)
17820 {
17821 if (rif->compute_glyph_string_overhangs)
17822 rif->compute_glyph_string_overhangs (s);
17823 s->x = x;
17824 x += s->width;
17825 s = s->next;
17826 }
17827 }
17828 }
17829
17830
17831
17832 /* The following macros are only called from draw_glyphs below.
17833 They reference the following parameters of that function directly:
17834 `w', `row', `area', and `overlap_p'
17835 as well as the following local variables:
17836 `s', `f', and `hdc' (in W32) */
17837
17838 #ifdef HAVE_NTGUI
17839 /* On W32, silently add local `hdc' variable to argument list of
17840 init_glyph_string. */
17841 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17842 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17843 #else
17844 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17845 init_glyph_string (s, char2b, w, row, area, start, hl)
17846 #endif
17847
17848 /* Add a glyph string for a stretch glyph to the list of strings
17849 between HEAD and TAIL. START is the index of the stretch glyph in
17850 row area AREA of glyph row ROW. END is the index of the last glyph
17851 in that glyph row area. X is the current output position assigned
17852 to the new glyph string constructed. HL overrides that face of the
17853 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17854 is the right-most x-position of the drawing area. */
17855
17856 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17857 and below -- keep them on one line. */
17858 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17859 do \
17860 { \
17861 s = (struct glyph_string *) alloca (sizeof *s); \
17862 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17863 START = fill_stretch_glyph_string (s, row, area, START, END); \
17864 append_glyph_string (&HEAD, &TAIL, s); \
17865 s->x = (X); \
17866 } \
17867 while (0)
17868
17869
17870 /* Add a glyph string for an image glyph to the list of strings
17871 between HEAD and TAIL. START is the index of the image glyph in
17872 row area AREA of glyph row ROW. END is the index of the last glyph
17873 in that glyph row area. X is the current output position assigned
17874 to the new glyph string constructed. HL overrides that face of the
17875 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17876 is the right-most x-position of the drawing area. */
17877
17878 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17879 do \
17880 { \
17881 s = (struct glyph_string *) alloca (sizeof *s); \
17882 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17883 fill_image_glyph_string (s); \
17884 append_glyph_string (&HEAD, &TAIL, s); \
17885 ++START; \
17886 s->x = (X); \
17887 } \
17888 while (0)
17889
17890
17891 /* Add a glyph string for a sequence of character glyphs to the list
17892 of strings between HEAD and TAIL. START is the index of the first
17893 glyph in row area AREA of glyph row ROW that is part of the new
17894 glyph string. END is the index of the last glyph in that glyph row
17895 area. X is the current output position assigned to the new glyph
17896 string constructed. HL overrides that face of the glyph; e.g. it
17897 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17898 right-most x-position of the drawing area. */
17899
17900 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17901 do \
17902 { \
17903 int c, face_id; \
17904 XChar2b *char2b; \
17905 \
17906 c = (row)->glyphs[area][START].u.ch; \
17907 face_id = (row)->glyphs[area][START].face_id; \
17908 \
17909 s = (struct glyph_string *) alloca (sizeof *s); \
17910 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17911 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17912 append_glyph_string (&HEAD, &TAIL, s); \
17913 s->x = (X); \
17914 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17915 } \
17916 while (0)
17917
17918
17919 /* Add a glyph string for a composite sequence to the list of strings
17920 between HEAD and TAIL. START is the index of the first glyph in
17921 row area AREA of glyph row ROW that is part of the new glyph
17922 string. END is the index of the last glyph in that glyph row area.
17923 X is the current output position assigned to the new glyph string
17924 constructed. HL overrides that face of the glyph; e.g. it is
17925 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17926 x-position of the drawing area. */
17927
17928 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17929 do { \
17930 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17931 int face_id = (row)->glyphs[area][START].face_id; \
17932 struct face *base_face = FACE_FROM_ID (f, face_id); \
17933 struct composition *cmp = composition_table[cmp_id]; \
17934 int glyph_len = cmp->glyph_len; \
17935 XChar2b *char2b; \
17936 struct face **faces; \
17937 struct glyph_string *first_s = NULL; \
17938 int n; \
17939 \
17940 base_face = base_face->ascii_face; \
17941 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17942 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17943 /* At first, fill in `char2b' and `faces'. */ \
17944 for (n = 0; n < glyph_len; n++) \
17945 { \
17946 int c = COMPOSITION_GLYPH (cmp, n); \
17947 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17948 faces[n] = FACE_FROM_ID (f, this_face_id); \
17949 get_char_face_and_encoding (f, c, this_face_id, \
17950 char2b + n, 1, 1); \
17951 } \
17952 \
17953 /* Make glyph_strings for each glyph sequence that is drawable by \
17954 the same face, and append them to HEAD/TAIL. */ \
17955 for (n = 0; n < cmp->glyph_len;) \
17956 { \
17957 s = (struct glyph_string *) alloca (sizeof *s); \
17958 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17959 append_glyph_string (&(HEAD), &(TAIL), s); \
17960 s->cmp = cmp; \
17961 s->gidx = n; \
17962 s->x = (X); \
17963 \
17964 if (n == 0) \
17965 first_s = s; \
17966 \
17967 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17968 } \
17969 \
17970 ++START; \
17971 s = first_s; \
17972 } while (0)
17973
17974
17975 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17976 of AREA of glyph row ROW on window W between indices START and END.
17977 HL overrides the face for drawing glyph strings, e.g. it is
17978 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17979 x-positions of the drawing area.
17980
17981 This is an ugly monster macro construct because we must use alloca
17982 to allocate glyph strings (because draw_glyphs can be called
17983 asynchronously). */
17984
17985 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17986 do \
17987 { \
17988 HEAD = TAIL = NULL; \
17989 while (START < END) \
17990 { \
17991 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17992 switch (first_glyph->type) \
17993 { \
17994 case CHAR_GLYPH: \
17995 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17996 HL, X, LAST_X); \
17997 break; \
17998 \
17999 case COMPOSITE_GLYPH: \
18000 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18001 HL, X, LAST_X); \
18002 break; \
18003 \
18004 case STRETCH_GLYPH: \
18005 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18006 HL, X, LAST_X); \
18007 break; \
18008 \
18009 case IMAGE_GLYPH: \
18010 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18011 HL, X, LAST_X); \
18012 break; \
18013 \
18014 default: \
18015 abort (); \
18016 } \
18017 \
18018 set_glyph_string_background_width (s, START, LAST_X); \
18019 (X) += s->width; \
18020 } \
18021 } \
18022 while (0)
18023
18024
18025 /* Draw glyphs between START and END in AREA of ROW on window W,
18026 starting at x-position X. X is relative to AREA in W. HL is a
18027 face-override with the following meaning:
18028
18029 DRAW_NORMAL_TEXT draw normally
18030 DRAW_CURSOR draw in cursor face
18031 DRAW_MOUSE_FACE draw in mouse face.
18032 DRAW_INVERSE_VIDEO draw in mode line face
18033 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18034 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18035
18036 If OVERLAPS_P is non-zero, draw only the foreground of characters
18037 and clip to the physical height of ROW.
18038
18039 Value is the x-position reached, relative to AREA of W. */
18040
18041 static int
18042 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18043 struct window *w;
18044 int x;
18045 struct glyph_row *row;
18046 enum glyph_row_area area;
18047 int start, end;
18048 enum draw_glyphs_face hl;
18049 int overlaps_p;
18050 {
18051 struct glyph_string *head, *tail;
18052 struct glyph_string *s;
18053 int last_x, area_width;
18054 int x_reached;
18055 int i, j;
18056 struct frame *f = XFRAME (WINDOW_FRAME (w));
18057 DECLARE_HDC (hdc);
18058
18059 ALLOCATE_HDC (hdc, f);
18060
18061 /* Let's rather be paranoid than getting a SEGV. */
18062 end = min (end, row->used[area]);
18063 start = max (0, start);
18064 start = min (end, start);
18065
18066 /* Translate X to frame coordinates. Set last_x to the right
18067 end of the drawing area. */
18068 if (row->full_width_p)
18069 {
18070 /* X is relative to the left edge of W, without scroll bars
18071 or fringes. */
18072 x += WINDOW_LEFT_EDGE_X (w);
18073 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18074 }
18075 else
18076 {
18077 int area_left = window_box_left (w, area);
18078 x += area_left;
18079 area_width = window_box_width (w, area);
18080 last_x = area_left + area_width;
18081 }
18082
18083 /* Build a doubly-linked list of glyph_string structures between
18084 head and tail from what we have to draw. Note that the macro
18085 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18086 the reason we use a separate variable `i'. */
18087 i = start;
18088 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18089 if (tail)
18090 x_reached = tail->x + tail->background_width;
18091 else
18092 x_reached = x;
18093
18094 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18095 the row, redraw some glyphs in front or following the glyph
18096 strings built above. */
18097 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18098 {
18099 int dummy_x = 0;
18100 struct glyph_string *h, *t;
18101
18102 /* Compute overhangs for all glyph strings. */
18103 if (rif->compute_glyph_string_overhangs)
18104 for (s = head; s; s = s->next)
18105 rif->compute_glyph_string_overhangs (s);
18106
18107 /* Prepend glyph strings for glyphs in front of the first glyph
18108 string that are overwritten because of the first glyph
18109 string's left overhang. The background of all strings
18110 prepended must be drawn because the first glyph string
18111 draws over it. */
18112 i = left_overwritten (head);
18113 if (i >= 0)
18114 {
18115 j = i;
18116 BUILD_GLYPH_STRINGS (j, start, h, t,
18117 DRAW_NORMAL_TEXT, dummy_x, last_x);
18118 start = i;
18119 compute_overhangs_and_x (t, head->x, 1);
18120 prepend_glyph_string_lists (&head, &tail, h, t);
18121 }
18122
18123 /* Prepend glyph strings for glyphs in front of the first glyph
18124 string that overwrite that glyph string because of their
18125 right overhang. For these strings, only the foreground must
18126 be drawn, because it draws over the glyph string at `head'.
18127 The background must not be drawn because this would overwrite
18128 right overhangs of preceding glyphs for which no glyph
18129 strings exist. */
18130 i = left_overwriting (head);
18131 if (i >= 0)
18132 {
18133 BUILD_GLYPH_STRINGS (i, start, h, t,
18134 DRAW_NORMAL_TEXT, dummy_x, last_x);
18135 for (s = h; s; s = s->next)
18136 s->background_filled_p = 1;
18137 compute_overhangs_and_x (t, head->x, 1);
18138 prepend_glyph_string_lists (&head, &tail, h, t);
18139 }
18140
18141 /* Append glyphs strings for glyphs following the last glyph
18142 string tail that are overwritten by tail. The background of
18143 these strings has to be drawn because tail's foreground draws
18144 over it. */
18145 i = right_overwritten (tail);
18146 if (i >= 0)
18147 {
18148 BUILD_GLYPH_STRINGS (end, i, h, t,
18149 DRAW_NORMAL_TEXT, x, last_x);
18150 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18151 append_glyph_string_lists (&head, &tail, h, t);
18152 }
18153
18154 /* Append glyph strings for glyphs following the last glyph
18155 string tail that overwrite tail. The foreground of such
18156 glyphs has to be drawn because it writes into the background
18157 of tail. The background must not be drawn because it could
18158 paint over the foreground of following glyphs. */
18159 i = right_overwriting (tail);
18160 if (i >= 0)
18161 {
18162 BUILD_GLYPH_STRINGS (end, i, h, t,
18163 DRAW_NORMAL_TEXT, x, last_x);
18164 for (s = h; s; s = s->next)
18165 s->background_filled_p = 1;
18166 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18167 append_glyph_string_lists (&head, &tail, h, t);
18168 }
18169 }
18170
18171 /* Draw all strings. */
18172 for (s = head; s; s = s->next)
18173 rif->draw_glyph_string (s);
18174
18175 if (area == TEXT_AREA
18176 && !row->full_width_p
18177 /* When drawing overlapping rows, only the glyph strings'
18178 foreground is drawn, which doesn't erase a cursor
18179 completely. */
18180 && !overlaps_p)
18181 {
18182 int x0 = head ? head->x : x;
18183 int x1 = tail ? tail->x + tail->background_width : x;
18184
18185 int text_left = window_box_left (w, TEXT_AREA);
18186 x0 -= text_left;
18187 x1 -= text_left;
18188
18189 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18190 row->y, MATRIX_ROW_BOTTOM_Y (row));
18191 }
18192
18193 /* Value is the x-position up to which drawn, relative to AREA of W.
18194 This doesn't include parts drawn because of overhangs. */
18195 if (row->full_width_p)
18196 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18197 else
18198 x_reached -= window_box_left (w, area);
18199
18200 RELEASE_HDC (hdc, f);
18201
18202 return x_reached;
18203 }
18204
18205
18206 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18207 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18208
18209 static INLINE void
18210 append_glyph (it)
18211 struct it *it;
18212 {
18213 struct glyph *glyph;
18214 enum glyph_row_area area = it->area;
18215
18216 xassert (it->glyph_row);
18217 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18218
18219 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18220 if (glyph < it->glyph_row->glyphs[area + 1])
18221 {
18222 glyph->charpos = CHARPOS (it->position);
18223 glyph->object = it->object;
18224 glyph->pixel_width = it->pixel_width;
18225 glyph->ascent = it->ascent;
18226 glyph->descent = it->descent;
18227 glyph->voffset = it->voffset;
18228 glyph->type = CHAR_GLYPH;
18229 glyph->multibyte_p = it->multibyte_p;
18230 glyph->left_box_line_p = it->start_of_box_run_p;
18231 glyph->right_box_line_p = it->end_of_box_run_p;
18232 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18233 || it->phys_descent > it->descent);
18234 glyph->padding_p = 0;
18235 glyph->glyph_not_available_p = it->glyph_not_available_p;
18236 glyph->face_id = it->face_id;
18237 glyph->u.ch = it->char_to_display;
18238 glyph->slice = null_glyph_slice;
18239 glyph->font_type = FONT_TYPE_UNKNOWN;
18240 ++it->glyph_row->used[area];
18241 }
18242 else if (!fonts_changed_p)
18243 {
18244 it->w->ncols_scale_factor++;
18245 fonts_changed_p = 1;
18246 }
18247 }
18248
18249 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18250 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18251
18252 static INLINE void
18253 append_composite_glyph (it)
18254 struct it *it;
18255 {
18256 struct glyph *glyph;
18257 enum glyph_row_area area = it->area;
18258
18259 xassert (it->glyph_row);
18260
18261 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18262 if (glyph < it->glyph_row->glyphs[area + 1])
18263 {
18264 glyph->charpos = CHARPOS (it->position);
18265 glyph->object = it->object;
18266 glyph->pixel_width = it->pixel_width;
18267 glyph->ascent = it->ascent;
18268 glyph->descent = it->descent;
18269 glyph->voffset = it->voffset;
18270 glyph->type = COMPOSITE_GLYPH;
18271 glyph->multibyte_p = it->multibyte_p;
18272 glyph->left_box_line_p = it->start_of_box_run_p;
18273 glyph->right_box_line_p = it->end_of_box_run_p;
18274 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18275 || it->phys_descent > it->descent);
18276 glyph->padding_p = 0;
18277 glyph->glyph_not_available_p = 0;
18278 glyph->face_id = it->face_id;
18279 glyph->u.cmp_id = it->cmp_id;
18280 glyph->slice = null_glyph_slice;
18281 glyph->font_type = FONT_TYPE_UNKNOWN;
18282 ++it->glyph_row->used[area];
18283 }
18284 else if (!fonts_changed_p)
18285 {
18286 it->w->ncols_scale_factor++;
18287 fonts_changed_p = 1;
18288 }
18289 }
18290
18291
18292 /* Change IT->ascent and IT->height according to the setting of
18293 IT->voffset. */
18294
18295 static INLINE void
18296 take_vertical_position_into_account (it)
18297 struct it *it;
18298 {
18299 if (it->voffset)
18300 {
18301 if (it->voffset < 0)
18302 /* Increase the ascent so that we can display the text higher
18303 in the line. */
18304 it->ascent -= it->voffset;
18305 else
18306 /* Increase the descent so that we can display the text lower
18307 in the line. */
18308 it->descent += it->voffset;
18309 }
18310 }
18311
18312
18313 /* Produce glyphs/get display metrics for the image IT is loaded with.
18314 See the description of struct display_iterator in dispextern.h for
18315 an overview of struct display_iterator. */
18316
18317 static void
18318 produce_image_glyph (it)
18319 struct it *it;
18320 {
18321 struct image *img;
18322 struct face *face;
18323 int face_ascent, glyph_ascent;
18324 struct glyph_slice slice;
18325
18326 xassert (it->what == IT_IMAGE);
18327
18328 face = FACE_FROM_ID (it->f, it->face_id);
18329 xassert (face);
18330 /* Make sure X resources of the face is loaded. */
18331 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18332
18333 if (it->image_id < 0)
18334 {
18335 /* Fringe bitmap. */
18336 it->ascent = it->phys_ascent = 0;
18337 it->descent = it->phys_descent = 0;
18338 it->pixel_width = 0;
18339 it->nglyphs = 0;
18340 return;
18341 }
18342
18343 img = IMAGE_FROM_ID (it->f, it->image_id);
18344 xassert (img);
18345 /* Make sure X resources of the image is loaded. */
18346 prepare_image_for_display (it->f, img);
18347
18348 slice.x = slice.y = 0;
18349 slice.width = img->width;
18350 slice.height = img->height;
18351
18352 if (INTEGERP (it->slice.x))
18353 slice.x = XINT (it->slice.x);
18354 else if (FLOATP (it->slice.x))
18355 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18356
18357 if (INTEGERP (it->slice.y))
18358 slice.y = XINT (it->slice.y);
18359 else if (FLOATP (it->slice.y))
18360 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18361
18362 if (INTEGERP (it->slice.width))
18363 slice.width = XINT (it->slice.width);
18364 else if (FLOATP (it->slice.width))
18365 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18366
18367 if (INTEGERP (it->slice.height))
18368 slice.height = XINT (it->slice.height);
18369 else if (FLOATP (it->slice.height))
18370 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18371
18372 if (slice.x >= img->width)
18373 slice.x = img->width;
18374 if (slice.y >= img->height)
18375 slice.y = img->height;
18376 if (slice.x + slice.width >= img->width)
18377 slice.width = img->width - slice.x;
18378 if (slice.y + slice.height > img->height)
18379 slice.height = img->height - slice.y;
18380
18381 if (slice.width == 0 || slice.height == 0)
18382 return;
18383
18384 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18385
18386 it->descent = slice.height - glyph_ascent;
18387 if (slice.y == 0)
18388 it->descent += img->vmargin;
18389 if (slice.y + slice.height == img->height)
18390 it->descent += img->vmargin;
18391 it->phys_descent = it->descent;
18392
18393 it->pixel_width = slice.width;
18394 if (slice.x == 0)
18395 it->pixel_width += img->hmargin;
18396 if (slice.x + slice.width == img->width)
18397 it->pixel_width += img->hmargin;
18398
18399 /* It's quite possible for images to have an ascent greater than
18400 their height, so don't get confused in that case. */
18401 if (it->descent < 0)
18402 it->descent = 0;
18403
18404 #if 0 /* this breaks image tiling */
18405 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18406 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18407 if (face_ascent > it->ascent)
18408 it->ascent = it->phys_ascent = face_ascent;
18409 #endif
18410
18411 it->nglyphs = 1;
18412
18413 if (face->box != FACE_NO_BOX)
18414 {
18415 if (face->box_line_width > 0)
18416 {
18417 if (slice.y == 0)
18418 it->ascent += face->box_line_width;
18419 if (slice.y + slice.height == img->height)
18420 it->descent += face->box_line_width;
18421 }
18422
18423 if (it->start_of_box_run_p && slice.x == 0)
18424 it->pixel_width += abs (face->box_line_width);
18425 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18426 it->pixel_width += abs (face->box_line_width);
18427 }
18428
18429 take_vertical_position_into_account (it);
18430
18431 if (it->glyph_row)
18432 {
18433 struct glyph *glyph;
18434 enum glyph_row_area area = it->area;
18435
18436 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18437 if (glyph < it->glyph_row->glyphs[area + 1])
18438 {
18439 glyph->charpos = CHARPOS (it->position);
18440 glyph->object = it->object;
18441 glyph->pixel_width = it->pixel_width;
18442 glyph->ascent = glyph_ascent;
18443 glyph->descent = it->descent;
18444 glyph->voffset = it->voffset;
18445 glyph->type = IMAGE_GLYPH;
18446 glyph->multibyte_p = it->multibyte_p;
18447 glyph->left_box_line_p = it->start_of_box_run_p;
18448 glyph->right_box_line_p = it->end_of_box_run_p;
18449 glyph->overlaps_vertically_p = 0;
18450 glyph->padding_p = 0;
18451 glyph->glyph_not_available_p = 0;
18452 glyph->face_id = it->face_id;
18453 glyph->u.img_id = img->id;
18454 glyph->slice = slice;
18455 glyph->font_type = FONT_TYPE_UNKNOWN;
18456 ++it->glyph_row->used[area];
18457 }
18458 else if (!fonts_changed_p)
18459 {
18460 it->w->ncols_scale_factor++;
18461 fonts_changed_p = 1;
18462 }
18463 }
18464 }
18465
18466
18467 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18468 of the glyph, WIDTH and HEIGHT are the width and height of the
18469 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18470
18471 static void
18472 append_stretch_glyph (it, object, width, height, ascent)
18473 struct it *it;
18474 Lisp_Object object;
18475 int width, height;
18476 int ascent;
18477 {
18478 struct glyph *glyph;
18479 enum glyph_row_area area = it->area;
18480
18481 xassert (ascent >= 0 && ascent <= height);
18482
18483 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18484 if (glyph < it->glyph_row->glyphs[area + 1])
18485 {
18486 glyph->charpos = CHARPOS (it->position);
18487 glyph->object = object;
18488 glyph->pixel_width = width;
18489 glyph->ascent = ascent;
18490 glyph->descent = height - ascent;
18491 glyph->voffset = it->voffset;
18492 glyph->type = STRETCH_GLYPH;
18493 glyph->multibyte_p = it->multibyte_p;
18494 glyph->left_box_line_p = it->start_of_box_run_p;
18495 glyph->right_box_line_p = it->end_of_box_run_p;
18496 glyph->overlaps_vertically_p = 0;
18497 glyph->padding_p = 0;
18498 glyph->glyph_not_available_p = 0;
18499 glyph->face_id = it->face_id;
18500 glyph->u.stretch.ascent = ascent;
18501 glyph->u.stretch.height = height;
18502 glyph->slice = null_glyph_slice;
18503 glyph->font_type = FONT_TYPE_UNKNOWN;
18504 ++it->glyph_row->used[area];
18505 }
18506 else if (!fonts_changed_p)
18507 {
18508 it->w->ncols_scale_factor++;
18509 fonts_changed_p = 1;
18510 }
18511 }
18512
18513
18514 /* Produce a stretch glyph for iterator IT. IT->object is the value
18515 of the glyph property displayed. The value must be a list
18516 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18517 being recognized:
18518
18519 1. `:width WIDTH' specifies that the space should be WIDTH *
18520 canonical char width wide. WIDTH may be an integer or floating
18521 point number.
18522
18523 2. `:relative-width FACTOR' specifies that the width of the stretch
18524 should be computed from the width of the first character having the
18525 `glyph' property, and should be FACTOR times that width.
18526
18527 3. `:align-to HPOS' specifies that the space should be wide enough
18528 to reach HPOS, a value in canonical character units.
18529
18530 Exactly one of the above pairs must be present.
18531
18532 4. `:height HEIGHT' specifies that the height of the stretch produced
18533 should be HEIGHT, measured in canonical character units.
18534
18535 5. `:relative-height FACTOR' specifies that the height of the
18536 stretch should be FACTOR times the height of the characters having
18537 the glyph property.
18538
18539 Either none or exactly one of 4 or 5 must be present.
18540
18541 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18542 of the stretch should be used for the ascent of the stretch.
18543 ASCENT must be in the range 0 <= ASCENT <= 100. */
18544
18545 static void
18546 produce_stretch_glyph (it)
18547 struct it *it;
18548 {
18549 /* (space :width WIDTH :height HEIGHT ...) */
18550 Lisp_Object prop, plist;
18551 int width = 0, height = 0, align_to = -1;
18552 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18553 int ascent = 0;
18554 double tem;
18555 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18556 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18557
18558 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18559
18560 /* List should start with `space'. */
18561 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18562 plist = XCDR (it->object);
18563
18564 /* Compute the width of the stretch. */
18565 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18566 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18567 {
18568 /* Absolute width `:width WIDTH' specified and valid. */
18569 zero_width_ok_p = 1;
18570 width = (int)tem;
18571 }
18572 else if (prop = Fplist_get (plist, QCrelative_width),
18573 NUMVAL (prop) > 0)
18574 {
18575 /* Relative width `:relative-width FACTOR' specified and valid.
18576 Compute the width of the characters having the `glyph'
18577 property. */
18578 struct it it2;
18579 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18580
18581 it2 = *it;
18582 if (it->multibyte_p)
18583 {
18584 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18585 - IT_BYTEPOS (*it));
18586 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18587 }
18588 else
18589 it2.c = *p, it2.len = 1;
18590
18591 it2.glyph_row = NULL;
18592 it2.what = IT_CHARACTER;
18593 x_produce_glyphs (&it2);
18594 width = NUMVAL (prop) * it2.pixel_width;
18595 }
18596 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18597 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18598 {
18599 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18600 align_to = (align_to < 0
18601 ? 0
18602 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18603 else if (align_to < 0)
18604 align_to = window_box_left_offset (it->w, TEXT_AREA);
18605 width = max (0, (int)tem + align_to - it->current_x);
18606 zero_width_ok_p = 1;
18607 }
18608 else
18609 /* Nothing specified -> width defaults to canonical char width. */
18610 width = FRAME_COLUMN_WIDTH (it->f);
18611
18612 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18613 width = 1;
18614
18615 /* Compute height. */
18616 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18617 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18618 {
18619 height = (int)tem;
18620 zero_height_ok_p = 1;
18621 }
18622 else if (prop = Fplist_get (plist, QCrelative_height),
18623 NUMVAL (prop) > 0)
18624 height = FONT_HEIGHT (font) * NUMVAL (prop);
18625 else
18626 height = FONT_HEIGHT (font);
18627
18628 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18629 height = 1;
18630
18631 /* Compute percentage of height used for ascent. If
18632 `:ascent ASCENT' is present and valid, use that. Otherwise,
18633 derive the ascent from the font in use. */
18634 if (prop = Fplist_get (plist, QCascent),
18635 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18636 ascent = height * NUMVAL (prop) / 100.0;
18637 else if (!NILP (prop)
18638 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18639 ascent = min (max (0, (int)tem), height);
18640 else
18641 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18642
18643 if (width > 0 && height > 0 && it->glyph_row)
18644 {
18645 Lisp_Object object = it->stack[it->sp - 1].string;
18646 if (!STRINGP (object))
18647 object = it->w->buffer;
18648 append_stretch_glyph (it, object, width, height, ascent);
18649 }
18650
18651 it->pixel_width = width;
18652 it->ascent = it->phys_ascent = ascent;
18653 it->descent = it->phys_descent = height - it->ascent;
18654 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18655
18656 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18657 {
18658 if (face->box_line_width > 0)
18659 {
18660 it->ascent += face->box_line_width;
18661 it->descent += face->box_line_width;
18662 }
18663
18664 if (it->start_of_box_run_p)
18665 it->pixel_width += abs (face->box_line_width);
18666 if (it->end_of_box_run_p)
18667 it->pixel_width += abs (face->box_line_width);
18668 }
18669
18670 take_vertical_position_into_account (it);
18671 }
18672
18673 /* Calculate line-height and line-spacing properties.
18674 An integer value specifies explicit pixel value.
18675 A float value specifies relative value to current face height.
18676 A cons (float . face-name) specifies relative value to
18677 height of specified face font.
18678
18679 Returns height in pixels, or nil. */
18680
18681 static Lisp_Object
18682 calc_line_height_property (it, prop, font, boff, total)
18683 struct it *it;
18684 Lisp_Object prop;
18685 XFontStruct *font;
18686 int boff, *total;
18687 {
18688 Lisp_Object position, val;
18689 Lisp_Object face_name = Qnil;
18690 int ascent, descent, height, override;
18691
18692 if (STRINGP (it->object))
18693 position = make_number (IT_STRING_CHARPOS (*it));
18694 else
18695 position = make_number (IT_CHARPOS (*it));
18696
18697 val = Fget_char_property (position, prop, it->object);
18698
18699 if (NILP (val))
18700 return val;
18701
18702 if (total && CONSP (val) && EQ (XCAR (val), Qtotal))
18703 {
18704 *total = 1;
18705 val = XCDR (val);
18706 }
18707
18708 if (INTEGERP (val))
18709 return val;
18710
18711 if (CONSP (val))
18712 {
18713 face_name = XCDR (val);
18714 val = XCAR (val);
18715 }
18716 else if (SYMBOLP (val))
18717 {
18718 face_name = val;
18719 val = Qnil;
18720 }
18721
18722 override = EQ (prop, Qline_height);
18723
18724 if (NILP (face_name))
18725 {
18726 font = FRAME_FONT (it->f);
18727 boff = FRAME_BASELINE_OFFSET (it->f);
18728 }
18729 else if (EQ (face_name, Qt))
18730 {
18731 override = 0;
18732 }
18733 else
18734 {
18735 int face_id;
18736 struct face *face;
18737 struct font_info *font_info;
18738
18739 face_id = lookup_named_face (it->f, face_name, ' ');
18740 if (face_id < 0)
18741 return make_number (-1);
18742
18743 face = FACE_FROM_ID (it->f, face_id);
18744 font = face->font;
18745 if (font == NULL)
18746 return make_number (-1);
18747
18748 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18749 boff = font_info->baseline_offset;
18750 if (font_info->vertical_centering)
18751 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18752 }
18753
18754 ascent = FONT_BASE (font) + boff;
18755 descent = FONT_DESCENT (font) - boff;
18756
18757 if (override)
18758 {
18759 it->override_ascent = ascent;
18760 it->override_descent = descent;
18761 it->override_boff = boff;
18762 }
18763
18764 height = ascent + descent;
18765 if (FLOATP (val))
18766 height = (int)(XFLOAT_DATA (val) * height);
18767 else if (INTEGERP (val))
18768 height *= XINT (val);
18769
18770 return make_number (height);
18771 }
18772
18773
18774 /* RIF:
18775 Produce glyphs/get display metrics for the display element IT is
18776 loaded with. See the description of struct display_iterator in
18777 dispextern.h for an overview of struct display_iterator. */
18778
18779 void
18780 x_produce_glyphs (it)
18781 struct it *it;
18782 {
18783 int extra_line_spacing = it->extra_line_spacing;
18784
18785 it->glyph_not_available_p = 0;
18786
18787 if (it->what == IT_CHARACTER)
18788 {
18789 XChar2b char2b;
18790 XFontStruct *font;
18791 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18792 XCharStruct *pcm;
18793 int font_not_found_p;
18794 struct font_info *font_info;
18795 int boff; /* baseline offset */
18796 /* We may change it->multibyte_p upon unibyte<->multibyte
18797 conversion. So, save the current value now and restore it
18798 later.
18799
18800 Note: It seems that we don't have to record multibyte_p in
18801 struct glyph because the character code itself tells if or
18802 not the character is multibyte. Thus, in the future, we must
18803 consider eliminating the field `multibyte_p' in the struct
18804 glyph. */
18805 int saved_multibyte_p = it->multibyte_p;
18806
18807 /* Maybe translate single-byte characters to multibyte, or the
18808 other way. */
18809 it->char_to_display = it->c;
18810 if (!ASCII_BYTE_P (it->c))
18811 {
18812 if (unibyte_display_via_language_environment
18813 && SINGLE_BYTE_CHAR_P (it->c)
18814 && (it->c >= 0240
18815 || !NILP (Vnonascii_translation_table)))
18816 {
18817 it->char_to_display = unibyte_char_to_multibyte (it->c);
18818 it->multibyte_p = 1;
18819 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18820 face = FACE_FROM_ID (it->f, it->face_id);
18821 }
18822 else if (!SINGLE_BYTE_CHAR_P (it->c)
18823 && !it->multibyte_p)
18824 {
18825 it->multibyte_p = 1;
18826 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18827 face = FACE_FROM_ID (it->f, it->face_id);
18828 }
18829 }
18830
18831 /* Get font to use. Encode IT->char_to_display. */
18832 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18833 &char2b, it->multibyte_p, 0);
18834 font = face->font;
18835
18836 /* When no suitable font found, use the default font. */
18837 font_not_found_p = font == NULL;
18838 if (font_not_found_p)
18839 {
18840 font = FRAME_FONT (it->f);
18841 boff = FRAME_BASELINE_OFFSET (it->f);
18842 font_info = NULL;
18843 }
18844 else
18845 {
18846 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18847 boff = font_info->baseline_offset;
18848 if (font_info->vertical_centering)
18849 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18850 }
18851
18852 if (it->char_to_display >= ' '
18853 && (!it->multibyte_p || it->char_to_display < 128))
18854 {
18855 /* Either unibyte or ASCII. */
18856 int stretched_p;
18857
18858 it->nglyphs = 1;
18859
18860 pcm = rif->per_char_metric (font, &char2b,
18861 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18862
18863 if (it->override_ascent >= 0)
18864 {
18865 it->ascent = it->override_ascent;
18866 it->descent = it->override_descent;
18867 boff = it->override_boff;
18868 }
18869 else
18870 {
18871 it->ascent = FONT_BASE (font) + boff;
18872 it->descent = FONT_DESCENT (font) - boff;
18873 }
18874
18875 if (pcm)
18876 {
18877 it->phys_ascent = pcm->ascent + boff;
18878 it->phys_descent = pcm->descent - boff;
18879 it->pixel_width = pcm->width;
18880 }
18881 else
18882 {
18883 it->glyph_not_available_p = 1;
18884 it->phys_ascent = it->ascent;
18885 it->phys_descent = it->descent;
18886 it->pixel_width = FONT_WIDTH (font);
18887 }
18888
18889 if (it->constrain_row_ascent_descent_p)
18890 {
18891 if (it->descent > it->max_descent)
18892 {
18893 it->ascent += it->descent - it->max_descent;
18894 it->descent = it->max_descent;
18895 }
18896 if (it->ascent > it->max_ascent)
18897 {
18898 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
18899 it->ascent = it->max_ascent;
18900 }
18901 it->phys_ascent = min (it->phys_ascent, it->ascent);
18902 it->phys_descent = min (it->phys_descent, it->descent);
18903 extra_line_spacing = 0;
18904 }
18905
18906 /* If this is a space inside a region of text with
18907 `space-width' property, change its width. */
18908 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18909 if (stretched_p)
18910 it->pixel_width *= XFLOATINT (it->space_width);
18911
18912 /* If face has a box, add the box thickness to the character
18913 height. If character has a box line to the left and/or
18914 right, add the box line width to the character's width. */
18915 if (face->box != FACE_NO_BOX)
18916 {
18917 int thick = face->box_line_width;
18918
18919 if (thick > 0)
18920 {
18921 it->ascent += thick;
18922 it->descent += thick;
18923 }
18924 else
18925 thick = -thick;
18926
18927 if (it->start_of_box_run_p)
18928 it->pixel_width += thick;
18929 if (it->end_of_box_run_p)
18930 it->pixel_width += thick;
18931 }
18932
18933 /* If face has an overline, add the height of the overline
18934 (1 pixel) and a 1 pixel margin to the character height. */
18935 if (face->overline_p)
18936 it->ascent += 2;
18937
18938 if (it->constrain_row_ascent_descent_p)
18939 {
18940 if (it->ascent > it->max_ascent)
18941 it->ascent = it->max_ascent;
18942 if (it->descent > it->max_descent)
18943 it->descent = it->max_descent;
18944 }
18945
18946 take_vertical_position_into_account (it);
18947
18948 /* If we have to actually produce glyphs, do it. */
18949 if (it->glyph_row)
18950 {
18951 if (stretched_p)
18952 {
18953 /* Translate a space with a `space-width' property
18954 into a stretch glyph. */
18955 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18956 / FONT_HEIGHT (font));
18957 append_stretch_glyph (it, it->object, it->pixel_width,
18958 it->ascent + it->descent, ascent);
18959 }
18960 else
18961 append_glyph (it);
18962
18963 /* If characters with lbearing or rbearing are displayed
18964 in this line, record that fact in a flag of the
18965 glyph row. This is used to optimize X output code. */
18966 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18967 it->glyph_row->contains_overlapping_glyphs_p = 1;
18968 }
18969 }
18970 else if (it->char_to_display == '\n')
18971 {
18972 /* A newline has no width but we need the height of the line.
18973 But if previous part of the line set a height, don't
18974 increase that height */
18975
18976 Lisp_Object height;
18977
18978 it->override_ascent = -1;
18979 it->pixel_width = 0;
18980 it->nglyphs = 0;
18981
18982 height = calc_line_height_property(it, Qline_height, font, boff, 0);
18983
18984 if (it->override_ascent >= 0)
18985 {
18986 it->ascent = it->override_ascent;
18987 it->descent = it->override_descent;
18988 boff = it->override_boff;
18989 }
18990 else
18991 {
18992 it->ascent = FONT_BASE (font) + boff;
18993 it->descent = FONT_DESCENT (font) - boff;
18994 }
18995
18996 if (EQ (height, make_number(0)))
18997 {
18998 if (it->descent > it->max_descent)
18999 {
19000 it->ascent += it->descent - it->max_descent;
19001 it->descent = it->max_descent;
19002 }
19003 if (it->ascent > it->max_ascent)
19004 {
19005 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19006 it->ascent = it->max_ascent;
19007 }
19008 it->phys_ascent = min (it->phys_ascent, it->ascent);
19009 it->phys_descent = min (it->phys_descent, it->descent);
19010 it->constrain_row_ascent_descent_p = 1;
19011 extra_line_spacing = 0;
19012 }
19013 else
19014 {
19015 Lisp_Object spacing;
19016 int total = 0;
19017
19018 it->phys_ascent = it->ascent;
19019 it->phys_descent = it->descent;
19020
19021 if ((it->max_ascent > 0 || it->max_descent > 0)
19022 && face->box != FACE_NO_BOX
19023 && face->box_line_width > 0)
19024 {
19025 it->ascent += face->box_line_width;
19026 it->descent += face->box_line_width;
19027 }
19028 if (!NILP (height)
19029 && XINT (height) > it->ascent + it->descent)
19030 it->ascent = XINT (height) - it->descent;
19031
19032 spacing = calc_line_height_property(it, Qline_spacing, font, boff, &total);
19033 if (INTEGERP (spacing))
19034 {
19035 extra_line_spacing = XINT (spacing);
19036 if (total)
19037 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19038 }
19039 }
19040 }
19041 else if (it->char_to_display == '\t')
19042 {
19043 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
19044 int x = it->current_x + it->continuation_lines_width;
19045 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19046
19047 /* If the distance from the current position to the next tab
19048 stop is less than a canonical character width, use the
19049 tab stop after that. */
19050 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
19051 next_tab_x += tab_width;
19052
19053 it->pixel_width = next_tab_x - x;
19054 it->nglyphs = 1;
19055 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19056 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19057
19058 if (it->glyph_row)
19059 {
19060 append_stretch_glyph (it, it->object, it->pixel_width,
19061 it->ascent + it->descent, it->ascent);
19062 }
19063 }
19064 else
19065 {
19066 /* A multi-byte character. Assume that the display width of the
19067 character is the width of the character multiplied by the
19068 width of the font. */
19069
19070 /* If we found a font, this font should give us the right
19071 metrics. If we didn't find a font, use the frame's
19072 default font and calculate the width of the character
19073 from the charset width; this is what old redisplay code
19074 did. */
19075
19076 pcm = rif->per_char_metric (font, &char2b,
19077 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19078
19079 if (font_not_found_p || !pcm)
19080 {
19081 int charset = CHAR_CHARSET (it->char_to_display);
19082
19083 it->glyph_not_available_p = 1;
19084 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19085 * CHARSET_WIDTH (charset));
19086 it->phys_ascent = FONT_BASE (font) + boff;
19087 it->phys_descent = FONT_DESCENT (font) - boff;
19088 }
19089 else
19090 {
19091 it->pixel_width = pcm->width;
19092 it->phys_ascent = pcm->ascent + boff;
19093 it->phys_descent = pcm->descent - boff;
19094 if (it->glyph_row
19095 && (pcm->lbearing < 0
19096 || pcm->rbearing > pcm->width))
19097 it->glyph_row->contains_overlapping_glyphs_p = 1;
19098 }
19099 it->nglyphs = 1;
19100 it->ascent = FONT_BASE (font) + boff;
19101 it->descent = FONT_DESCENT (font) - boff;
19102 if (face->box != FACE_NO_BOX)
19103 {
19104 int thick = face->box_line_width;
19105
19106 if (thick > 0)
19107 {
19108 it->ascent += thick;
19109 it->descent += thick;
19110 }
19111 else
19112 thick = - thick;
19113
19114 if (it->start_of_box_run_p)
19115 it->pixel_width += thick;
19116 if (it->end_of_box_run_p)
19117 it->pixel_width += thick;
19118 }
19119
19120 /* If face has an overline, add the height of the overline
19121 (1 pixel) and a 1 pixel margin to the character height. */
19122 if (face->overline_p)
19123 it->ascent += 2;
19124
19125 take_vertical_position_into_account (it);
19126
19127 if (it->glyph_row)
19128 append_glyph (it);
19129 }
19130 it->multibyte_p = saved_multibyte_p;
19131 }
19132 else if (it->what == IT_COMPOSITION)
19133 {
19134 /* Note: A composition is represented as one glyph in the
19135 glyph matrix. There are no padding glyphs. */
19136 XChar2b char2b;
19137 XFontStruct *font;
19138 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19139 XCharStruct *pcm;
19140 int font_not_found_p;
19141 struct font_info *font_info;
19142 int boff; /* baseline offset */
19143 struct composition *cmp = composition_table[it->cmp_id];
19144
19145 /* Maybe translate single-byte characters to multibyte. */
19146 it->char_to_display = it->c;
19147 if (unibyte_display_via_language_environment
19148 && SINGLE_BYTE_CHAR_P (it->c)
19149 && (it->c >= 0240
19150 || (it->c >= 0200
19151 && !NILP (Vnonascii_translation_table))))
19152 {
19153 it->char_to_display = unibyte_char_to_multibyte (it->c);
19154 }
19155
19156 /* Get face and font to use. Encode IT->char_to_display. */
19157 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19158 face = FACE_FROM_ID (it->f, it->face_id);
19159 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19160 &char2b, it->multibyte_p, 0);
19161 font = face->font;
19162
19163 /* When no suitable font found, use the default font. */
19164 font_not_found_p = font == NULL;
19165 if (font_not_found_p)
19166 {
19167 font = FRAME_FONT (it->f);
19168 boff = FRAME_BASELINE_OFFSET (it->f);
19169 font_info = NULL;
19170 }
19171 else
19172 {
19173 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19174 boff = font_info->baseline_offset;
19175 if (font_info->vertical_centering)
19176 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19177 }
19178
19179 /* There are no padding glyphs, so there is only one glyph to
19180 produce for the composition. Important is that pixel_width,
19181 ascent and descent are the values of what is drawn by
19182 draw_glyphs (i.e. the values of the overall glyphs composed). */
19183 it->nglyphs = 1;
19184
19185 /* If we have not yet calculated pixel size data of glyphs of
19186 the composition for the current face font, calculate them
19187 now. Theoretically, we have to check all fonts for the
19188 glyphs, but that requires much time and memory space. So,
19189 here we check only the font of the first glyph. This leads
19190 to incorrect display very rarely, and C-l (recenter) can
19191 correct the display anyway. */
19192 if (cmp->font != (void *) font)
19193 {
19194 /* Ascent and descent of the font of the first character of
19195 this composition (adjusted by baseline offset). Ascent
19196 and descent of overall glyphs should not be less than
19197 them respectively. */
19198 int font_ascent = FONT_BASE (font) + boff;
19199 int font_descent = FONT_DESCENT (font) - boff;
19200 /* Bounding box of the overall glyphs. */
19201 int leftmost, rightmost, lowest, highest;
19202 int i, width, ascent, descent;
19203
19204 cmp->font = (void *) font;
19205
19206 /* Initialize the bounding box. */
19207 if (font_info
19208 && (pcm = rif->per_char_metric (font, &char2b,
19209 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19210 {
19211 width = pcm->width;
19212 ascent = pcm->ascent;
19213 descent = pcm->descent;
19214 }
19215 else
19216 {
19217 width = FONT_WIDTH (font);
19218 ascent = FONT_BASE (font);
19219 descent = FONT_DESCENT (font);
19220 }
19221
19222 rightmost = width;
19223 lowest = - descent + boff;
19224 highest = ascent + boff;
19225 leftmost = 0;
19226
19227 if (font_info
19228 && font_info->default_ascent
19229 && CHAR_TABLE_P (Vuse_default_ascent)
19230 && !NILP (Faref (Vuse_default_ascent,
19231 make_number (it->char_to_display))))
19232 highest = font_info->default_ascent + boff;
19233
19234 /* Draw the first glyph at the normal position. It may be
19235 shifted to right later if some other glyphs are drawn at
19236 the left. */
19237 cmp->offsets[0] = 0;
19238 cmp->offsets[1] = boff;
19239
19240 /* Set cmp->offsets for the remaining glyphs. */
19241 for (i = 1; i < cmp->glyph_len; i++)
19242 {
19243 int left, right, btm, top;
19244 int ch = COMPOSITION_GLYPH (cmp, i);
19245 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19246
19247 face = FACE_FROM_ID (it->f, face_id);
19248 get_char_face_and_encoding (it->f, ch, face->id,
19249 &char2b, it->multibyte_p, 0);
19250 font = face->font;
19251 if (font == NULL)
19252 {
19253 font = FRAME_FONT (it->f);
19254 boff = FRAME_BASELINE_OFFSET (it->f);
19255 font_info = NULL;
19256 }
19257 else
19258 {
19259 font_info
19260 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19261 boff = font_info->baseline_offset;
19262 if (font_info->vertical_centering)
19263 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19264 }
19265
19266 if (font_info
19267 && (pcm = rif->per_char_metric (font, &char2b,
19268 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19269 {
19270 width = pcm->width;
19271 ascent = pcm->ascent;
19272 descent = pcm->descent;
19273 }
19274 else
19275 {
19276 width = FONT_WIDTH (font);
19277 ascent = 1;
19278 descent = 0;
19279 }
19280
19281 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19282 {
19283 /* Relative composition with or without
19284 alternate chars. */
19285 left = (leftmost + rightmost - width) / 2;
19286 btm = - descent + boff;
19287 if (font_info && font_info->relative_compose
19288 && (! CHAR_TABLE_P (Vignore_relative_composition)
19289 || NILP (Faref (Vignore_relative_composition,
19290 make_number (ch)))))
19291 {
19292
19293 if (- descent >= font_info->relative_compose)
19294 /* One extra pixel between two glyphs. */
19295 btm = highest + 1;
19296 else if (ascent <= 0)
19297 /* One extra pixel between two glyphs. */
19298 btm = lowest - 1 - ascent - descent;
19299 }
19300 }
19301 else
19302 {
19303 /* A composition rule is specified by an integer
19304 value that encodes global and new reference
19305 points (GREF and NREF). GREF and NREF are
19306 specified by numbers as below:
19307
19308 0---1---2 -- ascent
19309 | |
19310 | |
19311 | |
19312 9--10--11 -- center
19313 | |
19314 ---3---4---5--- baseline
19315 | |
19316 6---7---8 -- descent
19317 */
19318 int rule = COMPOSITION_RULE (cmp, i);
19319 int gref, nref, grefx, grefy, nrefx, nrefy;
19320
19321 COMPOSITION_DECODE_RULE (rule, gref, nref);
19322 grefx = gref % 3, nrefx = nref % 3;
19323 grefy = gref / 3, nrefy = nref / 3;
19324
19325 left = (leftmost
19326 + grefx * (rightmost - leftmost) / 2
19327 - nrefx * width / 2);
19328 btm = ((grefy == 0 ? highest
19329 : grefy == 1 ? 0
19330 : grefy == 2 ? lowest
19331 : (highest + lowest) / 2)
19332 - (nrefy == 0 ? ascent + descent
19333 : nrefy == 1 ? descent - boff
19334 : nrefy == 2 ? 0
19335 : (ascent + descent) / 2));
19336 }
19337
19338 cmp->offsets[i * 2] = left;
19339 cmp->offsets[i * 2 + 1] = btm + descent;
19340
19341 /* Update the bounding box of the overall glyphs. */
19342 right = left + width;
19343 top = btm + descent + ascent;
19344 if (left < leftmost)
19345 leftmost = left;
19346 if (right > rightmost)
19347 rightmost = right;
19348 if (top > highest)
19349 highest = top;
19350 if (btm < lowest)
19351 lowest = btm;
19352 }
19353
19354 /* If there are glyphs whose x-offsets are negative,
19355 shift all glyphs to the right and make all x-offsets
19356 non-negative. */
19357 if (leftmost < 0)
19358 {
19359 for (i = 0; i < cmp->glyph_len; i++)
19360 cmp->offsets[i * 2] -= leftmost;
19361 rightmost -= leftmost;
19362 }
19363
19364 cmp->pixel_width = rightmost;
19365 cmp->ascent = highest;
19366 cmp->descent = - lowest;
19367 if (cmp->ascent < font_ascent)
19368 cmp->ascent = font_ascent;
19369 if (cmp->descent < font_descent)
19370 cmp->descent = font_descent;
19371 }
19372
19373 it->pixel_width = cmp->pixel_width;
19374 it->ascent = it->phys_ascent = cmp->ascent;
19375 it->descent = it->phys_descent = cmp->descent;
19376
19377 if (face->box != FACE_NO_BOX)
19378 {
19379 int thick = face->box_line_width;
19380
19381 if (thick > 0)
19382 {
19383 it->ascent += thick;
19384 it->descent += thick;
19385 }
19386 else
19387 thick = - thick;
19388
19389 if (it->start_of_box_run_p)
19390 it->pixel_width += thick;
19391 if (it->end_of_box_run_p)
19392 it->pixel_width += thick;
19393 }
19394
19395 /* If face has an overline, add the height of the overline
19396 (1 pixel) and a 1 pixel margin to the character height. */
19397 if (face->overline_p)
19398 it->ascent += 2;
19399
19400 take_vertical_position_into_account (it);
19401
19402 if (it->glyph_row)
19403 append_composite_glyph (it);
19404 }
19405 else if (it->what == IT_IMAGE)
19406 produce_image_glyph (it);
19407 else if (it->what == IT_STRETCH)
19408 produce_stretch_glyph (it);
19409
19410 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19411 because this isn't true for images with `:ascent 100'. */
19412 xassert (it->ascent >= 0 && it->descent >= 0);
19413 if (it->area == TEXT_AREA)
19414 it->current_x += it->pixel_width;
19415
19416 if (extra_line_spacing > 0)
19417 it->descent += extra_line_spacing;
19418
19419 it->max_ascent = max (it->max_ascent, it->ascent);
19420 it->max_descent = max (it->max_descent, it->descent);
19421 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19422 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19423 }
19424
19425 /* EXPORT for RIF:
19426 Output LEN glyphs starting at START at the nominal cursor position.
19427 Advance the nominal cursor over the text. The global variable
19428 updated_window contains the window being updated, updated_row is
19429 the glyph row being updated, and updated_area is the area of that
19430 row being updated. */
19431
19432 void
19433 x_write_glyphs (start, len)
19434 struct glyph *start;
19435 int len;
19436 {
19437 int x, hpos;
19438
19439 xassert (updated_window && updated_row);
19440 BLOCK_INPUT;
19441
19442 /* Write glyphs. */
19443
19444 hpos = start - updated_row->glyphs[updated_area];
19445 x = draw_glyphs (updated_window, output_cursor.x,
19446 updated_row, updated_area,
19447 hpos, hpos + len,
19448 DRAW_NORMAL_TEXT, 0);
19449
19450 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19451 if (updated_area == TEXT_AREA
19452 && updated_window->phys_cursor_on_p
19453 && updated_window->phys_cursor.vpos == output_cursor.vpos
19454 && updated_window->phys_cursor.hpos >= hpos
19455 && updated_window->phys_cursor.hpos < hpos + len)
19456 updated_window->phys_cursor_on_p = 0;
19457
19458 UNBLOCK_INPUT;
19459
19460 /* Advance the output cursor. */
19461 output_cursor.hpos += len;
19462 output_cursor.x = x;
19463 }
19464
19465
19466 /* EXPORT for RIF:
19467 Insert LEN glyphs from START at the nominal cursor position. */
19468
19469 void
19470 x_insert_glyphs (start, len)
19471 struct glyph *start;
19472 int len;
19473 {
19474 struct frame *f;
19475 struct window *w;
19476 int line_height, shift_by_width, shifted_region_width;
19477 struct glyph_row *row;
19478 struct glyph *glyph;
19479 int frame_x, frame_y, hpos;
19480
19481 xassert (updated_window && updated_row);
19482 BLOCK_INPUT;
19483 w = updated_window;
19484 f = XFRAME (WINDOW_FRAME (w));
19485
19486 /* Get the height of the line we are in. */
19487 row = updated_row;
19488 line_height = row->height;
19489
19490 /* Get the width of the glyphs to insert. */
19491 shift_by_width = 0;
19492 for (glyph = start; glyph < start + len; ++glyph)
19493 shift_by_width += glyph->pixel_width;
19494
19495 /* Get the width of the region to shift right. */
19496 shifted_region_width = (window_box_width (w, updated_area)
19497 - output_cursor.x
19498 - shift_by_width);
19499
19500 /* Shift right. */
19501 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19502 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19503
19504 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19505 line_height, shift_by_width);
19506
19507 /* Write the glyphs. */
19508 hpos = start - row->glyphs[updated_area];
19509 draw_glyphs (w, output_cursor.x, row, updated_area,
19510 hpos, hpos + len,
19511 DRAW_NORMAL_TEXT, 0);
19512
19513 /* Advance the output cursor. */
19514 output_cursor.hpos += len;
19515 output_cursor.x += shift_by_width;
19516 UNBLOCK_INPUT;
19517 }
19518
19519
19520 /* EXPORT for RIF:
19521 Erase the current text line from the nominal cursor position
19522 (inclusive) to pixel column TO_X (exclusive). The idea is that
19523 everything from TO_X onward is already erased.
19524
19525 TO_X is a pixel position relative to updated_area of
19526 updated_window. TO_X == -1 means clear to the end of this area. */
19527
19528 void
19529 x_clear_end_of_line (to_x)
19530 int to_x;
19531 {
19532 struct frame *f;
19533 struct window *w = updated_window;
19534 int max_x, min_y, max_y;
19535 int from_x, from_y, to_y;
19536
19537 xassert (updated_window && updated_row);
19538 f = XFRAME (w->frame);
19539
19540 if (updated_row->full_width_p)
19541 max_x = WINDOW_TOTAL_WIDTH (w);
19542 else
19543 max_x = window_box_width (w, updated_area);
19544 max_y = window_text_bottom_y (w);
19545
19546 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19547 of window. For TO_X > 0, truncate to end of drawing area. */
19548 if (to_x == 0)
19549 return;
19550 else if (to_x < 0)
19551 to_x = max_x;
19552 else
19553 to_x = min (to_x, max_x);
19554
19555 to_y = min (max_y, output_cursor.y + updated_row->height);
19556
19557 /* Notice if the cursor will be cleared by this operation. */
19558 if (!updated_row->full_width_p)
19559 notice_overwritten_cursor (w, updated_area,
19560 output_cursor.x, -1,
19561 updated_row->y,
19562 MATRIX_ROW_BOTTOM_Y (updated_row));
19563
19564 from_x = output_cursor.x;
19565
19566 /* Translate to frame coordinates. */
19567 if (updated_row->full_width_p)
19568 {
19569 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19570 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19571 }
19572 else
19573 {
19574 int area_left = window_box_left (w, updated_area);
19575 from_x += area_left;
19576 to_x += area_left;
19577 }
19578
19579 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19580 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19581 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19582
19583 /* Prevent inadvertently clearing to end of the X window. */
19584 if (to_x > from_x && to_y > from_y)
19585 {
19586 BLOCK_INPUT;
19587 rif->clear_frame_area (f, from_x, from_y,
19588 to_x - from_x, to_y - from_y);
19589 UNBLOCK_INPUT;
19590 }
19591 }
19592
19593 #endif /* HAVE_WINDOW_SYSTEM */
19594
19595
19596 \f
19597 /***********************************************************************
19598 Cursor types
19599 ***********************************************************************/
19600
19601 /* Value is the internal representation of the specified cursor type
19602 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19603 of the bar cursor. */
19604
19605 static enum text_cursor_kinds
19606 get_specified_cursor_type (arg, width)
19607 Lisp_Object arg;
19608 int *width;
19609 {
19610 enum text_cursor_kinds type;
19611
19612 if (NILP (arg))
19613 return NO_CURSOR;
19614
19615 if (EQ (arg, Qbox))
19616 return FILLED_BOX_CURSOR;
19617
19618 if (EQ (arg, Qhollow))
19619 return HOLLOW_BOX_CURSOR;
19620
19621 if (EQ (arg, Qbar))
19622 {
19623 *width = 2;
19624 return BAR_CURSOR;
19625 }
19626
19627 if (CONSP (arg)
19628 && EQ (XCAR (arg), Qbar)
19629 && INTEGERP (XCDR (arg))
19630 && XINT (XCDR (arg)) >= 0)
19631 {
19632 *width = XINT (XCDR (arg));
19633 return BAR_CURSOR;
19634 }
19635
19636 if (EQ (arg, Qhbar))
19637 {
19638 *width = 2;
19639 return HBAR_CURSOR;
19640 }
19641
19642 if (CONSP (arg)
19643 && EQ (XCAR (arg), Qhbar)
19644 && INTEGERP (XCDR (arg))
19645 && XINT (XCDR (arg)) >= 0)
19646 {
19647 *width = XINT (XCDR (arg));
19648 return HBAR_CURSOR;
19649 }
19650
19651 /* Treat anything unknown as "hollow box cursor".
19652 It was bad to signal an error; people have trouble fixing
19653 .Xdefaults with Emacs, when it has something bad in it. */
19654 type = HOLLOW_BOX_CURSOR;
19655
19656 return type;
19657 }
19658
19659 /* Set the default cursor types for specified frame. */
19660 void
19661 set_frame_cursor_types (f, arg)
19662 struct frame *f;
19663 Lisp_Object arg;
19664 {
19665 int width;
19666 Lisp_Object tem;
19667
19668 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19669 FRAME_CURSOR_WIDTH (f) = width;
19670
19671 /* By default, set up the blink-off state depending on the on-state. */
19672
19673 tem = Fassoc (arg, Vblink_cursor_alist);
19674 if (!NILP (tem))
19675 {
19676 FRAME_BLINK_OFF_CURSOR (f)
19677 = get_specified_cursor_type (XCDR (tem), &width);
19678 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19679 }
19680 else
19681 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19682 }
19683
19684
19685 /* Return the cursor we want to be displayed in window W. Return
19686 width of bar/hbar cursor through WIDTH arg. Return with
19687 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19688 (i.e. if the `system caret' should track this cursor).
19689
19690 In a mini-buffer window, we want the cursor only to appear if we
19691 are reading input from this window. For the selected window, we
19692 want the cursor type given by the frame parameter or buffer local
19693 setting of cursor-type. If explicitly marked off, draw no cursor.
19694 In all other cases, we want a hollow box cursor. */
19695
19696 static enum text_cursor_kinds
19697 get_window_cursor_type (w, glyph, width, active_cursor)
19698 struct window *w;
19699 struct glyph *glyph;
19700 int *width;
19701 int *active_cursor;
19702 {
19703 struct frame *f = XFRAME (w->frame);
19704 struct buffer *b = XBUFFER (w->buffer);
19705 int cursor_type = DEFAULT_CURSOR;
19706 Lisp_Object alt_cursor;
19707 int non_selected = 0;
19708
19709 *active_cursor = 1;
19710
19711 /* Echo area */
19712 if (cursor_in_echo_area
19713 && FRAME_HAS_MINIBUF_P (f)
19714 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19715 {
19716 if (w == XWINDOW (echo_area_window))
19717 {
19718 *width = FRAME_CURSOR_WIDTH (f);
19719 return FRAME_DESIRED_CURSOR (f);
19720 }
19721
19722 *active_cursor = 0;
19723 non_selected = 1;
19724 }
19725
19726 /* Nonselected window or nonselected frame. */
19727 else if (w != XWINDOW (f->selected_window)
19728 #ifdef HAVE_WINDOW_SYSTEM
19729 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19730 #endif
19731 )
19732 {
19733 *active_cursor = 0;
19734
19735 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19736 return NO_CURSOR;
19737
19738 non_selected = 1;
19739 }
19740
19741 /* Never display a cursor in a window in which cursor-type is nil. */
19742 if (NILP (b->cursor_type))
19743 return NO_CURSOR;
19744
19745 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19746 if (non_selected)
19747 {
19748 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19749 return get_specified_cursor_type (alt_cursor, width);
19750 }
19751
19752 /* Get the normal cursor type for this window. */
19753 if (EQ (b->cursor_type, Qt))
19754 {
19755 cursor_type = FRAME_DESIRED_CURSOR (f);
19756 *width = FRAME_CURSOR_WIDTH (f);
19757 }
19758 else
19759 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19760
19761 /* Use normal cursor if not blinked off. */
19762 if (!w->cursor_off_p)
19763 {
19764 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19765 if (cursor_type == FILLED_BOX_CURSOR)
19766 cursor_type = HOLLOW_BOX_CURSOR;
19767 }
19768 return cursor_type;
19769 }
19770
19771 /* Cursor is blinked off, so determine how to "toggle" it. */
19772
19773 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19774 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19775 return get_specified_cursor_type (XCDR (alt_cursor), width);
19776
19777 /* Then see if frame has specified a specific blink off cursor type. */
19778 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19779 {
19780 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19781 return FRAME_BLINK_OFF_CURSOR (f);
19782 }
19783
19784 #if 0
19785 /* Some people liked having a permanently visible blinking cursor,
19786 while others had very strong opinions against it. So it was
19787 decided to remove it. KFS 2003-09-03 */
19788
19789 /* Finally perform built-in cursor blinking:
19790 filled box <-> hollow box
19791 wide [h]bar <-> narrow [h]bar
19792 narrow [h]bar <-> no cursor
19793 other type <-> no cursor */
19794
19795 if (cursor_type == FILLED_BOX_CURSOR)
19796 return HOLLOW_BOX_CURSOR;
19797
19798 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19799 {
19800 *width = 1;
19801 return cursor_type;
19802 }
19803 #endif
19804
19805 return NO_CURSOR;
19806 }
19807
19808
19809 #ifdef HAVE_WINDOW_SYSTEM
19810
19811 /* Notice when the text cursor of window W has been completely
19812 overwritten by a drawing operation that outputs glyphs in AREA
19813 starting at X0 and ending at X1 in the line starting at Y0 and
19814 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19815 the rest of the line after X0 has been written. Y coordinates
19816 are window-relative. */
19817
19818 static void
19819 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19820 struct window *w;
19821 enum glyph_row_area area;
19822 int x0, y0, x1, y1;
19823 {
19824 int cx0, cx1, cy0, cy1;
19825 struct glyph_row *row;
19826
19827 if (!w->phys_cursor_on_p)
19828 return;
19829 if (area != TEXT_AREA)
19830 return;
19831
19832 row = w->current_matrix->rows + w->phys_cursor.vpos;
19833 if (!row->displays_text_p)
19834 return;
19835
19836 if (row->cursor_in_fringe_p)
19837 {
19838 row->cursor_in_fringe_p = 0;
19839 draw_fringe_bitmap (w, row, 0);
19840 w->phys_cursor_on_p = 0;
19841 return;
19842 }
19843
19844 cx0 = w->phys_cursor.x;
19845 cx1 = cx0 + w->phys_cursor_width;
19846 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19847 return;
19848
19849 /* The cursor image will be completely removed from the
19850 screen if the output area intersects the cursor area in
19851 y-direction. When we draw in [y0 y1[, and some part of
19852 the cursor is at y < y0, that part must have been drawn
19853 before. When scrolling, the cursor is erased before
19854 actually scrolling, so we don't come here. When not
19855 scrolling, the rows above the old cursor row must have
19856 changed, and in this case these rows must have written
19857 over the cursor image.
19858
19859 Likewise if part of the cursor is below y1, with the
19860 exception of the cursor being in the first blank row at
19861 the buffer and window end because update_text_area
19862 doesn't draw that row. (Except when it does, but
19863 that's handled in update_text_area.) */
19864
19865 cy0 = w->phys_cursor.y;
19866 cy1 = cy0 + w->phys_cursor_height;
19867 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19868 return;
19869
19870 w->phys_cursor_on_p = 0;
19871 }
19872
19873 #endif /* HAVE_WINDOW_SYSTEM */
19874
19875 \f
19876 /************************************************************************
19877 Mouse Face
19878 ************************************************************************/
19879
19880 #ifdef HAVE_WINDOW_SYSTEM
19881
19882 /* EXPORT for RIF:
19883 Fix the display of area AREA of overlapping row ROW in window W. */
19884
19885 void
19886 x_fix_overlapping_area (w, row, area)
19887 struct window *w;
19888 struct glyph_row *row;
19889 enum glyph_row_area area;
19890 {
19891 int i, x;
19892
19893 BLOCK_INPUT;
19894
19895 x = 0;
19896 for (i = 0; i < row->used[area];)
19897 {
19898 if (row->glyphs[area][i].overlaps_vertically_p)
19899 {
19900 int start = i, start_x = x;
19901
19902 do
19903 {
19904 x += row->glyphs[area][i].pixel_width;
19905 ++i;
19906 }
19907 while (i < row->used[area]
19908 && row->glyphs[area][i].overlaps_vertically_p);
19909
19910 draw_glyphs (w, start_x, row, area,
19911 start, i,
19912 DRAW_NORMAL_TEXT, 1);
19913 }
19914 else
19915 {
19916 x += row->glyphs[area][i].pixel_width;
19917 ++i;
19918 }
19919 }
19920
19921 UNBLOCK_INPUT;
19922 }
19923
19924
19925 /* EXPORT:
19926 Draw the cursor glyph of window W in glyph row ROW. See the
19927 comment of draw_glyphs for the meaning of HL. */
19928
19929 void
19930 draw_phys_cursor_glyph (w, row, hl)
19931 struct window *w;
19932 struct glyph_row *row;
19933 enum draw_glyphs_face hl;
19934 {
19935 /* If cursor hpos is out of bounds, don't draw garbage. This can
19936 happen in mini-buffer windows when switching between echo area
19937 glyphs and mini-buffer. */
19938 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19939 {
19940 int on_p = w->phys_cursor_on_p;
19941 int x1;
19942 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19943 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19944 hl, 0);
19945 w->phys_cursor_on_p = on_p;
19946
19947 if (hl == DRAW_CURSOR)
19948 w->phys_cursor_width = x1 - w->phys_cursor.x;
19949 /* When we erase the cursor, and ROW is overlapped by other
19950 rows, make sure that these overlapping parts of other rows
19951 are redrawn. */
19952 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19953 {
19954 if (row > w->current_matrix->rows
19955 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19956 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19957
19958 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19959 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19960 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19961 }
19962 }
19963 }
19964
19965
19966 /* EXPORT:
19967 Erase the image of a cursor of window W from the screen. */
19968
19969 void
19970 erase_phys_cursor (w)
19971 struct window *w;
19972 {
19973 struct frame *f = XFRAME (w->frame);
19974 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19975 int hpos = w->phys_cursor.hpos;
19976 int vpos = w->phys_cursor.vpos;
19977 int mouse_face_here_p = 0;
19978 struct glyph_matrix *active_glyphs = w->current_matrix;
19979 struct glyph_row *cursor_row;
19980 struct glyph *cursor_glyph;
19981 enum draw_glyphs_face hl;
19982
19983 /* No cursor displayed or row invalidated => nothing to do on the
19984 screen. */
19985 if (w->phys_cursor_type == NO_CURSOR)
19986 goto mark_cursor_off;
19987
19988 /* VPOS >= active_glyphs->nrows means that window has been resized.
19989 Don't bother to erase the cursor. */
19990 if (vpos >= active_glyphs->nrows)
19991 goto mark_cursor_off;
19992
19993 /* If row containing cursor is marked invalid, there is nothing we
19994 can do. */
19995 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19996 if (!cursor_row->enabled_p)
19997 goto mark_cursor_off;
19998
19999 /* If row is completely invisible, don't attempt to delete a cursor which
20000 isn't there. This can happen if cursor is at top of a window, and
20001 we switch to a buffer with a header line in that window. */
20002 if (cursor_row->visible_height <= 0)
20003 goto mark_cursor_off;
20004
20005 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20006 if (cursor_row->cursor_in_fringe_p)
20007 {
20008 cursor_row->cursor_in_fringe_p = 0;
20009 draw_fringe_bitmap (w, cursor_row, 0);
20010 goto mark_cursor_off;
20011 }
20012
20013 /* This can happen when the new row is shorter than the old one.
20014 In this case, either draw_glyphs or clear_end_of_line
20015 should have cleared the cursor. Note that we wouldn't be
20016 able to erase the cursor in this case because we don't have a
20017 cursor glyph at hand. */
20018 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20019 goto mark_cursor_off;
20020
20021 /* If the cursor is in the mouse face area, redisplay that when
20022 we clear the cursor. */
20023 if (! NILP (dpyinfo->mouse_face_window)
20024 && w == XWINDOW (dpyinfo->mouse_face_window)
20025 && (vpos > dpyinfo->mouse_face_beg_row
20026 || (vpos == dpyinfo->mouse_face_beg_row
20027 && hpos >= dpyinfo->mouse_face_beg_col))
20028 && (vpos < dpyinfo->mouse_face_end_row
20029 || (vpos == dpyinfo->mouse_face_end_row
20030 && hpos < dpyinfo->mouse_face_end_col))
20031 /* Don't redraw the cursor's spot in mouse face if it is at the
20032 end of a line (on a newline). The cursor appears there, but
20033 mouse highlighting does not. */
20034 && cursor_row->used[TEXT_AREA] > hpos)
20035 mouse_face_here_p = 1;
20036
20037 /* Maybe clear the display under the cursor. */
20038 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20039 {
20040 int x, y;
20041 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20042
20043 cursor_glyph = get_phys_cursor_glyph (w);
20044 if (cursor_glyph == NULL)
20045 goto mark_cursor_off;
20046
20047 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20048 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20049
20050 rif->clear_frame_area (f, x, y,
20051 cursor_glyph->pixel_width, cursor_row->visible_height);
20052 }
20053
20054 /* Erase the cursor by redrawing the character underneath it. */
20055 if (mouse_face_here_p)
20056 hl = DRAW_MOUSE_FACE;
20057 else
20058 hl = DRAW_NORMAL_TEXT;
20059 draw_phys_cursor_glyph (w, cursor_row, hl);
20060
20061 mark_cursor_off:
20062 w->phys_cursor_on_p = 0;
20063 w->phys_cursor_type = NO_CURSOR;
20064 }
20065
20066
20067 /* EXPORT:
20068 Display or clear cursor of window W. If ON is zero, clear the
20069 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20070 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20071
20072 void
20073 display_and_set_cursor (w, on, hpos, vpos, x, y)
20074 struct window *w;
20075 int on, hpos, vpos, x, y;
20076 {
20077 struct frame *f = XFRAME (w->frame);
20078 int new_cursor_type;
20079 int new_cursor_width;
20080 int active_cursor;
20081 struct glyph_row *glyph_row;
20082 struct glyph *glyph;
20083
20084 /* This is pointless on invisible frames, and dangerous on garbaged
20085 windows and frames; in the latter case, the frame or window may
20086 be in the midst of changing its size, and x and y may be off the
20087 window. */
20088 if (! FRAME_VISIBLE_P (f)
20089 || FRAME_GARBAGED_P (f)
20090 || vpos >= w->current_matrix->nrows
20091 || hpos >= w->current_matrix->matrix_w)
20092 return;
20093
20094 /* If cursor is off and we want it off, return quickly. */
20095 if (!on && !w->phys_cursor_on_p)
20096 return;
20097
20098 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20099 /* If cursor row is not enabled, we don't really know where to
20100 display the cursor. */
20101 if (!glyph_row->enabled_p)
20102 {
20103 w->phys_cursor_on_p = 0;
20104 return;
20105 }
20106
20107 glyph = NULL;
20108 if (!glyph_row->exact_window_width_line_p
20109 || hpos < glyph_row->used[TEXT_AREA])
20110 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20111
20112 xassert (interrupt_input_blocked);
20113
20114 /* Set new_cursor_type to the cursor we want to be displayed. */
20115 new_cursor_type = get_window_cursor_type (w, glyph,
20116 &new_cursor_width, &active_cursor);
20117
20118 /* If cursor is currently being shown and we don't want it to be or
20119 it is in the wrong place, or the cursor type is not what we want,
20120 erase it. */
20121 if (w->phys_cursor_on_p
20122 && (!on
20123 || w->phys_cursor.x != x
20124 || w->phys_cursor.y != y
20125 || new_cursor_type != w->phys_cursor_type
20126 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20127 && new_cursor_width != w->phys_cursor_width)))
20128 erase_phys_cursor (w);
20129
20130 /* Don't check phys_cursor_on_p here because that flag is only set
20131 to zero in some cases where we know that the cursor has been
20132 completely erased, to avoid the extra work of erasing the cursor
20133 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20134 still not be visible, or it has only been partly erased. */
20135 if (on)
20136 {
20137 w->phys_cursor_ascent = glyph_row->ascent;
20138 w->phys_cursor_height = glyph_row->height;
20139
20140 /* Set phys_cursor_.* before x_draw_.* is called because some
20141 of them may need the information. */
20142 w->phys_cursor.x = x;
20143 w->phys_cursor.y = glyph_row->y;
20144 w->phys_cursor.hpos = hpos;
20145 w->phys_cursor.vpos = vpos;
20146 }
20147
20148 rif->draw_window_cursor (w, glyph_row, x, y,
20149 new_cursor_type, new_cursor_width,
20150 on, active_cursor);
20151 }
20152
20153
20154 /* Switch the display of W's cursor on or off, according to the value
20155 of ON. */
20156
20157 static void
20158 update_window_cursor (w, on)
20159 struct window *w;
20160 int on;
20161 {
20162 /* Don't update cursor in windows whose frame is in the process
20163 of being deleted. */
20164 if (w->current_matrix)
20165 {
20166 BLOCK_INPUT;
20167 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20168 w->phys_cursor.x, w->phys_cursor.y);
20169 UNBLOCK_INPUT;
20170 }
20171 }
20172
20173
20174 /* Call update_window_cursor with parameter ON_P on all leaf windows
20175 in the window tree rooted at W. */
20176
20177 static void
20178 update_cursor_in_window_tree (w, on_p)
20179 struct window *w;
20180 int on_p;
20181 {
20182 while (w)
20183 {
20184 if (!NILP (w->hchild))
20185 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20186 else if (!NILP (w->vchild))
20187 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20188 else
20189 update_window_cursor (w, on_p);
20190
20191 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20192 }
20193 }
20194
20195
20196 /* EXPORT:
20197 Display the cursor on window W, or clear it, according to ON_P.
20198 Don't change the cursor's position. */
20199
20200 void
20201 x_update_cursor (f, on_p)
20202 struct frame *f;
20203 int on_p;
20204 {
20205 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20206 }
20207
20208
20209 /* EXPORT:
20210 Clear the cursor of window W to background color, and mark the
20211 cursor as not shown. This is used when the text where the cursor
20212 is is about to be rewritten. */
20213
20214 void
20215 x_clear_cursor (w)
20216 struct window *w;
20217 {
20218 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20219 update_window_cursor (w, 0);
20220 }
20221
20222
20223 /* EXPORT:
20224 Display the active region described by mouse_face_* according to DRAW. */
20225
20226 void
20227 show_mouse_face (dpyinfo, draw)
20228 Display_Info *dpyinfo;
20229 enum draw_glyphs_face draw;
20230 {
20231 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20232 struct frame *f = XFRAME (WINDOW_FRAME (w));
20233
20234 if (/* If window is in the process of being destroyed, don't bother
20235 to do anything. */
20236 w->current_matrix != NULL
20237 /* Don't update mouse highlight if hidden */
20238 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20239 /* Recognize when we are called to operate on rows that don't exist
20240 anymore. This can happen when a window is split. */
20241 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20242 {
20243 int phys_cursor_on_p = w->phys_cursor_on_p;
20244 struct glyph_row *row, *first, *last;
20245
20246 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20247 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20248
20249 for (row = first; row <= last && row->enabled_p; ++row)
20250 {
20251 int start_hpos, end_hpos, start_x;
20252
20253 /* For all but the first row, the highlight starts at column 0. */
20254 if (row == first)
20255 {
20256 start_hpos = dpyinfo->mouse_face_beg_col;
20257 start_x = dpyinfo->mouse_face_beg_x;
20258 }
20259 else
20260 {
20261 start_hpos = 0;
20262 start_x = 0;
20263 }
20264
20265 if (row == last)
20266 end_hpos = dpyinfo->mouse_face_end_col;
20267 else
20268 end_hpos = row->used[TEXT_AREA];
20269
20270 if (end_hpos > start_hpos)
20271 {
20272 draw_glyphs (w, start_x, row, TEXT_AREA,
20273 start_hpos, end_hpos,
20274 draw, 0);
20275
20276 row->mouse_face_p
20277 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20278 }
20279 }
20280
20281 /* When we've written over the cursor, arrange for it to
20282 be displayed again. */
20283 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20284 {
20285 BLOCK_INPUT;
20286 display_and_set_cursor (w, 1,
20287 w->phys_cursor.hpos, w->phys_cursor.vpos,
20288 w->phys_cursor.x, w->phys_cursor.y);
20289 UNBLOCK_INPUT;
20290 }
20291 }
20292
20293 /* Change the mouse cursor. */
20294 if (draw == DRAW_NORMAL_TEXT)
20295 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20296 else if (draw == DRAW_MOUSE_FACE)
20297 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20298 else
20299 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20300 }
20301
20302 /* EXPORT:
20303 Clear out the mouse-highlighted active region.
20304 Redraw it un-highlighted first. Value is non-zero if mouse
20305 face was actually drawn unhighlighted. */
20306
20307 int
20308 clear_mouse_face (dpyinfo)
20309 Display_Info *dpyinfo;
20310 {
20311 int cleared = 0;
20312
20313 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20314 {
20315 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20316 cleared = 1;
20317 }
20318
20319 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20320 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20321 dpyinfo->mouse_face_window = Qnil;
20322 dpyinfo->mouse_face_overlay = Qnil;
20323 return cleared;
20324 }
20325
20326
20327 /* EXPORT:
20328 Non-zero if physical cursor of window W is within mouse face. */
20329
20330 int
20331 cursor_in_mouse_face_p (w)
20332 struct window *w;
20333 {
20334 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20335 int in_mouse_face = 0;
20336
20337 if (WINDOWP (dpyinfo->mouse_face_window)
20338 && XWINDOW (dpyinfo->mouse_face_window) == w)
20339 {
20340 int hpos = w->phys_cursor.hpos;
20341 int vpos = w->phys_cursor.vpos;
20342
20343 if (vpos >= dpyinfo->mouse_face_beg_row
20344 && vpos <= dpyinfo->mouse_face_end_row
20345 && (vpos > dpyinfo->mouse_face_beg_row
20346 || hpos >= dpyinfo->mouse_face_beg_col)
20347 && (vpos < dpyinfo->mouse_face_end_row
20348 || hpos < dpyinfo->mouse_face_end_col
20349 || dpyinfo->mouse_face_past_end))
20350 in_mouse_face = 1;
20351 }
20352
20353 return in_mouse_face;
20354 }
20355
20356
20357
20358 \f
20359 /* Find the glyph matrix position of buffer position CHARPOS in window
20360 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20361 current glyphs must be up to date. If CHARPOS is above window
20362 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20363 of last line in W. In the row containing CHARPOS, stop before glyphs
20364 having STOP as object. */
20365
20366 #if 1 /* This is a version of fast_find_position that's more correct
20367 in the presence of hscrolling, for example. I didn't install
20368 it right away because the problem fixed is minor, it failed
20369 in 20.x as well, and I think it's too risky to install
20370 so near the release of 21.1. 2001-09-25 gerd. */
20371
20372 static int
20373 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20374 struct window *w;
20375 int charpos;
20376 int *hpos, *vpos, *x, *y;
20377 Lisp_Object stop;
20378 {
20379 struct glyph_row *row, *first;
20380 struct glyph *glyph, *end;
20381 int past_end = 0;
20382
20383 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20384 row = row_containing_pos (w, charpos, first, NULL, 0);
20385 if (row == NULL)
20386 {
20387 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20388 {
20389 *x = *y = *hpos = *vpos = 0;
20390 return 1;
20391 }
20392 else
20393 {
20394 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20395 past_end = 1;
20396 }
20397 }
20398
20399 *x = row->x;
20400 *y = row->y;
20401 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20402
20403 glyph = row->glyphs[TEXT_AREA];
20404 end = glyph + row->used[TEXT_AREA];
20405
20406 /* Skip over glyphs not having an object at the start of the row.
20407 These are special glyphs like truncation marks on terminal
20408 frames. */
20409 if (row->displays_text_p)
20410 while (glyph < end
20411 && INTEGERP (glyph->object)
20412 && !EQ (stop, glyph->object)
20413 && glyph->charpos < 0)
20414 {
20415 *x += glyph->pixel_width;
20416 ++glyph;
20417 }
20418
20419 while (glyph < end
20420 && !INTEGERP (glyph->object)
20421 && !EQ (stop, glyph->object)
20422 && (!BUFFERP (glyph->object)
20423 || glyph->charpos < charpos))
20424 {
20425 *x += glyph->pixel_width;
20426 ++glyph;
20427 }
20428
20429 *hpos = glyph - row->glyphs[TEXT_AREA];
20430 return !past_end;
20431 }
20432
20433 #else /* not 1 */
20434
20435 static int
20436 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20437 struct window *w;
20438 int pos;
20439 int *hpos, *vpos, *x, *y;
20440 Lisp_Object stop;
20441 {
20442 int i;
20443 int lastcol;
20444 int maybe_next_line_p = 0;
20445 int line_start_position;
20446 int yb = window_text_bottom_y (w);
20447 struct glyph_row *row, *best_row;
20448 int row_vpos, best_row_vpos;
20449 int current_x;
20450
20451 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20452 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20453
20454 while (row->y < yb)
20455 {
20456 if (row->used[TEXT_AREA])
20457 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20458 else
20459 line_start_position = 0;
20460
20461 if (line_start_position > pos)
20462 break;
20463 /* If the position sought is the end of the buffer,
20464 don't include the blank lines at the bottom of the window. */
20465 else if (line_start_position == pos
20466 && pos == BUF_ZV (XBUFFER (w->buffer)))
20467 {
20468 maybe_next_line_p = 1;
20469 break;
20470 }
20471 else if (line_start_position > 0)
20472 {
20473 best_row = row;
20474 best_row_vpos = row_vpos;
20475 }
20476
20477 if (row->y + row->height >= yb)
20478 break;
20479
20480 ++row;
20481 ++row_vpos;
20482 }
20483
20484 /* Find the right column within BEST_ROW. */
20485 lastcol = 0;
20486 current_x = best_row->x;
20487 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20488 {
20489 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20490 int charpos = glyph->charpos;
20491
20492 if (BUFFERP (glyph->object))
20493 {
20494 if (charpos == pos)
20495 {
20496 *hpos = i;
20497 *vpos = best_row_vpos;
20498 *x = current_x;
20499 *y = best_row->y;
20500 return 1;
20501 }
20502 else if (charpos > pos)
20503 break;
20504 }
20505 else if (EQ (glyph->object, stop))
20506 break;
20507
20508 if (charpos > 0)
20509 lastcol = i;
20510 current_x += glyph->pixel_width;
20511 }
20512
20513 /* If we're looking for the end of the buffer,
20514 and we didn't find it in the line we scanned,
20515 use the start of the following line. */
20516 if (maybe_next_line_p)
20517 {
20518 ++best_row;
20519 ++best_row_vpos;
20520 lastcol = 0;
20521 current_x = best_row->x;
20522 }
20523
20524 *vpos = best_row_vpos;
20525 *hpos = lastcol + 1;
20526 *x = current_x;
20527 *y = best_row->y;
20528 return 0;
20529 }
20530
20531 #endif /* not 1 */
20532
20533
20534 /* Find the position of the glyph for position POS in OBJECT in
20535 window W's current matrix, and return in *X, *Y the pixel
20536 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20537
20538 RIGHT_P non-zero means return the position of the right edge of the
20539 glyph, RIGHT_P zero means return the left edge position.
20540
20541 If no glyph for POS exists in the matrix, return the position of
20542 the glyph with the next smaller position that is in the matrix, if
20543 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20544 exists in the matrix, return the position of the glyph with the
20545 next larger position in OBJECT.
20546
20547 Value is non-zero if a glyph was found. */
20548
20549 static int
20550 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20551 struct window *w;
20552 int pos;
20553 Lisp_Object object;
20554 int *hpos, *vpos, *x, *y;
20555 int right_p;
20556 {
20557 int yb = window_text_bottom_y (w);
20558 struct glyph_row *r;
20559 struct glyph *best_glyph = NULL;
20560 struct glyph_row *best_row = NULL;
20561 int best_x = 0;
20562
20563 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20564 r->enabled_p && r->y < yb;
20565 ++r)
20566 {
20567 struct glyph *g = r->glyphs[TEXT_AREA];
20568 struct glyph *e = g + r->used[TEXT_AREA];
20569 int gx;
20570
20571 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20572 if (EQ (g->object, object))
20573 {
20574 if (g->charpos == pos)
20575 {
20576 best_glyph = g;
20577 best_x = gx;
20578 best_row = r;
20579 goto found;
20580 }
20581 else if (best_glyph == NULL
20582 || ((abs (g->charpos - pos)
20583 < abs (best_glyph->charpos - pos))
20584 && (right_p
20585 ? g->charpos < pos
20586 : g->charpos > pos)))
20587 {
20588 best_glyph = g;
20589 best_x = gx;
20590 best_row = r;
20591 }
20592 }
20593 }
20594
20595 found:
20596
20597 if (best_glyph)
20598 {
20599 *x = best_x;
20600 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20601
20602 if (right_p)
20603 {
20604 *x += best_glyph->pixel_width;
20605 ++*hpos;
20606 }
20607
20608 *y = best_row->y;
20609 *vpos = best_row - w->current_matrix->rows;
20610 }
20611
20612 return best_glyph != NULL;
20613 }
20614
20615
20616 /* See if position X, Y is within a hot-spot of an image. */
20617
20618 static int
20619 on_hot_spot_p (hot_spot, x, y)
20620 Lisp_Object hot_spot;
20621 int x, y;
20622 {
20623 if (!CONSP (hot_spot))
20624 return 0;
20625
20626 if (EQ (XCAR (hot_spot), Qrect))
20627 {
20628 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20629 Lisp_Object rect = XCDR (hot_spot);
20630 Lisp_Object tem;
20631 if (!CONSP (rect))
20632 return 0;
20633 if (!CONSP (XCAR (rect)))
20634 return 0;
20635 if (!CONSP (XCDR (rect)))
20636 return 0;
20637 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20638 return 0;
20639 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20640 return 0;
20641 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20642 return 0;
20643 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20644 return 0;
20645 return 1;
20646 }
20647 else if (EQ (XCAR (hot_spot), Qcircle))
20648 {
20649 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20650 Lisp_Object circ = XCDR (hot_spot);
20651 Lisp_Object lr, lx0, ly0;
20652 if (CONSP (circ)
20653 && CONSP (XCAR (circ))
20654 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20655 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20656 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20657 {
20658 double r = XFLOATINT (lr);
20659 double dx = XINT (lx0) - x;
20660 double dy = XINT (ly0) - y;
20661 return (dx * dx + dy * dy <= r * r);
20662 }
20663 }
20664 else if (EQ (XCAR (hot_spot), Qpoly))
20665 {
20666 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20667 if (VECTORP (XCDR (hot_spot)))
20668 {
20669 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20670 Lisp_Object *poly = v->contents;
20671 int n = v->size;
20672 int i;
20673 int inside = 0;
20674 Lisp_Object lx, ly;
20675 int x0, y0;
20676
20677 /* Need an even number of coordinates, and at least 3 edges. */
20678 if (n < 6 || n & 1)
20679 return 0;
20680
20681 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20682 If count is odd, we are inside polygon. Pixels on edges
20683 may or may not be included depending on actual geometry of the
20684 polygon. */
20685 if ((lx = poly[n-2], !INTEGERP (lx))
20686 || (ly = poly[n-1], !INTEGERP (lx)))
20687 return 0;
20688 x0 = XINT (lx), y0 = XINT (ly);
20689 for (i = 0; i < n; i += 2)
20690 {
20691 int x1 = x0, y1 = y0;
20692 if ((lx = poly[i], !INTEGERP (lx))
20693 || (ly = poly[i+1], !INTEGERP (ly)))
20694 return 0;
20695 x0 = XINT (lx), y0 = XINT (ly);
20696
20697 /* Does this segment cross the X line? */
20698 if (x0 >= x)
20699 {
20700 if (x1 >= x)
20701 continue;
20702 }
20703 else if (x1 < x)
20704 continue;
20705 if (y > y0 && y > y1)
20706 continue;
20707 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20708 inside = !inside;
20709 }
20710 return inside;
20711 }
20712 }
20713 /* If we don't understand the format, pretend we're not in the hot-spot. */
20714 return 0;
20715 }
20716
20717 Lisp_Object
20718 find_hot_spot (map, x, y)
20719 Lisp_Object map;
20720 int x, y;
20721 {
20722 while (CONSP (map))
20723 {
20724 if (CONSP (XCAR (map))
20725 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20726 return XCAR (map);
20727 map = XCDR (map);
20728 }
20729
20730 return Qnil;
20731 }
20732
20733 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20734 3, 3, 0,
20735 doc: /* Lookup in image map MAP coordinates X and Y.
20736 An image map is an alist where each element has the format (AREA ID PLIST).
20737 An AREA is specified as either a rectangle, a circle, or a polygon:
20738 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20739 pixel coordinates of the upper left and bottom right corners.
20740 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20741 and the radius of the circle; r may be a float or integer.
20742 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20743 vector describes one corner in the polygon.
20744 Returns the alist element for the first matching AREA in MAP. */)
20745 (map, x, y)
20746 Lisp_Object map;
20747 Lisp_Object x, y;
20748 {
20749 if (NILP (map))
20750 return Qnil;
20751
20752 CHECK_NUMBER (x);
20753 CHECK_NUMBER (y);
20754
20755 return find_hot_spot (map, XINT (x), XINT (y));
20756 }
20757
20758
20759 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20760 static void
20761 define_frame_cursor1 (f, cursor, pointer)
20762 struct frame *f;
20763 Cursor cursor;
20764 Lisp_Object pointer;
20765 {
20766 if (!NILP (pointer))
20767 {
20768 if (EQ (pointer, Qarrow))
20769 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20770 else if (EQ (pointer, Qhand))
20771 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20772 else if (EQ (pointer, Qtext))
20773 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20774 else if (EQ (pointer, intern ("hdrag")))
20775 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20776 #ifdef HAVE_X_WINDOWS
20777 else if (EQ (pointer, intern ("vdrag")))
20778 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20779 #endif
20780 else if (EQ (pointer, intern ("hourglass")))
20781 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20782 else if (EQ (pointer, Qmodeline))
20783 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20784 else
20785 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20786 }
20787
20788 if (cursor != No_Cursor)
20789 rif->define_frame_cursor (f, cursor);
20790 }
20791
20792 /* Take proper action when mouse has moved to the mode or header line
20793 or marginal area AREA of window W, x-position X and y-position Y.
20794 X is relative to the start of the text display area of W, so the
20795 width of bitmap areas and scroll bars must be subtracted to get a
20796 position relative to the start of the mode line. */
20797
20798 static void
20799 note_mode_line_or_margin_highlight (w, x, y, area)
20800 struct window *w;
20801 int x, y;
20802 enum window_part area;
20803 {
20804 struct frame *f = XFRAME (w->frame);
20805 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20806 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20807 Lisp_Object pointer = Qnil;
20808 int charpos, dx, dy, width, height;
20809 Lisp_Object string, object = Qnil;
20810 Lisp_Object pos, help;
20811
20812 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20813 string = mode_line_string (w, area, &x, &y, &charpos,
20814 &object, &dx, &dy, &width, &height);
20815 else
20816 {
20817 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20818 string = marginal_area_string (w, area, &x, &y, &charpos,
20819 &object, &dx, &dy, &width, &height);
20820 }
20821
20822 help = Qnil;
20823
20824 if (IMAGEP (object))
20825 {
20826 Lisp_Object image_map, hotspot;
20827 if ((image_map = Fplist_get (XCDR (object), QCmap),
20828 !NILP (image_map))
20829 && (hotspot = find_hot_spot (image_map, dx, dy),
20830 CONSP (hotspot))
20831 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20832 {
20833 Lisp_Object area_id, plist;
20834
20835 area_id = XCAR (hotspot);
20836 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20837 If so, we could look for mouse-enter, mouse-leave
20838 properties in PLIST (and do something...). */
20839 if ((plist = XCDR (hotspot), CONSP (plist)))
20840 {
20841 pointer = Fplist_get (plist, Qpointer);
20842 if (NILP (pointer))
20843 pointer = Qhand;
20844 help = Fplist_get (plist, Qhelp_echo);
20845 if (!NILP (help))
20846 {
20847 help_echo_string = help;
20848 /* Is this correct? ++kfs */
20849 XSETWINDOW (help_echo_window, w);
20850 help_echo_object = w->buffer;
20851 help_echo_pos = charpos;
20852 }
20853 }
20854 if (NILP (pointer))
20855 pointer = Fplist_get (XCDR (object), QCpointer);
20856 }
20857 }
20858
20859 if (STRINGP (string))
20860 {
20861 pos = make_number (charpos);
20862 /* If we're on a string with `help-echo' text property, arrange
20863 for the help to be displayed. This is done by setting the
20864 global variable help_echo_string to the help string. */
20865 help = Fget_text_property (pos, Qhelp_echo, string);
20866 if (!NILP (help))
20867 {
20868 help_echo_string = help;
20869 XSETWINDOW (help_echo_window, w);
20870 help_echo_object = string;
20871 help_echo_pos = charpos;
20872 }
20873
20874 if (NILP (pointer))
20875 pointer = Fget_text_property (pos, Qpointer, string);
20876
20877 /* Change the mouse pointer according to what is under X/Y. */
20878 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20879 {
20880 Lisp_Object map;
20881 map = Fget_text_property (pos, Qlocal_map, string);
20882 if (!KEYMAPP (map))
20883 map = Fget_text_property (pos, Qkeymap, string);
20884 if (!KEYMAPP (map))
20885 cursor = dpyinfo->vertical_scroll_bar_cursor;
20886 }
20887 }
20888
20889 define_frame_cursor1 (f, cursor, pointer);
20890 }
20891
20892
20893 /* EXPORT:
20894 Take proper action when the mouse has moved to position X, Y on
20895 frame F as regards highlighting characters that have mouse-face
20896 properties. Also de-highlighting chars where the mouse was before.
20897 X and Y can be negative or out of range. */
20898
20899 void
20900 note_mouse_highlight (f, x, y)
20901 struct frame *f;
20902 int x, y;
20903 {
20904 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20905 enum window_part part;
20906 Lisp_Object window;
20907 struct window *w;
20908 Cursor cursor = No_Cursor;
20909 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20910 struct buffer *b;
20911
20912 /* When a menu is active, don't highlight because this looks odd. */
20913 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20914 if (popup_activated ())
20915 return;
20916 #endif
20917
20918 if (NILP (Vmouse_highlight)
20919 || !f->glyphs_initialized_p)
20920 return;
20921
20922 dpyinfo->mouse_face_mouse_x = x;
20923 dpyinfo->mouse_face_mouse_y = y;
20924 dpyinfo->mouse_face_mouse_frame = f;
20925
20926 if (dpyinfo->mouse_face_defer)
20927 return;
20928
20929 if (gc_in_progress)
20930 {
20931 dpyinfo->mouse_face_deferred_gc = 1;
20932 return;
20933 }
20934
20935 /* Which window is that in? */
20936 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20937
20938 /* If we were displaying active text in another window, clear that. */
20939 if (! EQ (window, dpyinfo->mouse_face_window))
20940 clear_mouse_face (dpyinfo);
20941
20942 /* Not on a window -> return. */
20943 if (!WINDOWP (window))
20944 return;
20945
20946 /* Reset help_echo_string. It will get recomputed below. */
20947 help_echo_string = Qnil;
20948
20949 /* Convert to window-relative pixel coordinates. */
20950 w = XWINDOW (window);
20951 frame_to_window_pixel_xy (w, &x, &y);
20952
20953 /* Handle tool-bar window differently since it doesn't display a
20954 buffer. */
20955 if (EQ (window, f->tool_bar_window))
20956 {
20957 note_tool_bar_highlight (f, x, y);
20958 return;
20959 }
20960
20961 /* Mouse is on the mode, header line or margin? */
20962 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20963 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20964 {
20965 note_mode_line_or_margin_highlight (w, x, y, part);
20966 return;
20967 }
20968
20969 if (part == ON_VERTICAL_BORDER)
20970 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20971 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
20972 || part == ON_SCROLL_BAR)
20973 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20974 else
20975 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20976
20977 /* Are we in a window whose display is up to date?
20978 And verify the buffer's text has not changed. */
20979 b = XBUFFER (w->buffer);
20980 if (part == ON_TEXT
20981 && EQ (w->window_end_valid, w->buffer)
20982 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20983 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20984 {
20985 int hpos, vpos, pos, i, dx, dy, area;
20986 struct glyph *glyph;
20987 Lisp_Object object;
20988 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20989 Lisp_Object *overlay_vec = NULL;
20990 int noverlays;
20991 struct buffer *obuf;
20992 int obegv, ozv, same_region;
20993
20994 /* Find the glyph under X/Y. */
20995 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20996
20997 /* Look for :pointer property on image. */
20998 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20999 {
21000 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21001 if (img != NULL && IMAGEP (img->spec))
21002 {
21003 Lisp_Object image_map, hotspot;
21004 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
21005 !NILP (image_map))
21006 && (hotspot = find_hot_spot (image_map,
21007 glyph->slice.x + dx,
21008 glyph->slice.y + dy),
21009 CONSP (hotspot))
21010 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21011 {
21012 Lisp_Object area_id, plist;
21013
21014 area_id = XCAR (hotspot);
21015 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21016 If so, we could look for mouse-enter, mouse-leave
21017 properties in PLIST (and do something...). */
21018 if ((plist = XCDR (hotspot), CONSP (plist)))
21019 {
21020 pointer = Fplist_get (plist, Qpointer);
21021 if (NILP (pointer))
21022 pointer = Qhand;
21023 help_echo_string = Fplist_get (plist, Qhelp_echo);
21024 if (!NILP (help_echo_string))
21025 {
21026 help_echo_window = window;
21027 help_echo_object = glyph->object;
21028 help_echo_pos = glyph->charpos;
21029 }
21030 }
21031 }
21032 if (NILP (pointer))
21033 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21034 }
21035 }
21036
21037 /* Clear mouse face if X/Y not over text. */
21038 if (glyph == NULL
21039 || area != TEXT_AREA
21040 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21041 {
21042 if (clear_mouse_face (dpyinfo))
21043 cursor = No_Cursor;
21044 if (NILP (pointer))
21045 {
21046 if (area != TEXT_AREA)
21047 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21048 else
21049 pointer = Vvoid_text_area_pointer;
21050 }
21051 goto set_cursor;
21052 }
21053
21054 pos = glyph->charpos;
21055 object = glyph->object;
21056 if (!STRINGP (object) && !BUFFERP (object))
21057 goto set_cursor;
21058
21059 /* If we get an out-of-range value, return now; avoid an error. */
21060 if (BUFFERP (object) && pos > BUF_Z (b))
21061 goto set_cursor;
21062
21063 /* Make the window's buffer temporarily current for
21064 overlays_at and compute_char_face. */
21065 obuf = current_buffer;
21066 current_buffer = b;
21067 obegv = BEGV;
21068 ozv = ZV;
21069 BEGV = BEG;
21070 ZV = Z;
21071
21072 /* Is this char mouse-active or does it have help-echo? */
21073 position = make_number (pos);
21074
21075 if (BUFFERP (object))
21076 {
21077 /* Put all the overlays we want in a vector in overlay_vec. */
21078 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21079 /* Sort overlays into increasing priority order. */
21080 noverlays = sort_overlays (overlay_vec, noverlays, w);
21081 }
21082 else
21083 noverlays = 0;
21084
21085 same_region = (EQ (window, dpyinfo->mouse_face_window)
21086 && vpos >= dpyinfo->mouse_face_beg_row
21087 && vpos <= dpyinfo->mouse_face_end_row
21088 && (vpos > dpyinfo->mouse_face_beg_row
21089 || hpos >= dpyinfo->mouse_face_beg_col)
21090 && (vpos < dpyinfo->mouse_face_end_row
21091 || hpos < dpyinfo->mouse_face_end_col
21092 || dpyinfo->mouse_face_past_end));
21093
21094 if (same_region)
21095 cursor = No_Cursor;
21096
21097 /* Check mouse-face highlighting. */
21098 if (! same_region
21099 /* If there exists an overlay with mouse-face overlapping
21100 the one we are currently highlighting, we have to
21101 check if we enter the overlapping overlay, and then
21102 highlight only that. */
21103 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21104 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21105 {
21106 /* Find the highest priority overlay that has a mouse-face
21107 property. */
21108 overlay = Qnil;
21109 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21110 {
21111 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21112 if (!NILP (mouse_face))
21113 overlay = overlay_vec[i];
21114 }
21115
21116 /* If we're actually highlighting the same overlay as
21117 before, there's no need to do that again. */
21118 if (!NILP (overlay)
21119 && EQ (overlay, dpyinfo->mouse_face_overlay))
21120 goto check_help_echo;
21121
21122 dpyinfo->mouse_face_overlay = overlay;
21123
21124 /* Clear the display of the old active region, if any. */
21125 if (clear_mouse_face (dpyinfo))
21126 cursor = No_Cursor;
21127
21128 /* If no overlay applies, get a text property. */
21129 if (NILP (overlay))
21130 mouse_face = Fget_text_property (position, Qmouse_face, object);
21131
21132 /* Handle the overlay case. */
21133 if (!NILP (overlay))
21134 {
21135 /* Find the range of text around this char that
21136 should be active. */
21137 Lisp_Object before, after;
21138 int ignore;
21139
21140 before = Foverlay_start (overlay);
21141 after = Foverlay_end (overlay);
21142 /* Record this as the current active region. */
21143 fast_find_position (w, XFASTINT (before),
21144 &dpyinfo->mouse_face_beg_col,
21145 &dpyinfo->mouse_face_beg_row,
21146 &dpyinfo->mouse_face_beg_x,
21147 &dpyinfo->mouse_face_beg_y, Qnil);
21148
21149 dpyinfo->mouse_face_past_end
21150 = !fast_find_position (w, XFASTINT (after),
21151 &dpyinfo->mouse_face_end_col,
21152 &dpyinfo->mouse_face_end_row,
21153 &dpyinfo->mouse_face_end_x,
21154 &dpyinfo->mouse_face_end_y, Qnil);
21155 dpyinfo->mouse_face_window = window;
21156
21157 dpyinfo->mouse_face_face_id
21158 = face_at_buffer_position (w, pos, 0, 0,
21159 &ignore, pos + 1,
21160 !dpyinfo->mouse_face_hidden);
21161
21162 /* Display it as active. */
21163 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21164 cursor = No_Cursor;
21165 }
21166 /* Handle the text property case. */
21167 else if (!NILP (mouse_face) && BUFFERP (object))
21168 {
21169 /* Find the range of text around this char that
21170 should be active. */
21171 Lisp_Object before, after, beginning, end;
21172 int ignore;
21173
21174 beginning = Fmarker_position (w->start);
21175 end = make_number (BUF_Z (XBUFFER (object))
21176 - XFASTINT (w->window_end_pos));
21177 before
21178 = Fprevious_single_property_change (make_number (pos + 1),
21179 Qmouse_face,
21180 object, beginning);
21181 after
21182 = Fnext_single_property_change (position, Qmouse_face,
21183 object, end);
21184
21185 /* Record this as the current active region. */
21186 fast_find_position (w, XFASTINT (before),
21187 &dpyinfo->mouse_face_beg_col,
21188 &dpyinfo->mouse_face_beg_row,
21189 &dpyinfo->mouse_face_beg_x,
21190 &dpyinfo->mouse_face_beg_y, Qnil);
21191 dpyinfo->mouse_face_past_end
21192 = !fast_find_position (w, XFASTINT (after),
21193 &dpyinfo->mouse_face_end_col,
21194 &dpyinfo->mouse_face_end_row,
21195 &dpyinfo->mouse_face_end_x,
21196 &dpyinfo->mouse_face_end_y, Qnil);
21197 dpyinfo->mouse_face_window = window;
21198
21199 if (BUFFERP (object))
21200 dpyinfo->mouse_face_face_id
21201 = face_at_buffer_position (w, pos, 0, 0,
21202 &ignore, pos + 1,
21203 !dpyinfo->mouse_face_hidden);
21204
21205 /* Display it as active. */
21206 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21207 cursor = No_Cursor;
21208 }
21209 else if (!NILP (mouse_face) && STRINGP (object))
21210 {
21211 Lisp_Object b, e;
21212 int ignore;
21213
21214 b = Fprevious_single_property_change (make_number (pos + 1),
21215 Qmouse_face,
21216 object, Qnil);
21217 e = Fnext_single_property_change (position, Qmouse_face,
21218 object, Qnil);
21219 if (NILP (b))
21220 b = make_number (0);
21221 if (NILP (e))
21222 e = make_number (SCHARS (object) - 1);
21223 fast_find_string_pos (w, XINT (b), object,
21224 &dpyinfo->mouse_face_beg_col,
21225 &dpyinfo->mouse_face_beg_row,
21226 &dpyinfo->mouse_face_beg_x,
21227 &dpyinfo->mouse_face_beg_y, 0);
21228 fast_find_string_pos (w, XINT (e), object,
21229 &dpyinfo->mouse_face_end_col,
21230 &dpyinfo->mouse_face_end_row,
21231 &dpyinfo->mouse_face_end_x,
21232 &dpyinfo->mouse_face_end_y, 1);
21233 dpyinfo->mouse_face_past_end = 0;
21234 dpyinfo->mouse_face_window = window;
21235 dpyinfo->mouse_face_face_id
21236 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21237 glyph->face_id, 1);
21238 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21239 cursor = No_Cursor;
21240 }
21241 else if (STRINGP (object) && NILP (mouse_face))
21242 {
21243 /* A string which doesn't have mouse-face, but
21244 the text ``under'' it might have. */
21245 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21246 int start = MATRIX_ROW_START_CHARPOS (r);
21247
21248 pos = string_buffer_position (w, object, start);
21249 if (pos > 0)
21250 mouse_face = get_char_property_and_overlay (make_number (pos),
21251 Qmouse_face,
21252 w->buffer,
21253 &overlay);
21254 if (!NILP (mouse_face) && !NILP (overlay))
21255 {
21256 Lisp_Object before = Foverlay_start (overlay);
21257 Lisp_Object after = Foverlay_end (overlay);
21258 int ignore;
21259
21260 /* Note that we might not be able to find position
21261 BEFORE in the glyph matrix if the overlay is
21262 entirely covered by a `display' property. In
21263 this case, we overshoot. So let's stop in
21264 the glyph matrix before glyphs for OBJECT. */
21265 fast_find_position (w, XFASTINT (before),
21266 &dpyinfo->mouse_face_beg_col,
21267 &dpyinfo->mouse_face_beg_row,
21268 &dpyinfo->mouse_face_beg_x,
21269 &dpyinfo->mouse_face_beg_y,
21270 object);
21271
21272 dpyinfo->mouse_face_past_end
21273 = !fast_find_position (w, XFASTINT (after),
21274 &dpyinfo->mouse_face_end_col,
21275 &dpyinfo->mouse_face_end_row,
21276 &dpyinfo->mouse_face_end_x,
21277 &dpyinfo->mouse_face_end_y,
21278 Qnil);
21279 dpyinfo->mouse_face_window = window;
21280 dpyinfo->mouse_face_face_id
21281 = face_at_buffer_position (w, pos, 0, 0,
21282 &ignore, pos + 1,
21283 !dpyinfo->mouse_face_hidden);
21284
21285 /* Display it as active. */
21286 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21287 cursor = No_Cursor;
21288 }
21289 }
21290 }
21291
21292 check_help_echo:
21293
21294 /* Look for a `help-echo' property. */
21295 if (NILP (help_echo_string)) {
21296 Lisp_Object help, overlay;
21297
21298 /* Check overlays first. */
21299 help = overlay = Qnil;
21300 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21301 {
21302 overlay = overlay_vec[i];
21303 help = Foverlay_get (overlay, Qhelp_echo);
21304 }
21305
21306 if (!NILP (help))
21307 {
21308 help_echo_string = help;
21309 help_echo_window = window;
21310 help_echo_object = overlay;
21311 help_echo_pos = pos;
21312 }
21313 else
21314 {
21315 Lisp_Object object = glyph->object;
21316 int charpos = glyph->charpos;
21317
21318 /* Try text properties. */
21319 if (STRINGP (object)
21320 && charpos >= 0
21321 && charpos < SCHARS (object))
21322 {
21323 help = Fget_text_property (make_number (charpos),
21324 Qhelp_echo, object);
21325 if (NILP (help))
21326 {
21327 /* If the string itself doesn't specify a help-echo,
21328 see if the buffer text ``under'' it does. */
21329 struct glyph_row *r
21330 = MATRIX_ROW (w->current_matrix, vpos);
21331 int start = MATRIX_ROW_START_CHARPOS (r);
21332 int pos = string_buffer_position (w, object, start);
21333 if (pos > 0)
21334 {
21335 help = Fget_char_property (make_number (pos),
21336 Qhelp_echo, w->buffer);
21337 if (!NILP (help))
21338 {
21339 charpos = pos;
21340 object = w->buffer;
21341 }
21342 }
21343 }
21344 }
21345 else if (BUFFERP (object)
21346 && charpos >= BEGV
21347 && charpos < ZV)
21348 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21349 object);
21350
21351 if (!NILP (help))
21352 {
21353 help_echo_string = help;
21354 help_echo_window = window;
21355 help_echo_object = object;
21356 help_echo_pos = charpos;
21357 }
21358 }
21359 }
21360
21361 /* Look for a `pointer' property. */
21362 if (NILP (pointer))
21363 {
21364 /* Check overlays first. */
21365 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21366 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21367
21368 if (NILP (pointer))
21369 {
21370 Lisp_Object object = glyph->object;
21371 int charpos = glyph->charpos;
21372
21373 /* Try text properties. */
21374 if (STRINGP (object)
21375 && charpos >= 0
21376 && charpos < SCHARS (object))
21377 {
21378 pointer = Fget_text_property (make_number (charpos),
21379 Qpointer, object);
21380 if (NILP (pointer))
21381 {
21382 /* If the string itself doesn't specify a pointer,
21383 see if the buffer text ``under'' it does. */
21384 struct glyph_row *r
21385 = MATRIX_ROW (w->current_matrix, vpos);
21386 int start = MATRIX_ROW_START_CHARPOS (r);
21387 int pos = string_buffer_position (w, object, start);
21388 if (pos > 0)
21389 pointer = Fget_char_property (make_number (pos),
21390 Qpointer, w->buffer);
21391 }
21392 }
21393 else if (BUFFERP (object)
21394 && charpos >= BEGV
21395 && charpos < ZV)
21396 pointer = Fget_text_property (make_number (charpos),
21397 Qpointer, object);
21398 }
21399 }
21400
21401 BEGV = obegv;
21402 ZV = ozv;
21403 current_buffer = obuf;
21404 }
21405
21406 set_cursor:
21407
21408 define_frame_cursor1 (f, cursor, pointer);
21409 }
21410
21411
21412 /* EXPORT for RIF:
21413 Clear any mouse-face on window W. This function is part of the
21414 redisplay interface, and is called from try_window_id and similar
21415 functions to ensure the mouse-highlight is off. */
21416
21417 void
21418 x_clear_window_mouse_face (w)
21419 struct window *w;
21420 {
21421 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21422 Lisp_Object window;
21423
21424 BLOCK_INPUT;
21425 XSETWINDOW (window, w);
21426 if (EQ (window, dpyinfo->mouse_face_window))
21427 clear_mouse_face (dpyinfo);
21428 UNBLOCK_INPUT;
21429 }
21430
21431
21432 /* EXPORT:
21433 Just discard the mouse face information for frame F, if any.
21434 This is used when the size of F is changed. */
21435
21436 void
21437 cancel_mouse_face (f)
21438 struct frame *f;
21439 {
21440 Lisp_Object window;
21441 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21442
21443 window = dpyinfo->mouse_face_window;
21444 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21445 {
21446 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21447 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21448 dpyinfo->mouse_face_window = Qnil;
21449 }
21450 }
21451
21452
21453 #endif /* HAVE_WINDOW_SYSTEM */
21454
21455 \f
21456 /***********************************************************************
21457 Exposure Events
21458 ***********************************************************************/
21459
21460 #ifdef HAVE_WINDOW_SYSTEM
21461
21462 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21463 which intersects rectangle R. R is in window-relative coordinates. */
21464
21465 static void
21466 expose_area (w, row, r, area)
21467 struct window *w;
21468 struct glyph_row *row;
21469 XRectangle *r;
21470 enum glyph_row_area area;
21471 {
21472 struct glyph *first = row->glyphs[area];
21473 struct glyph *end = row->glyphs[area] + row->used[area];
21474 struct glyph *last;
21475 int first_x, start_x, x;
21476
21477 if (area == TEXT_AREA && row->fill_line_p)
21478 /* If row extends face to end of line write the whole line. */
21479 draw_glyphs (w, 0, row, area,
21480 0, row->used[area],
21481 DRAW_NORMAL_TEXT, 0);
21482 else
21483 {
21484 /* Set START_X to the window-relative start position for drawing glyphs of
21485 AREA. The first glyph of the text area can be partially visible.
21486 The first glyphs of other areas cannot. */
21487 start_x = window_box_left_offset (w, area);
21488 x = start_x;
21489 if (area == TEXT_AREA)
21490 x += row->x;
21491
21492 /* Find the first glyph that must be redrawn. */
21493 while (first < end
21494 && x + first->pixel_width < r->x)
21495 {
21496 x += first->pixel_width;
21497 ++first;
21498 }
21499
21500 /* Find the last one. */
21501 last = first;
21502 first_x = x;
21503 while (last < end
21504 && x < r->x + r->width)
21505 {
21506 x += last->pixel_width;
21507 ++last;
21508 }
21509
21510 /* Repaint. */
21511 if (last > first)
21512 draw_glyphs (w, first_x - start_x, row, area,
21513 first - row->glyphs[area], last - row->glyphs[area],
21514 DRAW_NORMAL_TEXT, 0);
21515 }
21516 }
21517
21518
21519 /* Redraw the parts of the glyph row ROW on window W intersecting
21520 rectangle R. R is in window-relative coordinates. Value is
21521 non-zero if mouse-face was overwritten. */
21522
21523 static int
21524 expose_line (w, row, r)
21525 struct window *w;
21526 struct glyph_row *row;
21527 XRectangle *r;
21528 {
21529 xassert (row->enabled_p);
21530
21531 if (row->mode_line_p || w->pseudo_window_p)
21532 draw_glyphs (w, 0, row, TEXT_AREA,
21533 0, row->used[TEXT_AREA],
21534 DRAW_NORMAL_TEXT, 0);
21535 else
21536 {
21537 if (row->used[LEFT_MARGIN_AREA])
21538 expose_area (w, row, r, LEFT_MARGIN_AREA);
21539 if (row->used[TEXT_AREA])
21540 expose_area (w, row, r, TEXT_AREA);
21541 if (row->used[RIGHT_MARGIN_AREA])
21542 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21543 draw_row_fringe_bitmaps (w, row);
21544 }
21545
21546 return row->mouse_face_p;
21547 }
21548
21549
21550 /* Redraw those parts of glyphs rows during expose event handling that
21551 overlap other rows. Redrawing of an exposed line writes over parts
21552 of lines overlapping that exposed line; this function fixes that.
21553
21554 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21555 row in W's current matrix that is exposed and overlaps other rows.
21556 LAST_OVERLAPPING_ROW is the last such row. */
21557
21558 static void
21559 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21560 struct window *w;
21561 struct glyph_row *first_overlapping_row;
21562 struct glyph_row *last_overlapping_row;
21563 {
21564 struct glyph_row *row;
21565
21566 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21567 if (row->overlapping_p)
21568 {
21569 xassert (row->enabled_p && !row->mode_line_p);
21570
21571 if (row->used[LEFT_MARGIN_AREA])
21572 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21573
21574 if (row->used[TEXT_AREA])
21575 x_fix_overlapping_area (w, row, TEXT_AREA);
21576
21577 if (row->used[RIGHT_MARGIN_AREA])
21578 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21579 }
21580 }
21581
21582
21583 /* Return non-zero if W's cursor intersects rectangle R. */
21584
21585 static int
21586 phys_cursor_in_rect_p (w, r)
21587 struct window *w;
21588 XRectangle *r;
21589 {
21590 XRectangle cr, result;
21591 struct glyph *cursor_glyph;
21592
21593 cursor_glyph = get_phys_cursor_glyph (w);
21594 if (cursor_glyph)
21595 {
21596 /* r is relative to W's box, but w->phys_cursor.x is relative
21597 to left edge of W's TEXT area. Adjust it. */
21598 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21599 cr.y = w->phys_cursor.y;
21600 cr.width = cursor_glyph->pixel_width;
21601 cr.height = w->phys_cursor_height;
21602 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21603 I assume the effect is the same -- and this is portable. */
21604 return x_intersect_rectangles (&cr, r, &result);
21605 }
21606 else
21607 return 0;
21608 }
21609
21610
21611 /* EXPORT:
21612 Draw a vertical window border to the right of window W if W doesn't
21613 have vertical scroll bars. */
21614
21615 void
21616 x_draw_vertical_border (w)
21617 struct window *w;
21618 {
21619 /* We could do better, if we knew what type of scroll-bar the adjacent
21620 windows (on either side) have... But we don't :-(
21621 However, I think this works ok. ++KFS 2003-04-25 */
21622
21623 /* Redraw borders between horizontally adjacent windows. Don't
21624 do it for frames with vertical scroll bars because either the
21625 right scroll bar of a window, or the left scroll bar of its
21626 neighbor will suffice as a border. */
21627 if (!WINDOW_RIGHTMOST_P (w)
21628 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21629 {
21630 int x0, x1, y0, y1;
21631
21632 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21633 y1 -= 1;
21634
21635 rif->draw_vertical_window_border (w, x1, y0, y1);
21636 }
21637 else if (!WINDOW_LEFTMOST_P (w)
21638 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21639 {
21640 int x0, x1, y0, y1;
21641
21642 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21643 y1 -= 1;
21644
21645 rif->draw_vertical_window_border (w, x0, y0, y1);
21646 }
21647 }
21648
21649
21650 /* Redraw the part of window W intersection rectangle FR. Pixel
21651 coordinates in FR are frame-relative. Call this function with
21652 input blocked. Value is non-zero if the exposure overwrites
21653 mouse-face. */
21654
21655 static int
21656 expose_window (w, fr)
21657 struct window *w;
21658 XRectangle *fr;
21659 {
21660 struct frame *f = XFRAME (w->frame);
21661 XRectangle wr, r;
21662 int mouse_face_overwritten_p = 0;
21663
21664 /* If window is not yet fully initialized, do nothing. This can
21665 happen when toolkit scroll bars are used and a window is split.
21666 Reconfiguring the scroll bar will generate an expose for a newly
21667 created window. */
21668 if (w->current_matrix == NULL)
21669 return 0;
21670
21671 /* When we're currently updating the window, display and current
21672 matrix usually don't agree. Arrange for a thorough display
21673 later. */
21674 if (w == updated_window)
21675 {
21676 SET_FRAME_GARBAGED (f);
21677 return 0;
21678 }
21679
21680 /* Frame-relative pixel rectangle of W. */
21681 wr.x = WINDOW_LEFT_EDGE_X (w);
21682 wr.y = WINDOW_TOP_EDGE_Y (w);
21683 wr.width = WINDOW_TOTAL_WIDTH (w);
21684 wr.height = WINDOW_TOTAL_HEIGHT (w);
21685
21686 if (x_intersect_rectangles (fr, &wr, &r))
21687 {
21688 int yb = window_text_bottom_y (w);
21689 struct glyph_row *row;
21690 int cursor_cleared_p;
21691 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21692
21693 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21694 r.x, r.y, r.width, r.height));
21695
21696 /* Convert to window coordinates. */
21697 r.x -= WINDOW_LEFT_EDGE_X (w);
21698 r.y -= WINDOW_TOP_EDGE_Y (w);
21699
21700 /* Turn off the cursor. */
21701 if (!w->pseudo_window_p
21702 && phys_cursor_in_rect_p (w, &r))
21703 {
21704 x_clear_cursor (w);
21705 cursor_cleared_p = 1;
21706 }
21707 else
21708 cursor_cleared_p = 0;
21709
21710 /* Update lines intersecting rectangle R. */
21711 first_overlapping_row = last_overlapping_row = NULL;
21712 for (row = w->current_matrix->rows;
21713 row->enabled_p;
21714 ++row)
21715 {
21716 int y0 = row->y;
21717 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21718
21719 if ((y0 >= r.y && y0 < r.y + r.height)
21720 || (y1 > r.y && y1 < r.y + r.height)
21721 || (r.y >= y0 && r.y < y1)
21722 || (r.y + r.height > y0 && r.y + r.height < y1))
21723 {
21724 if (row->overlapping_p)
21725 {
21726 if (first_overlapping_row == NULL)
21727 first_overlapping_row = row;
21728 last_overlapping_row = row;
21729 }
21730
21731 if (expose_line (w, row, &r))
21732 mouse_face_overwritten_p = 1;
21733 }
21734
21735 if (y1 >= yb)
21736 break;
21737 }
21738
21739 /* Display the mode line if there is one. */
21740 if (WINDOW_WANTS_MODELINE_P (w)
21741 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21742 row->enabled_p)
21743 && row->y < r.y + r.height)
21744 {
21745 if (expose_line (w, row, &r))
21746 mouse_face_overwritten_p = 1;
21747 }
21748
21749 if (!w->pseudo_window_p)
21750 {
21751 /* Fix the display of overlapping rows. */
21752 if (first_overlapping_row)
21753 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21754
21755 /* Draw border between windows. */
21756 x_draw_vertical_border (w);
21757
21758 /* Turn the cursor on again. */
21759 if (cursor_cleared_p)
21760 update_window_cursor (w, 1);
21761 }
21762 }
21763
21764 #ifdef HAVE_CARBON
21765 /* Display scroll bar for this window. */
21766 if (!NILP (w->vertical_scroll_bar))
21767 {
21768 /* ++KFS:
21769 If this doesn't work here (maybe some header files are missing),
21770 make a function in macterm.c and call it to do the job! */
21771 ControlHandle ch
21772 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21773
21774 Draw1Control (ch);
21775 }
21776 #endif
21777
21778 return mouse_face_overwritten_p;
21779 }
21780
21781
21782
21783 /* Redraw (parts) of all windows in the window tree rooted at W that
21784 intersect R. R contains frame pixel coordinates. Value is
21785 non-zero if the exposure overwrites mouse-face. */
21786
21787 static int
21788 expose_window_tree (w, r)
21789 struct window *w;
21790 XRectangle *r;
21791 {
21792 struct frame *f = XFRAME (w->frame);
21793 int mouse_face_overwritten_p = 0;
21794
21795 while (w && !FRAME_GARBAGED_P (f))
21796 {
21797 if (!NILP (w->hchild))
21798 mouse_face_overwritten_p
21799 |= expose_window_tree (XWINDOW (w->hchild), r);
21800 else if (!NILP (w->vchild))
21801 mouse_face_overwritten_p
21802 |= expose_window_tree (XWINDOW (w->vchild), r);
21803 else
21804 mouse_face_overwritten_p |= expose_window (w, r);
21805
21806 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21807 }
21808
21809 return mouse_face_overwritten_p;
21810 }
21811
21812
21813 /* EXPORT:
21814 Redisplay an exposed area of frame F. X and Y are the upper-left
21815 corner of the exposed rectangle. W and H are width and height of
21816 the exposed area. All are pixel values. W or H zero means redraw
21817 the entire frame. */
21818
21819 void
21820 expose_frame (f, x, y, w, h)
21821 struct frame *f;
21822 int x, y, w, h;
21823 {
21824 XRectangle r;
21825 int mouse_face_overwritten_p = 0;
21826
21827 TRACE ((stderr, "expose_frame "));
21828
21829 /* No need to redraw if frame will be redrawn soon. */
21830 if (FRAME_GARBAGED_P (f))
21831 {
21832 TRACE ((stderr, " garbaged\n"));
21833 return;
21834 }
21835
21836 #ifdef HAVE_CARBON
21837 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21838 or deactivated here, for unknown reasons, activated scroll bars
21839 are shown in deactivated frames in some instances. */
21840 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21841 activate_scroll_bars (f);
21842 else
21843 deactivate_scroll_bars (f);
21844 #endif
21845
21846 /* If basic faces haven't been realized yet, there is no point in
21847 trying to redraw anything. This can happen when we get an expose
21848 event while Emacs is starting, e.g. by moving another window. */
21849 if (FRAME_FACE_CACHE (f) == NULL
21850 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21851 {
21852 TRACE ((stderr, " no faces\n"));
21853 return;
21854 }
21855
21856 if (w == 0 || h == 0)
21857 {
21858 r.x = r.y = 0;
21859 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21860 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21861 }
21862 else
21863 {
21864 r.x = x;
21865 r.y = y;
21866 r.width = w;
21867 r.height = h;
21868 }
21869
21870 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21871 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21872
21873 if (WINDOWP (f->tool_bar_window))
21874 mouse_face_overwritten_p
21875 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21876
21877 #ifdef HAVE_X_WINDOWS
21878 #ifndef MSDOS
21879 #ifndef USE_X_TOOLKIT
21880 if (WINDOWP (f->menu_bar_window))
21881 mouse_face_overwritten_p
21882 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21883 #endif /* not USE_X_TOOLKIT */
21884 #endif
21885 #endif
21886
21887 /* Some window managers support a focus-follows-mouse style with
21888 delayed raising of frames. Imagine a partially obscured frame,
21889 and moving the mouse into partially obscured mouse-face on that
21890 frame. The visible part of the mouse-face will be highlighted,
21891 then the WM raises the obscured frame. With at least one WM, KDE
21892 2.1, Emacs is not getting any event for the raising of the frame
21893 (even tried with SubstructureRedirectMask), only Expose events.
21894 These expose events will draw text normally, i.e. not
21895 highlighted. Which means we must redo the highlight here.
21896 Subsume it under ``we love X''. --gerd 2001-08-15 */
21897 /* Included in Windows version because Windows most likely does not
21898 do the right thing if any third party tool offers
21899 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21900 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21901 {
21902 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21903 if (f == dpyinfo->mouse_face_mouse_frame)
21904 {
21905 int x = dpyinfo->mouse_face_mouse_x;
21906 int y = dpyinfo->mouse_face_mouse_y;
21907 clear_mouse_face (dpyinfo);
21908 note_mouse_highlight (f, x, y);
21909 }
21910 }
21911 }
21912
21913
21914 /* EXPORT:
21915 Determine the intersection of two rectangles R1 and R2. Return
21916 the intersection in *RESULT. Value is non-zero if RESULT is not
21917 empty. */
21918
21919 int
21920 x_intersect_rectangles (r1, r2, result)
21921 XRectangle *r1, *r2, *result;
21922 {
21923 XRectangle *left, *right;
21924 XRectangle *upper, *lower;
21925 int intersection_p = 0;
21926
21927 /* Rearrange so that R1 is the left-most rectangle. */
21928 if (r1->x < r2->x)
21929 left = r1, right = r2;
21930 else
21931 left = r2, right = r1;
21932
21933 /* X0 of the intersection is right.x0, if this is inside R1,
21934 otherwise there is no intersection. */
21935 if (right->x <= left->x + left->width)
21936 {
21937 result->x = right->x;
21938
21939 /* The right end of the intersection is the minimum of the
21940 the right ends of left and right. */
21941 result->width = (min (left->x + left->width, right->x + right->width)
21942 - result->x);
21943
21944 /* Same game for Y. */
21945 if (r1->y < r2->y)
21946 upper = r1, lower = r2;
21947 else
21948 upper = r2, lower = r1;
21949
21950 /* The upper end of the intersection is lower.y0, if this is inside
21951 of upper. Otherwise, there is no intersection. */
21952 if (lower->y <= upper->y + upper->height)
21953 {
21954 result->y = lower->y;
21955
21956 /* The lower end of the intersection is the minimum of the lower
21957 ends of upper and lower. */
21958 result->height = (min (lower->y + lower->height,
21959 upper->y + upper->height)
21960 - result->y);
21961 intersection_p = 1;
21962 }
21963 }
21964
21965 return intersection_p;
21966 }
21967
21968 #endif /* HAVE_WINDOW_SYSTEM */
21969
21970 \f
21971 /***********************************************************************
21972 Initialization
21973 ***********************************************************************/
21974
21975 void
21976 syms_of_xdisp ()
21977 {
21978 Vwith_echo_area_save_vector = Qnil;
21979 staticpro (&Vwith_echo_area_save_vector);
21980
21981 Vmessage_stack = Qnil;
21982 staticpro (&Vmessage_stack);
21983
21984 Qinhibit_redisplay = intern ("inhibit-redisplay");
21985 staticpro (&Qinhibit_redisplay);
21986
21987 message_dolog_marker1 = Fmake_marker ();
21988 staticpro (&message_dolog_marker1);
21989 message_dolog_marker2 = Fmake_marker ();
21990 staticpro (&message_dolog_marker2);
21991 message_dolog_marker3 = Fmake_marker ();
21992 staticpro (&message_dolog_marker3);
21993
21994 #if GLYPH_DEBUG
21995 defsubr (&Sdump_frame_glyph_matrix);
21996 defsubr (&Sdump_glyph_matrix);
21997 defsubr (&Sdump_glyph_row);
21998 defsubr (&Sdump_tool_bar_row);
21999 defsubr (&Strace_redisplay);
22000 defsubr (&Strace_to_stderr);
22001 #endif
22002 #ifdef HAVE_WINDOW_SYSTEM
22003 defsubr (&Stool_bar_lines_needed);
22004 defsubr (&Slookup_image_map);
22005 #endif
22006 defsubr (&Sformat_mode_line);
22007
22008 staticpro (&Qmenu_bar_update_hook);
22009 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22010
22011 staticpro (&Qoverriding_terminal_local_map);
22012 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22013
22014 staticpro (&Qoverriding_local_map);
22015 Qoverriding_local_map = intern ("overriding-local-map");
22016
22017 staticpro (&Qwindow_scroll_functions);
22018 Qwindow_scroll_functions = intern ("window-scroll-functions");
22019
22020 staticpro (&Qredisplay_end_trigger_functions);
22021 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22022
22023 staticpro (&Qinhibit_point_motion_hooks);
22024 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22025
22026 QCdata = intern (":data");
22027 staticpro (&QCdata);
22028 Qdisplay = intern ("display");
22029 staticpro (&Qdisplay);
22030 Qspace_width = intern ("space-width");
22031 staticpro (&Qspace_width);
22032 Qraise = intern ("raise");
22033 staticpro (&Qraise);
22034 Qslice = intern ("slice");
22035 staticpro (&Qslice);
22036 Qspace = intern ("space");
22037 staticpro (&Qspace);
22038 Qmargin = intern ("margin");
22039 staticpro (&Qmargin);
22040 Qpointer = intern ("pointer");
22041 staticpro (&Qpointer);
22042 Qleft_margin = intern ("left-margin");
22043 staticpro (&Qleft_margin);
22044 Qright_margin = intern ("right-margin");
22045 staticpro (&Qright_margin);
22046 Qcenter = intern ("center");
22047 staticpro (&Qcenter);
22048 Qline_height = intern ("line-height");
22049 staticpro (&Qline_height);
22050 Qtotal = intern ("total");
22051 staticpro (&Qtotal);
22052 QCalign_to = intern (":align-to");
22053 staticpro (&QCalign_to);
22054 QCrelative_width = intern (":relative-width");
22055 staticpro (&QCrelative_width);
22056 QCrelative_height = intern (":relative-height");
22057 staticpro (&QCrelative_height);
22058 QCeval = intern (":eval");
22059 staticpro (&QCeval);
22060 QCpropertize = intern (":propertize");
22061 staticpro (&QCpropertize);
22062 QCfile = intern (":file");
22063 staticpro (&QCfile);
22064 Qfontified = intern ("fontified");
22065 staticpro (&Qfontified);
22066 Qfontification_functions = intern ("fontification-functions");
22067 staticpro (&Qfontification_functions);
22068 Qtrailing_whitespace = intern ("trailing-whitespace");
22069 staticpro (&Qtrailing_whitespace);
22070 Qimage = intern ("image");
22071 staticpro (&Qimage);
22072 QCmap = intern (":map");
22073 staticpro (&QCmap);
22074 QCpointer = intern (":pointer");
22075 staticpro (&QCpointer);
22076 Qrect = intern ("rect");
22077 staticpro (&Qrect);
22078 Qcircle = intern ("circle");
22079 staticpro (&Qcircle);
22080 Qpoly = intern ("poly");
22081 staticpro (&Qpoly);
22082 Qmessage_truncate_lines = intern ("message-truncate-lines");
22083 staticpro (&Qmessage_truncate_lines);
22084 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22085 staticpro (&Qcursor_in_non_selected_windows);
22086 Qgrow_only = intern ("grow-only");
22087 staticpro (&Qgrow_only);
22088 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22089 staticpro (&Qinhibit_menubar_update);
22090 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22091 staticpro (&Qinhibit_eval_during_redisplay);
22092 Qposition = intern ("position");
22093 staticpro (&Qposition);
22094 Qbuffer_position = intern ("buffer-position");
22095 staticpro (&Qbuffer_position);
22096 Qobject = intern ("object");
22097 staticpro (&Qobject);
22098 Qbar = intern ("bar");
22099 staticpro (&Qbar);
22100 Qhbar = intern ("hbar");
22101 staticpro (&Qhbar);
22102 Qbox = intern ("box");
22103 staticpro (&Qbox);
22104 Qhollow = intern ("hollow");
22105 staticpro (&Qhollow);
22106 Qhand = intern ("hand");
22107 staticpro (&Qhand);
22108 Qarrow = intern ("arrow");
22109 staticpro (&Qarrow);
22110 Qtext = intern ("text");
22111 staticpro (&Qtext);
22112 Qrisky_local_variable = intern ("risky-local-variable");
22113 staticpro (&Qrisky_local_variable);
22114 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22115 staticpro (&Qinhibit_free_realized_faces);
22116
22117 list_of_error = Fcons (Fcons (intern ("error"),
22118 Fcons (intern ("void-variable"), Qnil)),
22119 Qnil);
22120 staticpro (&list_of_error);
22121
22122 Qlast_arrow_position = intern ("last-arrow-position");
22123 staticpro (&Qlast_arrow_position);
22124 Qlast_arrow_string = intern ("last-arrow-string");
22125 staticpro (&Qlast_arrow_string);
22126
22127 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22128 staticpro (&Qoverlay_arrow_string);
22129 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22130 staticpro (&Qoverlay_arrow_bitmap);
22131
22132 echo_buffer[0] = echo_buffer[1] = Qnil;
22133 staticpro (&echo_buffer[0]);
22134 staticpro (&echo_buffer[1]);
22135
22136 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22137 staticpro (&echo_area_buffer[0]);
22138 staticpro (&echo_area_buffer[1]);
22139
22140 Vmessages_buffer_name = build_string ("*Messages*");
22141 staticpro (&Vmessages_buffer_name);
22142
22143 mode_line_proptrans_alist = Qnil;
22144 staticpro (&mode_line_proptrans_alist);
22145
22146 mode_line_string_list = Qnil;
22147 staticpro (&mode_line_string_list);
22148
22149 help_echo_string = Qnil;
22150 staticpro (&help_echo_string);
22151 help_echo_object = Qnil;
22152 staticpro (&help_echo_object);
22153 help_echo_window = Qnil;
22154 staticpro (&help_echo_window);
22155 previous_help_echo_string = Qnil;
22156 staticpro (&previous_help_echo_string);
22157 help_echo_pos = -1;
22158
22159 #ifdef HAVE_WINDOW_SYSTEM
22160 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22161 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22162 For example, if a block cursor is over a tab, it will be drawn as
22163 wide as that tab on the display. */);
22164 x_stretch_cursor_p = 0;
22165 #endif
22166
22167 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22168 doc: /* *Non-nil means highlight trailing whitespace.
22169 The face used for trailing whitespace is `trailing-whitespace'. */);
22170 Vshow_trailing_whitespace = Qnil;
22171
22172 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22173 doc: /* *The pointer shape to show in void text areas.
22174 Nil means to show the text pointer. Other options are `arrow', `text',
22175 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22176 Vvoid_text_area_pointer = Qarrow;
22177
22178 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22179 doc: /* Non-nil means don't actually do any redisplay.
22180 This is used for internal purposes. */);
22181 Vinhibit_redisplay = Qnil;
22182
22183 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22184 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22185 Vglobal_mode_string = Qnil;
22186
22187 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22188 doc: /* Marker for where to display an arrow on top of the buffer text.
22189 This must be the beginning of a line in order to work.
22190 See also `overlay-arrow-string'. */);
22191 Voverlay_arrow_position = Qnil;
22192
22193 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22194 doc: /* String to display as an arrow in non-window frames.
22195 See also `overlay-arrow-position'. */);
22196 Voverlay_arrow_string = Qnil;
22197
22198 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22199 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22200 The symbols on this list are examined during redisplay to determine
22201 where to display overlay arrows. */);
22202 Voverlay_arrow_variable_list
22203 = Fcons (intern ("overlay-arrow-position"), Qnil);
22204
22205 DEFVAR_INT ("scroll-step", &scroll_step,
22206 doc: /* *The number of lines to try scrolling a window by when point moves out.
22207 If that fails to bring point back on frame, point is centered instead.
22208 If this is zero, point is always centered after it moves off frame.
22209 If you want scrolling to always be a line at a time, you should set
22210 `scroll-conservatively' to a large value rather than set this to 1. */);
22211
22212 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22213 doc: /* *Scroll up to this many lines, to bring point back on screen.
22214 A value of zero means to scroll the text to center point vertically
22215 in the window. */);
22216 scroll_conservatively = 0;
22217
22218 DEFVAR_INT ("scroll-margin", &scroll_margin,
22219 doc: /* *Number of lines of margin at the top and bottom of a window.
22220 Recenter the window whenever point gets within this many lines
22221 of the top or bottom of the window. */);
22222 scroll_margin = 0;
22223
22224 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22225 doc: /* Pixels per inch on current display.
22226 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22227 Vdisplay_pixels_per_inch = make_float (72.0);
22228
22229 #if GLYPH_DEBUG
22230 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22231 #endif
22232
22233 DEFVAR_BOOL ("truncate-partial-width-windows",
22234 &truncate_partial_width_windows,
22235 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22236 truncate_partial_width_windows = 1;
22237
22238 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22239 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22240 Any other value means to use the appropriate face, `mode-line',
22241 `header-line', or `menu' respectively. */);
22242 mode_line_inverse_video = 1;
22243
22244 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22245 doc: /* *Maximum buffer size for which line number should be displayed.
22246 If the buffer is bigger than this, the line number does not appear
22247 in the mode line. A value of nil means no limit. */);
22248 Vline_number_display_limit = Qnil;
22249
22250 DEFVAR_INT ("line-number-display-limit-width",
22251 &line_number_display_limit_width,
22252 doc: /* *Maximum line width (in characters) for line number display.
22253 If the average length of the lines near point is bigger than this, then the
22254 line number may be omitted from the mode line. */);
22255 line_number_display_limit_width = 200;
22256
22257 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22258 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22259 highlight_nonselected_windows = 0;
22260
22261 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22262 doc: /* Non-nil if more than one frame is visible on this display.
22263 Minibuffer-only frames don't count, but iconified frames do.
22264 This variable is not guaranteed to be accurate except while processing
22265 `frame-title-format' and `icon-title-format'. */);
22266
22267 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22268 doc: /* Template for displaying the title bar of visible frames.
22269 \(Assuming the window manager supports this feature.)
22270 This variable has the same structure as `mode-line-format' (which see),
22271 and is used only on frames for which no explicit name has been set
22272 \(see `modify-frame-parameters'). */);
22273
22274 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22275 doc: /* Template for displaying the title bar of an iconified frame.
22276 \(Assuming the window manager supports this feature.)
22277 This variable has the same structure as `mode-line-format' (which see),
22278 and is used only on frames for which no explicit name has been set
22279 \(see `modify-frame-parameters'). */);
22280 Vicon_title_format
22281 = Vframe_title_format
22282 = Fcons (intern ("multiple-frames"),
22283 Fcons (build_string ("%b"),
22284 Fcons (Fcons (empty_string,
22285 Fcons (intern ("invocation-name"),
22286 Fcons (build_string ("@"),
22287 Fcons (intern ("system-name"),
22288 Qnil)))),
22289 Qnil)));
22290
22291 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22292 doc: /* Maximum number of lines to keep in the message log buffer.
22293 If nil, disable message logging. If t, log messages but don't truncate
22294 the buffer when it becomes large. */);
22295 Vmessage_log_max = make_number (50);
22296
22297 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22298 doc: /* Functions called before redisplay, if window sizes have changed.
22299 The value should be a list of functions that take one argument.
22300 Just before redisplay, for each frame, if any of its windows have changed
22301 size since the last redisplay, or have been split or deleted,
22302 all the functions in the list are called, with the frame as argument. */);
22303 Vwindow_size_change_functions = Qnil;
22304
22305 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22306 doc: /* List of functions to call before redisplaying a window with scrolling.
22307 Each function is called with two arguments, the window
22308 and its new display-start position. Note that the value of `window-end'
22309 is not valid when these functions are called. */);
22310 Vwindow_scroll_functions = Qnil;
22311
22312 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22313 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22314 mouse_autoselect_window = 0;
22315
22316 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22317 doc: /* *Non-nil means automatically resize tool-bars.
22318 This increases a tool-bar's height if not all tool-bar items are visible.
22319 It decreases a tool-bar's height when it would display blank lines
22320 otherwise. */);
22321 auto_resize_tool_bars_p = 1;
22322
22323 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22324 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22325 auto_raise_tool_bar_buttons_p = 1;
22326
22327 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22328 doc: /* *Margin around tool-bar buttons in pixels.
22329 If an integer, use that for both horizontal and vertical margins.
22330 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22331 HORZ specifying the horizontal margin, and VERT specifying the
22332 vertical margin. */);
22333 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22334
22335 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22336 doc: /* *Relief thickness of tool-bar buttons. */);
22337 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22338
22339 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22340 doc: /* List of functions to call to fontify regions of text.
22341 Each function is called with one argument POS. Functions must
22342 fontify a region starting at POS in the current buffer, and give
22343 fontified regions the property `fontified'. */);
22344 Vfontification_functions = Qnil;
22345 Fmake_variable_buffer_local (Qfontification_functions);
22346
22347 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22348 &unibyte_display_via_language_environment,
22349 doc: /* *Non-nil means display unibyte text according to language environment.
22350 Specifically this means that unibyte non-ASCII characters
22351 are displayed by converting them to the equivalent multibyte characters
22352 according to the current language environment. As a result, they are
22353 displayed according to the current fontset. */);
22354 unibyte_display_via_language_environment = 0;
22355
22356 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22357 doc: /* *Maximum height for resizing mini-windows.
22358 If a float, it specifies a fraction of the mini-window frame's height.
22359 If an integer, it specifies a number of lines. */);
22360 Vmax_mini_window_height = make_float (0.25);
22361
22362 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22363 doc: /* *How to resize mini-windows.
22364 A value of nil means don't automatically resize mini-windows.
22365 A value of t means resize them to fit the text displayed in them.
22366 A value of `grow-only', the default, means let mini-windows grow
22367 only, until their display becomes empty, at which point the windows
22368 go back to their normal size. */);
22369 Vresize_mini_windows = Qgrow_only;
22370
22371 DEFVAR_LISP ("cursor-in-non-selected-windows",
22372 &Vcursor_in_non_selected_windows,
22373 doc: /* *Cursor type to display in non-selected windows.
22374 t means to use hollow box cursor. See `cursor-type' for other values. */);
22375 Vcursor_in_non_selected_windows = Qt;
22376
22377 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22378 doc: /* Alist specifying how to blink the cursor off.
22379 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22380 `cursor-type' frame-parameter or variable equals ON-STATE,
22381 comparing using `equal', Emacs uses OFF-STATE to specify
22382 how to blink it off. */);
22383 Vblink_cursor_alist = Qnil;
22384
22385 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22386 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22387 automatic_hscrolling_p = 1;
22388
22389 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22390 doc: /* *How many columns away from the window edge point is allowed to get
22391 before automatic hscrolling will horizontally scroll the window. */);
22392 hscroll_margin = 5;
22393
22394 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22395 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22396 When point is less than `automatic-hscroll-margin' columns from the window
22397 edge, automatic hscrolling will scroll the window by the amount of columns
22398 determined by this variable. If its value is a positive integer, scroll that
22399 many columns. If it's a positive floating-point number, it specifies the
22400 fraction of the window's width to scroll. If it's nil or zero, point will be
22401 centered horizontally after the scroll. Any other value, including negative
22402 numbers, are treated as if the value were zero.
22403
22404 Automatic hscrolling always moves point outside the scroll margin, so if
22405 point was more than scroll step columns inside the margin, the window will
22406 scroll more than the value given by the scroll step.
22407
22408 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22409 and `scroll-right' overrides this variable's effect. */);
22410 Vhscroll_step = make_number (0);
22411
22412 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22413 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22414 Bind this around calls to `message' to let it take effect. */);
22415 message_truncate_lines = 0;
22416
22417 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22418 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
22419 Can be used to update submenus whose contents should vary. */);
22420 Vmenu_bar_update_hook = Qnil;
22421
22422 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22423 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22424 inhibit_menubar_update = 0;
22425
22426 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22427 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22428 inhibit_eval_during_redisplay = 0;
22429
22430 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22431 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22432 inhibit_free_realized_faces = 0;
22433
22434 #if GLYPH_DEBUG
22435 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22436 doc: /* Inhibit try_window_id display optimization. */);
22437 inhibit_try_window_id = 0;
22438
22439 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22440 doc: /* Inhibit try_window_reusing display optimization. */);
22441 inhibit_try_window_reusing = 0;
22442
22443 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22444 doc: /* Inhibit try_cursor_movement display optimization. */);
22445 inhibit_try_cursor_movement = 0;
22446 #endif /* GLYPH_DEBUG */
22447 }
22448
22449
22450 /* Initialize this module when Emacs starts. */
22451
22452 void
22453 init_xdisp ()
22454 {
22455 Lisp_Object root_window;
22456 struct window *mini_w;
22457
22458 current_header_line_height = current_mode_line_height = -1;
22459
22460 CHARPOS (this_line_start_pos) = 0;
22461
22462 mini_w = XWINDOW (minibuf_window);
22463 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22464
22465 if (!noninteractive)
22466 {
22467 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22468 int i;
22469
22470 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22471 set_window_height (root_window,
22472 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22473 0);
22474 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22475 set_window_height (minibuf_window, 1, 0);
22476
22477 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22478 mini_w->total_cols = make_number (FRAME_COLS (f));
22479
22480 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22481 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22482 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22483
22484 /* The default ellipsis glyphs `...'. */
22485 for (i = 0; i < 3; ++i)
22486 default_invis_vector[i] = make_number ('.');
22487 }
22488
22489 {
22490 /* Allocate the buffer for frame titles.
22491 Also used for `format-mode-line'. */
22492 int size = 100;
22493 frame_title_buf = (char *) xmalloc (size);
22494 frame_title_buf_end = frame_title_buf + size;
22495 frame_title_ptr = NULL;
22496 }
22497
22498 help_echo_showing_p = 0;
22499 }
22500
22501
22502 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22503 (do not change this comment) */