Mention `tla replay' in README.multi-tty (Gaute Strokkenes).
[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
202 Cursor No_Cursor;
203 #endif
204
205 #ifndef FRAME_X_OUTPUT
206 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
207 #endif
208
209 #define INFINITY 10000000
210
211 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
212 || defined (USE_GTK)
213 extern void set_frame_menubar P_ ((struct frame *f, int, int));
214 extern int pending_menu_activation;
215 #endif
216
217 extern int interrupt_input;
218 extern int command_loop_level;
219
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
222
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
225
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
231
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
241
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
244
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
247
248 Lisp_Object Qrisky_local_variable;
249
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
252
253 /* Functions called to fontify regions of text. */
254
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
257
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
261
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
264
265 int auto_raise_tool_bar_buttons_p;
266
267 /* Margin around tool bar buttons in pixels. */
268
269 Lisp_Object Vtool_bar_button_margin;
270
271 /* Thickness of shadow to draw around tool bar buttons. */
272
273 EMACS_INT tool_bar_button_relief;
274
275 /* Non-zero means automatically resize tool-bars so that all tool-bar
276 items are visible, and no blank lines remain. */
277
278 int auto_resize_tool_bars_p;
279
280 /* Non-zero means draw block and hollow cursor as wide as the glyph
281 under it. For example, if a block cursor is over a tab, it will be
282 drawn as wide as that tab on the display. */
283
284 int x_stretch_cursor_p;
285
286 /* Non-nil means don't actually do any redisplay. */
287
288 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
289
290 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
291
292 int inhibit_eval_during_redisplay;
293
294 /* Names of text properties relevant for redisplay. */
295
296 Lisp_Object Qdisplay;
297 extern Lisp_Object Qface, Qinvisible, Qwidth;
298
299 /* Symbols used in text property values. */
300
301 Lisp_Object Vdisplay_pixels_per_inch;
302 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
303 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
304 Lisp_Object Qcenter;
305 Lisp_Object Qmargin, Qpointer;
306 extern Lisp_Object Qheight;
307 extern Lisp_Object QCwidth, QCheight, QCascent;
308 extern Lisp_Object Qscroll_bar;
309
310 /* Non-nil means highlight trailing whitespace. */
311
312 Lisp_Object Vshow_trailing_whitespace;
313
314 #ifdef HAVE_WINDOW_SYSTEM
315 extern Lisp_Object Voverflow_newline_into_fringe;
316
317 /* Test if overflow newline into fringe. Called with iterator IT
318 at or past right window margin, and with IT->current_x set. */
319
320 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
321 (!NILP (Voverflow_newline_into_fringe) \
322 && FRAME_WINDOW_P (it->f) \
323 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
324 && it->current_x == it->last_visible_x)
325
326 #endif /* HAVE_WINDOW_SYSTEM */
327
328 /* Non-nil means show the text cursor in void text areas
329 i.e. in blank areas after eol and eob. This used to be
330 the default in 21.3. */
331
332 Lisp_Object Vvoid_text_area_pointer;
333
334 /* Name of the face used to highlight trailing whitespace. */
335
336 Lisp_Object Qtrailing_whitespace;
337
338 /* The symbol `image' which is the car of the lists used to represent
339 images in Lisp. */
340
341 Lisp_Object Qimage;
342
343 /* The image map types. */
344 Lisp_Object QCmap, QCpointer;
345 Lisp_Object Qrect, Qcircle, Qpoly;
346
347 /* Non-zero means print newline to stdout before next mini-buffer
348 message. */
349
350 int noninteractive_need_newline;
351
352 /* Non-zero means print newline to message log before next message. */
353
354 static int message_log_need_newline;
355
356 /* Three markers that message_dolog uses.
357 It could allocate them itself, but that causes trouble
358 in handling memory-full errors. */
359 static Lisp_Object message_dolog_marker1;
360 static Lisp_Object message_dolog_marker2;
361 static Lisp_Object message_dolog_marker3;
362 \f
363 /* The buffer position of the first character appearing entirely or
364 partially on the line of the selected window which contains the
365 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
366 redisplay optimization in redisplay_internal. */
367
368 static struct text_pos this_line_start_pos;
369
370 /* Number of characters past the end of the line above, including the
371 terminating newline. */
372
373 static struct text_pos this_line_end_pos;
374
375 /* The vertical positions and the height of this line. */
376
377 static int this_line_vpos;
378 static int this_line_y;
379 static int this_line_pixel_height;
380
381 /* X position at which this display line starts. Usually zero;
382 negative if first character is partially visible. */
383
384 static int this_line_start_x;
385
386 /* Buffer that this_line_.* variables are referring to. */
387
388 static struct buffer *this_line_buffer;
389
390 /* Nonzero means truncate lines in all windows less wide than the
391 frame. */
392
393 int truncate_partial_width_windows;
394
395 /* A flag to control how to display unibyte 8-bit character. */
396
397 int unibyte_display_via_language_environment;
398
399 /* Nonzero means we have more than one non-mini-buffer-only frame.
400 Not guaranteed to be accurate except while parsing
401 frame-title-format. */
402
403 int multiple_frames;
404
405 Lisp_Object Vglobal_mode_string;
406
407
408 /* List of variables (symbols) which hold markers for overlay arrows.
409 The symbols on this list are examined during redisplay to determine
410 where to display overlay arrows. */
411
412 Lisp_Object Voverlay_arrow_variable_list;
413
414 /* Marker for where to display an arrow on top of the buffer text. */
415
416 Lisp_Object Voverlay_arrow_position;
417
418 /* String to display for the arrow. Only used on terminal frames. */
419
420 Lisp_Object Voverlay_arrow_string;
421
422 /* Values of those variables at last redisplay are stored as
423 properties on `overlay-arrow-position' symbol. However, if
424 Voverlay_arrow_position is a marker, last-arrow-position is its
425 numerical position. */
426
427 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
428
429 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
430 properties on a symbol in overlay-arrow-variable-list. */
431
432 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
433
434 /* Like mode-line-format, but for the title bar on a visible frame. */
435
436 Lisp_Object Vframe_title_format;
437
438 /* Like mode-line-format, but for the title bar on an iconified frame. */
439
440 Lisp_Object Vicon_title_format;
441
442 /* List of functions to call when a window's size changes. These
443 functions get one arg, a frame on which one or more windows' sizes
444 have changed. */
445
446 static Lisp_Object Vwindow_size_change_functions;
447
448 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
449
450 /* Nonzero if overlay arrow has been displayed once in this window. */
451
452 static int overlay_arrow_seen;
453
454 /* Nonzero means highlight the region even in nonselected windows. */
455
456 int highlight_nonselected_windows;
457
458 /* If cursor motion alone moves point off frame, try scrolling this
459 many lines up or down if that will bring it back. */
460
461 static EMACS_INT scroll_step;
462
463 /* Nonzero means scroll just far enough to bring point back on the
464 screen, when appropriate. */
465
466 static EMACS_INT scroll_conservatively;
467
468 /* Recenter the window whenever point gets within this many lines of
469 the top or bottom of the window. This value is translated into a
470 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
471 that there is really a fixed pixel height scroll margin. */
472
473 EMACS_INT scroll_margin;
474
475 /* Number of windows showing the buffer of the selected window (or
476 another buffer with the same base buffer). keyboard.c refers to
477 this. */
478
479 int buffer_shared;
480
481 /* Vector containing glyphs for an ellipsis `...'. */
482
483 static Lisp_Object default_invis_vector[3];
484
485 /* Zero means display the mode-line/header-line/menu-bar in the default face
486 (this slightly odd definition is for compatibility with previous versions
487 of emacs), non-zero means display them using their respective faces.
488
489 This variable is deprecated. */
490
491 int mode_line_inverse_video;
492
493 /* Prompt to display in front of the mini-buffer contents. */
494
495 Lisp_Object minibuf_prompt;
496
497 /* Width of current mini-buffer prompt. Only set after display_line
498 of the line that contains the prompt. */
499
500 int minibuf_prompt_width;
501
502 /* This is the window where the echo area message was displayed. It
503 is always a mini-buffer window, but it may not be the same window
504 currently active as a mini-buffer. */
505
506 Lisp_Object echo_area_window;
507
508 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
509 pushes the current message and the value of
510 message_enable_multibyte on the stack, the function restore_message
511 pops the stack and displays MESSAGE again. */
512
513 Lisp_Object Vmessage_stack;
514
515 /* Nonzero means multibyte characters were enabled when the echo area
516 message was specified. */
517
518 int message_enable_multibyte;
519
520 /* Nonzero if we should redraw the mode lines on the next redisplay. */
521
522 int update_mode_lines;
523
524 /* Nonzero if window sizes or contents have changed since last
525 redisplay that finished. */
526
527 int windows_or_buffers_changed;
528
529 /* Nonzero means a frame's cursor type has been changed. */
530
531 int cursor_type_changed;
532
533 /* Nonzero after display_mode_line if %l was used and it displayed a
534 line number. */
535
536 int line_number_displayed;
537
538 /* Maximum buffer size for which to display line numbers. */
539
540 Lisp_Object Vline_number_display_limit;
541
542 /* Line width to consider when repositioning for line number display. */
543
544 static EMACS_INT line_number_display_limit_width;
545
546 /* Number of lines to keep in the message log buffer. t means
547 infinite. nil means don't log at all. */
548
549 Lisp_Object Vmessage_log_max;
550
551 /* The name of the *Messages* buffer, a string. */
552
553 static Lisp_Object Vmessages_buffer_name;
554
555 /* Current, index 0, and last displayed echo area message. Either
556 buffers from echo_buffers, or nil to indicate no message. */
557
558 Lisp_Object echo_area_buffer[2];
559
560 /* The buffers referenced from echo_area_buffer. */
561
562 static Lisp_Object echo_buffer[2];
563
564 /* A vector saved used in with_area_buffer to reduce consing. */
565
566 static Lisp_Object Vwith_echo_area_save_vector;
567
568 /* Non-zero means display_echo_area should display the last echo area
569 message again. Set by redisplay_preserve_echo_area. */
570
571 static int display_last_displayed_message_p;
572
573 /* Nonzero if echo area is being used by print; zero if being used by
574 message. */
575
576 int message_buf_print;
577
578 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
579
580 Lisp_Object Qinhibit_menubar_update;
581 int inhibit_menubar_update;
582
583 /* Maximum height for resizing mini-windows. Either a float
584 specifying a fraction of the available height, or an integer
585 specifying a number of lines. */
586
587 Lisp_Object Vmax_mini_window_height;
588
589 /* Non-zero means messages should be displayed with truncated
590 lines instead of being continued. */
591
592 int message_truncate_lines;
593 Lisp_Object Qmessage_truncate_lines;
594
595 /* Set to 1 in clear_message to make redisplay_internal aware
596 of an emptied echo area. */
597
598 static int message_cleared_p;
599
600 /* Non-zero means we want a hollow cursor in windows that are not
601 selected. Zero means there's no cursor in such windows. */
602
603 Lisp_Object Vcursor_in_non_selected_windows;
604 Lisp_Object Qcursor_in_non_selected_windows;
605
606 /* How to blink the default frame cursor off. */
607 Lisp_Object Vblink_cursor_alist;
608
609 /* A scratch glyph row with contents used for generating truncation
610 glyphs. Also used in direct_output_for_insert. */
611
612 #define MAX_SCRATCH_GLYPHS 100
613 struct glyph_row scratch_glyph_row;
614 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
615
616 /* Ascent and height of the last line processed by move_it_to. */
617
618 static int last_max_ascent, last_height;
619
620 /* Non-zero if there's a help-echo in the echo area. */
621
622 int help_echo_showing_p;
623
624 /* If >= 0, computed, exact values of mode-line and header-line height
625 to use in the macros CURRENT_MODE_LINE_HEIGHT and
626 CURRENT_HEADER_LINE_HEIGHT. */
627
628 int current_mode_line_height, current_header_line_height;
629
630 /* The maximum distance to look ahead for text properties. Values
631 that are too small let us call compute_char_face and similar
632 functions too often which is expensive. Values that are too large
633 let us call compute_char_face and alike too often because we
634 might not be interested in text properties that far away. */
635
636 #define TEXT_PROP_DISTANCE_LIMIT 100
637
638 #if GLYPH_DEBUG
639
640 /* Variables to turn off display optimizations from Lisp. */
641
642 int inhibit_try_window_id, inhibit_try_window_reusing;
643 int inhibit_try_cursor_movement;
644
645 /* Non-zero means print traces of redisplay if compiled with
646 GLYPH_DEBUG != 0. */
647
648 int trace_redisplay_p;
649
650 #endif /* GLYPH_DEBUG */
651
652 #ifdef DEBUG_TRACE_MOVE
653 /* Non-zero means trace with TRACE_MOVE to stderr. */
654 int trace_move;
655
656 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
657 #else
658 #define TRACE_MOVE(x) (void) 0
659 #endif
660
661 /* Non-zero means automatically scroll windows horizontally to make
662 point visible. */
663
664 int automatic_hscrolling_p;
665
666 /* How close to the margin can point get before the window is scrolled
667 horizontally. */
668 EMACS_INT hscroll_margin;
669
670 /* How much to scroll horizontally when point is inside the above margin. */
671 Lisp_Object Vhscroll_step;
672
673 /* A list of symbols, one for each supported image type. */
674
675 Lisp_Object Vimage_types;
676
677 /* The variable `resize-mini-windows'. If nil, don't resize
678 mini-windows. If t, always resize them to fit the text they
679 display. If `grow-only', let mini-windows grow only until they
680 become empty. */
681
682 Lisp_Object Vresize_mini_windows;
683
684 /* Buffer being redisplayed -- for redisplay_window_error. */
685
686 struct buffer *displayed_buffer;
687
688 /* Value returned from text property handlers (see below). */
689
690 enum prop_handled
691 {
692 HANDLED_NORMALLY,
693 HANDLED_RECOMPUTE_PROPS,
694 HANDLED_OVERLAY_STRING_CONSUMED,
695 HANDLED_RETURN
696 };
697
698 /* A description of text properties that redisplay is interested
699 in. */
700
701 struct props
702 {
703 /* The name of the property. */
704 Lisp_Object *name;
705
706 /* A unique index for the property. */
707 enum prop_idx idx;
708
709 /* A handler function called to set up iterator IT from the property
710 at IT's current position. Value is used to steer handle_stop. */
711 enum prop_handled (*handler) P_ ((struct it *it));
712 };
713
714 static enum prop_handled handle_face_prop P_ ((struct it *));
715 static enum prop_handled handle_invisible_prop P_ ((struct it *));
716 static enum prop_handled handle_display_prop P_ ((struct it *));
717 static enum prop_handled handle_composition_prop P_ ((struct it *));
718 static enum prop_handled handle_overlay_change P_ ((struct it *));
719 static enum prop_handled handle_fontified_prop P_ ((struct it *));
720
721 /* Properties handled by iterators. */
722
723 static struct props it_props[] =
724 {
725 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
726 /* Handle `face' before `display' because some sub-properties of
727 `display' need to know the face. */
728 {&Qface, FACE_PROP_IDX, handle_face_prop},
729 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
730 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
731 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
732 {NULL, 0, NULL}
733 };
734
735 /* Value is the position described by X. If X is a marker, value is
736 the marker_position of X. Otherwise, value is X. */
737
738 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
739
740 /* Enumeration returned by some move_it_.* functions internally. */
741
742 enum move_it_result
743 {
744 /* Not used. Undefined value. */
745 MOVE_UNDEFINED,
746
747 /* Move ended at the requested buffer position or ZV. */
748 MOVE_POS_MATCH_OR_ZV,
749
750 /* Move ended at the requested X pixel position. */
751 MOVE_X_REACHED,
752
753 /* Move within a line ended at the end of a line that must be
754 continued. */
755 MOVE_LINE_CONTINUED,
756
757 /* Move within a line ended at the end of a line that would
758 be displayed truncated. */
759 MOVE_LINE_TRUNCATED,
760
761 /* Move within a line ended at a line end. */
762 MOVE_NEWLINE_OR_CR
763 };
764
765 /* This counter is used to clear the face cache every once in a while
766 in redisplay_internal. It is incremented for each redisplay.
767 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
768 cleared. */
769
770 #define CLEAR_FACE_CACHE_COUNT 500
771 static int clear_face_cache_count;
772
773 /* Non-zero while redisplay_internal is in progress. */
774
775 int redisplaying_p;
776
777 /* Non-zero means don't free realized faces. Bound while freeing
778 realized faces is dangerous because glyph matrices might still
779 reference them. */
780
781 int inhibit_free_realized_faces;
782 Lisp_Object Qinhibit_free_realized_faces;
783
784 /* If a string, XTread_socket generates an event to display that string.
785 (The display is done in read_char.) */
786
787 Lisp_Object help_echo_string;
788 Lisp_Object help_echo_window;
789 Lisp_Object help_echo_object;
790 int help_echo_pos;
791
792 /* Temporary variable for XTread_socket. */
793
794 Lisp_Object previous_help_echo_string;
795
796
797 \f
798 /* Function prototypes. */
799
800 static void setup_for_ellipsis P_ ((struct it *));
801 static void mark_window_display_accurate_1 P_ ((struct window *, int));
802 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
803 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
804 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
805 static int redisplay_mode_lines P_ ((Lisp_Object, int));
806 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
807
808 #if 0
809 static int invisible_text_between_p P_ ((struct it *, int, int));
810 #endif
811
812 static int next_element_from_ellipsis P_ ((struct it *));
813 static void pint2str P_ ((char *, int, int));
814 static void pint2hrstr P_ ((char *, int, int));
815 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
816 struct text_pos));
817 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
818 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
819 static void store_frame_title_char P_ ((char));
820 static int store_frame_title P_ ((const unsigned char *, int, int));
821 static void x_consider_frame_title P_ ((Lisp_Object));
822 static void handle_stop P_ ((struct it *));
823 static int tool_bar_lines_needed P_ ((struct frame *));
824 static int single_display_prop_intangible_p P_ ((Lisp_Object));
825 static void ensure_echo_area_buffers P_ ((void));
826 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
827 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
828 static int with_echo_area_buffer P_ ((struct window *, int,
829 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
830 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
831 static void clear_garbaged_frames P_ ((void));
832 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
833 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
834 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
835 static int display_echo_area P_ ((struct window *));
836 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
837 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
838 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
839 static int string_char_and_length P_ ((const unsigned char *, int, int *));
840 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
841 struct text_pos));
842 static int compute_window_start_on_continuation_line P_ ((struct window *));
843 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
844 static void insert_left_trunc_glyphs P_ ((struct it *));
845 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
846 Lisp_Object));
847 static void extend_face_to_end_of_line P_ ((struct it *));
848 static int append_space P_ ((struct it *, int));
849 static int make_cursor_line_fully_visible P_ ((struct window *, int));
850 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
851 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
852 static int trailing_whitespace_p P_ ((int));
853 static int message_log_check_duplicate P_ ((int, int, int, int));
854 static void push_it P_ ((struct it *));
855 static void pop_it P_ ((struct it *));
856 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
857 static void select_frame_for_redisplay P_ ((Lisp_Object));
858 static void redisplay_internal P_ ((int));
859 static int echo_area_display P_ ((int));
860 static void redisplay_windows P_ ((Lisp_Object));
861 static void redisplay_window P_ ((Lisp_Object, int));
862 static Lisp_Object redisplay_window_error ();
863 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
864 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
865 static void update_menu_bar P_ ((struct frame *, int));
866 static int try_window_reusing_current_matrix P_ ((struct window *));
867 static int try_window_id P_ ((struct window *));
868 static int display_line P_ ((struct it *));
869 static int display_mode_lines P_ ((struct window *));
870 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
871 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
872 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
873 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
874 static void display_menu_bar P_ ((struct window *));
875 static int display_count_lines P_ ((int, int, int, int, int *));
876 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
877 int, int, struct it *, int, int, int, int));
878 static void compute_line_metrics P_ ((struct it *));
879 static void run_redisplay_end_trigger_hook P_ ((struct it *));
880 static int get_overlay_strings P_ ((struct it *, int));
881 static void next_overlay_string P_ ((struct it *));
882 static void reseat P_ ((struct it *, struct text_pos, int));
883 static void reseat_1 P_ ((struct it *, struct text_pos, int));
884 static void back_to_previous_visible_line_start P_ ((struct it *));
885 static void reseat_at_previous_visible_line_start P_ ((struct it *));
886 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
887 static int next_element_from_display_vector P_ ((struct it *));
888 static int next_element_from_string P_ ((struct it *));
889 static int next_element_from_c_string P_ ((struct it *));
890 static int next_element_from_buffer P_ ((struct it *));
891 static int next_element_from_composition P_ ((struct it *));
892 static int next_element_from_image P_ ((struct it *));
893 static int next_element_from_stretch P_ ((struct it *));
894 static void load_overlay_strings P_ ((struct it *, int));
895 static int init_from_display_pos P_ ((struct it *, struct window *,
896 struct display_pos *));
897 static void reseat_to_string P_ ((struct it *, unsigned char *,
898 Lisp_Object, int, int, int, int));
899 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
900 int, int, int));
901 void move_it_vertically_backward P_ ((struct it *, int));
902 static void init_to_row_start P_ ((struct it *, struct window *,
903 struct glyph_row *));
904 static int init_to_row_end P_ ((struct it *, struct window *,
905 struct glyph_row *));
906 static void back_to_previous_line_start P_ ((struct it *));
907 static int forward_to_next_line_start P_ ((struct it *, int *));
908 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
909 Lisp_Object, int));
910 static struct text_pos string_pos P_ ((int, Lisp_Object));
911 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
912 static int number_of_chars P_ ((unsigned char *, int));
913 static void compute_stop_pos P_ ((struct it *));
914 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
915 Lisp_Object));
916 static int face_before_or_after_it_pos P_ ((struct it *, int));
917 static int next_overlay_change P_ ((int));
918 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
919 Lisp_Object, struct text_pos *,
920 int));
921 static int underlying_face_id P_ ((struct it *));
922 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
923 struct window *));
924
925 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
926 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
927
928 #ifdef HAVE_WINDOW_SYSTEM
929
930 static void update_tool_bar P_ ((struct frame *, int));
931 static void build_desired_tool_bar_string P_ ((struct frame *f));
932 static int redisplay_tool_bar P_ ((struct frame *));
933 static void display_tool_bar_line P_ ((struct it *));
934 static void notice_overwritten_cursor P_ ((struct window *,
935 enum glyph_row_area,
936 int, int, int, int));
937
938
939
940 #endif /* HAVE_WINDOW_SYSTEM */
941
942 \f
943 /***********************************************************************
944 Window display dimensions
945 ***********************************************************************/
946
947 /* Return the bottom boundary y-position for text lines in window W.
948 This is the first y position at which a line cannot start.
949 It is relative to the top of the window.
950
951 This is the height of W minus the height of a mode line, if any. */
952
953 INLINE int
954 window_text_bottom_y (w)
955 struct window *w;
956 {
957 int height = WINDOW_TOTAL_HEIGHT (w);
958
959 if (WINDOW_WANTS_MODELINE_P (w))
960 height -= CURRENT_MODE_LINE_HEIGHT (w);
961 return height;
962 }
963
964 /* Return the pixel width of display area AREA of window W. AREA < 0
965 means return the total width of W, not including fringes to
966 the left and right of the window. */
967
968 INLINE int
969 window_box_width (w, area)
970 struct window *w;
971 int area;
972 {
973 int cols = XFASTINT (w->total_cols);
974 int pixels = 0;
975
976 if (!w->pseudo_window_p)
977 {
978 cols -= WINDOW_SCROLL_BAR_COLS (w);
979
980 if (area == TEXT_AREA)
981 {
982 if (INTEGERP (w->left_margin_cols))
983 cols -= XFASTINT (w->left_margin_cols);
984 if (INTEGERP (w->right_margin_cols))
985 cols -= XFASTINT (w->right_margin_cols);
986 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
987 }
988 else if (area == LEFT_MARGIN_AREA)
989 {
990 cols = (INTEGERP (w->left_margin_cols)
991 ? XFASTINT (w->left_margin_cols) : 0);
992 pixels = 0;
993 }
994 else if (area == RIGHT_MARGIN_AREA)
995 {
996 cols = (INTEGERP (w->right_margin_cols)
997 ? XFASTINT (w->right_margin_cols) : 0);
998 pixels = 0;
999 }
1000 }
1001
1002 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1003 }
1004
1005
1006 /* Return the pixel height of the display area of window W, not
1007 including mode lines of W, if any. */
1008
1009 INLINE int
1010 window_box_height (w)
1011 struct window *w;
1012 {
1013 struct frame *f = XFRAME (w->frame);
1014 int height = WINDOW_TOTAL_HEIGHT (w);
1015
1016 xassert (height >= 0);
1017
1018 /* Note: the code below that determines the mode-line/header-line
1019 height is essentially the same as that contained in the macro
1020 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1021 the appropriate glyph row has its `mode_line_p' flag set,
1022 and if it doesn't, uses estimate_mode_line_height instead. */
1023
1024 if (WINDOW_WANTS_MODELINE_P (w))
1025 {
1026 struct glyph_row *ml_row
1027 = (w->current_matrix && w->current_matrix->rows
1028 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1029 : 0);
1030 if (ml_row && ml_row->mode_line_p)
1031 height -= ml_row->height;
1032 else
1033 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1034 }
1035
1036 if (WINDOW_WANTS_HEADER_LINE_P (w))
1037 {
1038 struct glyph_row *hl_row
1039 = (w->current_matrix && w->current_matrix->rows
1040 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1041 : 0);
1042 if (hl_row && hl_row->mode_line_p)
1043 height -= hl_row->height;
1044 else
1045 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1046 }
1047
1048 /* With a very small font and a mode-line that's taller than
1049 default, we might end up with a negative height. */
1050 return max (0, height);
1051 }
1052
1053 /* Return the window-relative coordinate of the left edge of display
1054 area AREA of window W. AREA < 0 means return the left edge of the
1055 whole window, to the right of the left fringe of W. */
1056
1057 INLINE int
1058 window_box_left_offset (w, area)
1059 struct window *w;
1060 int area;
1061 {
1062 int x;
1063
1064 if (w->pseudo_window_p)
1065 return 0;
1066
1067 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1068
1069 if (area == TEXT_AREA)
1070 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1071 + window_box_width (w, LEFT_MARGIN_AREA));
1072 else if (area == RIGHT_MARGIN_AREA)
1073 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1074 + window_box_width (w, LEFT_MARGIN_AREA)
1075 + window_box_width (w, TEXT_AREA)
1076 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1077 ? 0
1078 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1079 else if (area == LEFT_MARGIN_AREA
1080 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1081 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1082
1083 return x;
1084 }
1085
1086
1087 /* Return the window-relative coordinate of the right edge of display
1088 area AREA of window W. AREA < 0 means return the left edge of the
1089 whole window, to the left of the right fringe of W. */
1090
1091 INLINE int
1092 window_box_right_offset (w, area)
1093 struct window *w;
1094 int area;
1095 {
1096 return window_box_left_offset (w, area) + window_box_width (w, area);
1097 }
1098
1099 /* Return the frame-relative coordinate of the left edge of display
1100 area AREA of window W. AREA < 0 means return the left edge of the
1101 whole window, to the right of the left fringe of W. */
1102
1103 INLINE int
1104 window_box_left (w, area)
1105 struct window *w;
1106 int area;
1107 {
1108 struct frame *f = XFRAME (w->frame);
1109 int x;
1110
1111 if (w->pseudo_window_p)
1112 return FRAME_INTERNAL_BORDER_WIDTH (f);
1113
1114 x = (WINDOW_LEFT_EDGE_X (w)
1115 + window_box_left_offset (w, area));
1116
1117 return x;
1118 }
1119
1120
1121 /* Return the frame-relative coordinate of the right edge of display
1122 area AREA of window W. AREA < 0 means return the left edge of the
1123 whole window, to the left of the right fringe of W. */
1124
1125 INLINE int
1126 window_box_right (w, area)
1127 struct window *w;
1128 int area;
1129 {
1130 return window_box_left (w, area) + window_box_width (w, area);
1131 }
1132
1133 /* Get the bounding box of the display area AREA of window W, without
1134 mode lines, in frame-relative coordinates. AREA < 0 means the
1135 whole window, not including the left and right fringes of
1136 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1137 coordinates of the upper-left corner of the box. Return in
1138 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1139
1140 INLINE void
1141 window_box (w, area, box_x, box_y, box_width, box_height)
1142 struct window *w;
1143 int area;
1144 int *box_x, *box_y, *box_width, *box_height;
1145 {
1146 if (box_width)
1147 *box_width = window_box_width (w, area);
1148 if (box_height)
1149 *box_height = window_box_height (w);
1150 if (box_x)
1151 *box_x = window_box_left (w, area);
1152 if (box_y)
1153 {
1154 *box_y = WINDOW_TOP_EDGE_Y (w);
1155 if (WINDOW_WANTS_HEADER_LINE_P (w))
1156 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1157 }
1158 }
1159
1160
1161 /* Get the bounding box of the display area AREA of window W, without
1162 mode lines. AREA < 0 means the whole window, not including the
1163 left and right fringe of the window. Return in *TOP_LEFT_X
1164 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1165 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1166 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1167 box. */
1168
1169 INLINE void
1170 window_box_edges (w, area, top_left_x, top_left_y,
1171 bottom_right_x, bottom_right_y)
1172 struct window *w;
1173 int area;
1174 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1175 {
1176 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1177 bottom_right_y);
1178 *bottom_right_x += *top_left_x;
1179 *bottom_right_y += *top_left_y;
1180 }
1181
1182
1183 \f
1184 /***********************************************************************
1185 Utilities
1186 ***********************************************************************/
1187
1188 /* Return the bottom y-position of the line the iterator IT is in.
1189 This can modify IT's settings. */
1190
1191 int
1192 line_bottom_y (it)
1193 struct it *it;
1194 {
1195 int line_height = it->max_ascent + it->max_descent;
1196 int line_top_y = it->current_y;
1197
1198 if (line_height == 0)
1199 {
1200 if (last_height)
1201 line_height = last_height;
1202 else if (IT_CHARPOS (*it) < ZV)
1203 {
1204 move_it_by_lines (it, 1, 1);
1205 line_height = (it->max_ascent || it->max_descent
1206 ? it->max_ascent + it->max_descent
1207 : last_height);
1208 }
1209 else
1210 {
1211 struct glyph_row *row = it->glyph_row;
1212
1213 /* Use the default character height. */
1214 it->glyph_row = NULL;
1215 it->what = IT_CHARACTER;
1216 it->c = ' ';
1217 it->len = 1;
1218 PRODUCE_GLYPHS (it);
1219 line_height = it->ascent + it->descent;
1220 it->glyph_row = row;
1221 }
1222 }
1223
1224 return line_top_y + line_height;
1225 }
1226
1227
1228 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1229 1 if POS is visible and the line containing POS is fully visible.
1230 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1231 and header-lines heights. */
1232
1233 int
1234 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1235 struct window *w;
1236 int charpos, *fully, exact_mode_line_heights_p;
1237 {
1238 struct it it;
1239 struct text_pos top;
1240 int visible_p;
1241 struct buffer *old_buffer = NULL;
1242
1243 if (XBUFFER (w->buffer) != current_buffer)
1244 {
1245 old_buffer = current_buffer;
1246 set_buffer_internal_1 (XBUFFER (w->buffer));
1247 }
1248
1249 *fully = visible_p = 0;
1250 SET_TEXT_POS_FROM_MARKER (top, w->start);
1251
1252 /* Compute exact mode line heights, if requested. */
1253 if (exact_mode_line_heights_p)
1254 {
1255 if (WINDOW_WANTS_MODELINE_P (w))
1256 current_mode_line_height
1257 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1258 current_buffer->mode_line_format);
1259
1260 if (WINDOW_WANTS_HEADER_LINE_P (w))
1261 current_header_line_height
1262 = display_mode_line (w, HEADER_LINE_FACE_ID,
1263 current_buffer->header_line_format);
1264 }
1265
1266 start_display (&it, w, top);
1267 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1268 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1269
1270 /* Note that we may overshoot because of invisible text. */
1271 if (IT_CHARPOS (it) >= charpos)
1272 {
1273 int top_y = it.current_y;
1274 int bottom_y = line_bottom_y (&it);
1275 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1276
1277 if (top_y < window_top_y)
1278 visible_p = bottom_y > window_top_y;
1279 else if (top_y < it.last_visible_y)
1280 {
1281 visible_p = 1;
1282 *fully = bottom_y <= it.last_visible_y;
1283 }
1284 }
1285 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1286 {
1287 move_it_by_lines (&it, 1, 0);
1288 if (charpos < IT_CHARPOS (it))
1289 {
1290 visible_p = 1;
1291 *fully = 0;
1292 }
1293 }
1294
1295 if (old_buffer)
1296 set_buffer_internal_1 (old_buffer);
1297
1298 current_header_line_height = current_mode_line_height = -1;
1299 return visible_p;
1300 }
1301
1302
1303 /* Return the next character from STR which is MAXLEN bytes long.
1304 Return in *LEN the length of the character. This is like
1305 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1306 we find one, we return a `?', but with the length of the invalid
1307 character. */
1308
1309 static INLINE int
1310 string_char_and_length (str, maxlen, len)
1311 const unsigned char *str;
1312 int maxlen, *len;
1313 {
1314 int c;
1315
1316 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1317 if (!CHAR_VALID_P (c, 1))
1318 /* We may not change the length here because other places in Emacs
1319 don't use this function, i.e. they silently accept invalid
1320 characters. */
1321 c = '?';
1322
1323 return c;
1324 }
1325
1326
1327
1328 /* Given a position POS containing a valid character and byte position
1329 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1330
1331 static struct text_pos
1332 string_pos_nchars_ahead (pos, string, nchars)
1333 struct text_pos pos;
1334 Lisp_Object string;
1335 int nchars;
1336 {
1337 xassert (STRINGP (string) && nchars >= 0);
1338
1339 if (STRING_MULTIBYTE (string))
1340 {
1341 int rest = SBYTES (string) - BYTEPOS (pos);
1342 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1343 int len;
1344
1345 while (nchars--)
1346 {
1347 string_char_and_length (p, rest, &len);
1348 p += len, rest -= len;
1349 xassert (rest >= 0);
1350 CHARPOS (pos) += 1;
1351 BYTEPOS (pos) += len;
1352 }
1353 }
1354 else
1355 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1356
1357 return pos;
1358 }
1359
1360
1361 /* Value is the text position, i.e. character and byte position,
1362 for character position CHARPOS in STRING. */
1363
1364 static INLINE struct text_pos
1365 string_pos (charpos, string)
1366 int charpos;
1367 Lisp_Object string;
1368 {
1369 struct text_pos pos;
1370 xassert (STRINGP (string));
1371 xassert (charpos >= 0);
1372 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1373 return pos;
1374 }
1375
1376
1377 /* Value is a text position, i.e. character and byte position, for
1378 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1379 means recognize multibyte characters. */
1380
1381 static struct text_pos
1382 c_string_pos (charpos, s, multibyte_p)
1383 int charpos;
1384 unsigned char *s;
1385 int multibyte_p;
1386 {
1387 struct text_pos pos;
1388
1389 xassert (s != NULL);
1390 xassert (charpos >= 0);
1391
1392 if (multibyte_p)
1393 {
1394 int rest = strlen (s), len;
1395
1396 SET_TEXT_POS (pos, 0, 0);
1397 while (charpos--)
1398 {
1399 string_char_and_length (s, rest, &len);
1400 s += len, rest -= len;
1401 xassert (rest >= 0);
1402 CHARPOS (pos) += 1;
1403 BYTEPOS (pos) += len;
1404 }
1405 }
1406 else
1407 SET_TEXT_POS (pos, charpos, charpos);
1408
1409 return pos;
1410 }
1411
1412
1413 /* Value is the number of characters in C string S. MULTIBYTE_P
1414 non-zero means recognize multibyte characters. */
1415
1416 static int
1417 number_of_chars (s, multibyte_p)
1418 unsigned char *s;
1419 int multibyte_p;
1420 {
1421 int nchars;
1422
1423 if (multibyte_p)
1424 {
1425 int rest = strlen (s), len;
1426 unsigned char *p = (unsigned char *) s;
1427
1428 for (nchars = 0; rest > 0; ++nchars)
1429 {
1430 string_char_and_length (p, rest, &len);
1431 rest -= len, p += len;
1432 }
1433 }
1434 else
1435 nchars = strlen (s);
1436
1437 return nchars;
1438 }
1439
1440
1441 /* Compute byte position NEWPOS->bytepos corresponding to
1442 NEWPOS->charpos. POS is a known position in string STRING.
1443 NEWPOS->charpos must be >= POS.charpos. */
1444
1445 static void
1446 compute_string_pos (newpos, pos, string)
1447 struct text_pos *newpos, pos;
1448 Lisp_Object string;
1449 {
1450 xassert (STRINGP (string));
1451 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1452
1453 if (STRING_MULTIBYTE (string))
1454 *newpos = string_pos_nchars_ahead (pos, string,
1455 CHARPOS (*newpos) - CHARPOS (pos));
1456 else
1457 BYTEPOS (*newpos) = CHARPOS (*newpos);
1458 }
1459
1460 /* EXPORT:
1461 Return an estimation of the pixel height of mode or top lines on
1462 frame F. FACE_ID specifies what line's height to estimate. */
1463
1464 int
1465 estimate_mode_line_height (f, face_id)
1466 struct frame *f;
1467 enum face_id face_id;
1468 {
1469 #ifdef HAVE_WINDOW_SYSTEM
1470 if (FRAME_WINDOW_P (f))
1471 {
1472 int height = FONT_HEIGHT (FRAME_FONT (f));
1473
1474 /* This function is called so early when Emacs starts that the face
1475 cache and mode line face are not yet initialized. */
1476 if (FRAME_FACE_CACHE (f))
1477 {
1478 struct face *face = FACE_FROM_ID (f, face_id);
1479 if (face)
1480 {
1481 if (face->font)
1482 height = FONT_HEIGHT (face->font);
1483 if (face->box_line_width > 0)
1484 height += 2 * face->box_line_width;
1485 }
1486 }
1487
1488 return height;
1489 }
1490 #endif
1491
1492 return 1;
1493 }
1494
1495 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1496 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1497 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1498 not force the value into range. */
1499
1500 void
1501 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1502 FRAME_PTR f;
1503 register int pix_x, pix_y;
1504 int *x, *y;
1505 NativeRectangle *bounds;
1506 int noclip;
1507 {
1508
1509 #ifdef HAVE_WINDOW_SYSTEM
1510 if (FRAME_WINDOW_P (f))
1511 {
1512 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1513 even for negative values. */
1514 if (pix_x < 0)
1515 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1516 if (pix_y < 0)
1517 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1518
1519 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1520 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1521
1522 if (bounds)
1523 STORE_NATIVE_RECT (*bounds,
1524 FRAME_COL_TO_PIXEL_X (f, pix_x),
1525 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1526 FRAME_COLUMN_WIDTH (f) - 1,
1527 FRAME_LINE_HEIGHT (f) - 1);
1528
1529 if (!noclip)
1530 {
1531 if (pix_x < 0)
1532 pix_x = 0;
1533 else if (pix_x > FRAME_TOTAL_COLS (f))
1534 pix_x = FRAME_TOTAL_COLS (f);
1535
1536 if (pix_y < 0)
1537 pix_y = 0;
1538 else if (pix_y > FRAME_LINES (f))
1539 pix_y = FRAME_LINES (f);
1540 }
1541 }
1542 #endif
1543
1544 *x = pix_x;
1545 *y = pix_y;
1546 }
1547
1548
1549 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1550 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1551 can't tell the positions because W's display is not up to date,
1552 return 0. */
1553
1554 int
1555 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1556 struct window *w;
1557 int hpos, vpos;
1558 int *frame_x, *frame_y;
1559 {
1560 #ifdef HAVE_WINDOW_SYSTEM
1561 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1562 {
1563 int success_p;
1564
1565 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1566 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1567
1568 if (display_completed)
1569 {
1570 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1571 struct glyph *glyph = row->glyphs[TEXT_AREA];
1572 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1573
1574 hpos = row->x;
1575 vpos = row->y;
1576 while (glyph < end)
1577 {
1578 hpos += glyph->pixel_width;
1579 ++glyph;
1580 }
1581
1582 /* If first glyph is partially visible, its first visible position is still 0. */
1583 if (hpos < 0)
1584 hpos = 0;
1585
1586 success_p = 1;
1587 }
1588 else
1589 {
1590 hpos = vpos = 0;
1591 success_p = 0;
1592 }
1593
1594 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1595 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1596 return success_p;
1597 }
1598 #endif
1599
1600 *frame_x = hpos;
1601 *frame_y = vpos;
1602 return 1;
1603 }
1604
1605
1606 #ifdef HAVE_WINDOW_SYSTEM
1607
1608 /* Find the glyph under window-relative coordinates X/Y in window W.
1609 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1610 strings. Return in *HPOS and *VPOS the row and column number of
1611 the glyph found. Return in *AREA the glyph area containing X.
1612 Value is a pointer to the glyph found or null if X/Y is not on
1613 text, or we can't tell because W's current matrix is not up to
1614 date. */
1615
1616 static struct glyph *
1617 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1618 struct window *w;
1619 int x, y;
1620 int *hpos, *vpos, *dx, *dy, *area;
1621 {
1622 struct glyph *glyph, *end;
1623 struct glyph_row *row = NULL;
1624 int x0, i;
1625
1626 /* Find row containing Y. Give up if some row is not enabled. */
1627 for (i = 0; i < w->current_matrix->nrows; ++i)
1628 {
1629 row = MATRIX_ROW (w->current_matrix, i);
1630 if (!row->enabled_p)
1631 return NULL;
1632 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1633 break;
1634 }
1635
1636 *vpos = i;
1637 *hpos = 0;
1638
1639 /* Give up if Y is not in the window. */
1640 if (i == w->current_matrix->nrows)
1641 return NULL;
1642
1643 /* Get the glyph area containing X. */
1644 if (w->pseudo_window_p)
1645 {
1646 *area = TEXT_AREA;
1647 x0 = 0;
1648 }
1649 else
1650 {
1651 if (x < window_box_left_offset (w, TEXT_AREA))
1652 {
1653 *area = LEFT_MARGIN_AREA;
1654 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1655 }
1656 else if (x < window_box_right_offset (w, TEXT_AREA))
1657 {
1658 *area = TEXT_AREA;
1659 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1660 }
1661 else
1662 {
1663 *area = RIGHT_MARGIN_AREA;
1664 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1665 }
1666 }
1667
1668 /* Find glyph containing X. */
1669 glyph = row->glyphs[*area];
1670 end = glyph + row->used[*area];
1671 x -= x0;
1672 while (glyph < end && x >= glyph->pixel_width)
1673 {
1674 x -= glyph->pixel_width;
1675 ++glyph;
1676 }
1677
1678 if (glyph == end)
1679 return NULL;
1680
1681 if (dx)
1682 {
1683 *dx = x;
1684 *dy = y - (row->y + row->ascent - glyph->ascent);
1685 }
1686
1687 *hpos = glyph - row->glyphs[*area];
1688 return glyph;
1689 }
1690
1691
1692 /* EXPORT:
1693 Convert frame-relative x/y to coordinates relative to window W.
1694 Takes pseudo-windows into account. */
1695
1696 void
1697 frame_to_window_pixel_xy (w, x, y)
1698 struct window *w;
1699 int *x, *y;
1700 {
1701 if (w->pseudo_window_p)
1702 {
1703 /* A pseudo-window is always full-width, and starts at the
1704 left edge of the frame, plus a frame border. */
1705 struct frame *f = XFRAME (w->frame);
1706 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1707 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1708 }
1709 else
1710 {
1711 *x -= WINDOW_LEFT_EDGE_X (w);
1712 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1713 }
1714 }
1715
1716 /* EXPORT:
1717 Return in *R the clipping rectangle for glyph string S. */
1718
1719 void
1720 get_glyph_string_clip_rect (s, nr)
1721 struct glyph_string *s;
1722 NativeRectangle *nr;
1723 {
1724 XRectangle r;
1725
1726 if (s->row->full_width_p)
1727 {
1728 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1729 r.x = WINDOW_LEFT_EDGE_X (s->w);
1730 r.width = WINDOW_TOTAL_WIDTH (s->w);
1731
1732 /* Unless displaying a mode or menu bar line, which are always
1733 fully visible, clip to the visible part of the row. */
1734 if (s->w->pseudo_window_p)
1735 r.height = s->row->visible_height;
1736 else
1737 r.height = s->height;
1738 }
1739 else
1740 {
1741 /* This is a text line that may be partially visible. */
1742 r.x = window_box_left (s->w, s->area);
1743 r.width = window_box_width (s->w, s->area);
1744 r.height = s->row->visible_height;
1745 }
1746
1747 /* If S draws overlapping rows, it's sufficient to use the top and
1748 bottom of the window for clipping because this glyph string
1749 intentionally draws over other lines. */
1750 if (s->for_overlaps_p)
1751 {
1752 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1753 r.height = window_text_bottom_y (s->w) - r.y;
1754 }
1755 else
1756 {
1757 /* Don't use S->y for clipping because it doesn't take partially
1758 visible lines into account. For example, it can be negative for
1759 partially visible lines at the top of a window. */
1760 if (!s->row->full_width_p
1761 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1762 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1763 else
1764 r.y = max (0, s->row->y);
1765
1766 /* If drawing a tool-bar window, draw it over the internal border
1767 at the top of the window. */
1768 if (s->w == XWINDOW (s->f->tool_bar_window))
1769 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1770 }
1771
1772 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1773
1774 /* If drawing the cursor, don't let glyph draw outside its
1775 advertised boundaries. Cleartype does this under some circumstances. */
1776 if (s->hl == DRAW_CURSOR)
1777 {
1778 struct glyph *glyph = s->first_glyph;
1779 int height;
1780
1781 if (s->x > r.x)
1782 {
1783 r.width -= s->x - r.x;
1784 r.x = s->x;
1785 }
1786 r.width = min (r.width, glyph->pixel_width);
1787
1788 /* Don't draw cursor glyph taller than our actual glyph. */
1789 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1790 if (height < r.height)
1791 {
1792 int max_y = r.y + r.height;
1793 r.y = min (max_y, s->ybase + glyph->descent - height);
1794 r.height = min (max_y - r.y, height);
1795 }
1796 }
1797
1798 #ifdef CONVERT_FROM_XRECT
1799 CONVERT_FROM_XRECT (r, *nr);
1800 #else
1801 *nr = r;
1802 #endif
1803 }
1804
1805 #endif /* HAVE_WINDOW_SYSTEM */
1806
1807 \f
1808 /***********************************************************************
1809 Lisp form evaluation
1810 ***********************************************************************/
1811
1812 /* Error handler for safe_eval and safe_call. */
1813
1814 static Lisp_Object
1815 safe_eval_handler (arg)
1816 Lisp_Object arg;
1817 {
1818 add_to_log ("Error during redisplay: %s", arg, Qnil);
1819 return Qnil;
1820 }
1821
1822
1823 /* Evaluate SEXPR and return the result, or nil if something went
1824 wrong. Prevent redisplay during the evaluation. */
1825
1826 Lisp_Object
1827 safe_eval (sexpr)
1828 Lisp_Object sexpr;
1829 {
1830 Lisp_Object val;
1831
1832 if (inhibit_eval_during_redisplay)
1833 val = Qnil;
1834 else
1835 {
1836 int count = SPECPDL_INDEX ();
1837 struct gcpro gcpro1;
1838
1839 GCPRO1 (sexpr);
1840 specbind (Qinhibit_redisplay, Qt);
1841 /* Use Qt to ensure debugger does not run,
1842 so there is no possibility of wanting to redisplay. */
1843 val = internal_condition_case_1 (Feval, sexpr, Qt,
1844 safe_eval_handler);
1845 UNGCPRO;
1846 val = unbind_to (count, val);
1847 }
1848
1849 return val;
1850 }
1851
1852
1853 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1854 Return the result, or nil if something went wrong. Prevent
1855 redisplay during the evaluation. */
1856
1857 Lisp_Object
1858 safe_call (nargs, args)
1859 int nargs;
1860 Lisp_Object *args;
1861 {
1862 Lisp_Object val;
1863
1864 if (inhibit_eval_during_redisplay)
1865 val = Qnil;
1866 else
1867 {
1868 int count = SPECPDL_INDEX ();
1869 struct gcpro gcpro1;
1870
1871 GCPRO1 (args[0]);
1872 gcpro1.nvars = nargs;
1873 specbind (Qinhibit_redisplay, Qt);
1874 /* Use Qt to ensure debugger does not run,
1875 so there is no possibility of wanting to redisplay. */
1876 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1877 safe_eval_handler);
1878 UNGCPRO;
1879 val = unbind_to (count, val);
1880 }
1881
1882 return val;
1883 }
1884
1885
1886 /* Call function FN with one argument ARG.
1887 Return the result, or nil if something went wrong. */
1888
1889 Lisp_Object
1890 safe_call1 (fn, arg)
1891 Lisp_Object fn, arg;
1892 {
1893 Lisp_Object args[2];
1894 args[0] = fn;
1895 args[1] = arg;
1896 return safe_call (2, args);
1897 }
1898
1899
1900 \f
1901 /***********************************************************************
1902 Debugging
1903 ***********************************************************************/
1904
1905 #if 0
1906
1907 /* Define CHECK_IT to perform sanity checks on iterators.
1908 This is for debugging. It is too slow to do unconditionally. */
1909
1910 static void
1911 check_it (it)
1912 struct it *it;
1913 {
1914 if (it->method == next_element_from_string)
1915 {
1916 xassert (STRINGP (it->string));
1917 xassert (IT_STRING_CHARPOS (*it) >= 0);
1918 }
1919 else
1920 {
1921 xassert (IT_STRING_CHARPOS (*it) < 0);
1922 if (it->method == next_element_from_buffer)
1923 {
1924 /* Check that character and byte positions agree. */
1925 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1926 }
1927 }
1928
1929 if (it->dpvec)
1930 xassert (it->current.dpvec_index >= 0);
1931 else
1932 xassert (it->current.dpvec_index < 0);
1933 }
1934
1935 #define CHECK_IT(IT) check_it ((IT))
1936
1937 #else /* not 0 */
1938
1939 #define CHECK_IT(IT) (void) 0
1940
1941 #endif /* not 0 */
1942
1943
1944 #if GLYPH_DEBUG
1945
1946 /* Check that the window end of window W is what we expect it
1947 to be---the last row in the current matrix displaying text. */
1948
1949 static void
1950 check_window_end (w)
1951 struct window *w;
1952 {
1953 if (!MINI_WINDOW_P (w)
1954 && !NILP (w->window_end_valid))
1955 {
1956 struct glyph_row *row;
1957 xassert ((row = MATRIX_ROW (w->current_matrix,
1958 XFASTINT (w->window_end_vpos)),
1959 !row->enabled_p
1960 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1961 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1962 }
1963 }
1964
1965 #define CHECK_WINDOW_END(W) check_window_end ((W))
1966
1967 #else /* not GLYPH_DEBUG */
1968
1969 #define CHECK_WINDOW_END(W) (void) 0
1970
1971 #endif /* not GLYPH_DEBUG */
1972
1973
1974 \f
1975 /***********************************************************************
1976 Iterator initialization
1977 ***********************************************************************/
1978
1979 /* Initialize IT for displaying current_buffer in window W, starting
1980 at character position CHARPOS. CHARPOS < 0 means that no buffer
1981 position is specified which is useful when the iterator is assigned
1982 a position later. BYTEPOS is the byte position corresponding to
1983 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1984
1985 If ROW is not null, calls to produce_glyphs with IT as parameter
1986 will produce glyphs in that row.
1987
1988 BASE_FACE_ID is the id of a base face to use. It must be one of
1989 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1990 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1991 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1992
1993 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1994 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1995 will be initialized to use the corresponding mode line glyph row of
1996 the desired matrix of W. */
1997
1998 void
1999 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2000 struct it *it;
2001 struct window *w;
2002 int charpos, bytepos;
2003 struct glyph_row *row;
2004 enum face_id base_face_id;
2005 {
2006 int highlight_region_p;
2007
2008 /* Some precondition checks. */
2009 xassert (w != NULL && it != NULL);
2010 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2011 && charpos <= ZV));
2012
2013 /* If face attributes have been changed since the last redisplay,
2014 free realized faces now because they depend on face definitions
2015 that might have changed. Don't free faces while there might be
2016 desired matrices pending which reference these faces. */
2017 if (face_change_count && !inhibit_free_realized_faces)
2018 {
2019 face_change_count = 0;
2020 free_all_realized_faces (Qnil);
2021 }
2022
2023 /* Use one of the mode line rows of W's desired matrix if
2024 appropriate. */
2025 if (row == NULL)
2026 {
2027 if (base_face_id == MODE_LINE_FACE_ID
2028 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2029 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2030 else if (base_face_id == HEADER_LINE_FACE_ID)
2031 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2032 }
2033
2034 /* Clear IT. */
2035 bzero (it, sizeof *it);
2036 it->current.overlay_string_index = -1;
2037 it->current.dpvec_index = -1;
2038 it->base_face_id = base_face_id;
2039 it->string = Qnil;
2040 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2041
2042 /* The window in which we iterate over current_buffer: */
2043 XSETWINDOW (it->window, w);
2044 it->w = w;
2045 it->f = XFRAME (w->frame);
2046
2047 /* Extra space between lines (on window systems only). */
2048 if (base_face_id == DEFAULT_FACE_ID
2049 && FRAME_WINDOW_P (it->f))
2050 {
2051 if (NATNUMP (current_buffer->extra_line_spacing))
2052 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2053 else if (it->f->extra_line_spacing > 0)
2054 it->extra_line_spacing = it->f->extra_line_spacing;
2055 }
2056
2057 /* If realized faces have been removed, e.g. because of face
2058 attribute changes of named faces, recompute them. When running
2059 in batch mode, the face cache of the initial frame is null. If
2060 we happen to get called, make a dummy face cache. */
2061 if (FRAME_FACE_CACHE (it->f) == NULL)
2062 init_frame_faces (it->f);
2063 if (FRAME_FACE_CACHE (it->f)->used == 0)
2064 recompute_basic_faces (it->f);
2065
2066 /* Current value of the `space-width', and 'height' properties. */
2067 it->space_width = Qnil;
2068 it->font_height = Qnil;
2069
2070 /* Are control characters displayed as `^C'? */
2071 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2072
2073 /* -1 means everything between a CR and the following line end
2074 is invisible. >0 means lines indented more than this value are
2075 invisible. */
2076 it->selective = (INTEGERP (current_buffer->selective_display)
2077 ? XFASTINT (current_buffer->selective_display)
2078 : (!NILP (current_buffer->selective_display)
2079 ? -1 : 0));
2080 it->selective_display_ellipsis_p
2081 = !NILP (current_buffer->selective_display_ellipses);
2082
2083 /* Display table to use. */
2084 it->dp = window_display_table (w);
2085
2086 /* Are multibyte characters enabled in current_buffer? */
2087 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2088
2089 /* Non-zero if we should highlight the region. */
2090 highlight_region_p
2091 = (!NILP (Vtransient_mark_mode)
2092 && !NILP (current_buffer->mark_active)
2093 && XMARKER (current_buffer->mark)->buffer != 0);
2094
2095 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2096 start and end of a visible region in window IT->w. Set both to
2097 -1 to indicate no region. */
2098 if (highlight_region_p
2099 /* Maybe highlight only in selected window. */
2100 && (/* Either show region everywhere. */
2101 highlight_nonselected_windows
2102 /* Or show region in the selected window. */
2103 || w == XWINDOW (selected_window)
2104 /* Or show the region if we are in the mini-buffer and W is
2105 the window the mini-buffer refers to. */
2106 || (MINI_WINDOW_P (XWINDOW (selected_window))
2107 && WINDOWP (minibuf_selected_window)
2108 && w == XWINDOW (minibuf_selected_window))))
2109 {
2110 int charpos = marker_position (current_buffer->mark);
2111 it->region_beg_charpos = min (PT, charpos);
2112 it->region_end_charpos = max (PT, charpos);
2113 }
2114 else
2115 it->region_beg_charpos = it->region_end_charpos = -1;
2116
2117 /* Get the position at which the redisplay_end_trigger hook should
2118 be run, if it is to be run at all. */
2119 if (MARKERP (w->redisplay_end_trigger)
2120 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2121 it->redisplay_end_trigger_charpos
2122 = marker_position (w->redisplay_end_trigger);
2123 else if (INTEGERP (w->redisplay_end_trigger))
2124 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2125
2126 /* Correct bogus values of tab_width. */
2127 it->tab_width = XINT (current_buffer->tab_width);
2128 if (it->tab_width <= 0 || it->tab_width > 1000)
2129 it->tab_width = 8;
2130
2131 /* Are lines in the display truncated? */
2132 it->truncate_lines_p
2133 = (base_face_id != DEFAULT_FACE_ID
2134 || XINT (it->w->hscroll)
2135 || (truncate_partial_width_windows
2136 && !WINDOW_FULL_WIDTH_P (it->w))
2137 || !NILP (current_buffer->truncate_lines));
2138
2139 /* Get dimensions of truncation and continuation glyphs. These are
2140 displayed as fringe bitmaps under X, so we don't need them for such
2141 frames. */
2142 if (!FRAME_WINDOW_P (it->f))
2143 {
2144 if (it->truncate_lines_p)
2145 {
2146 /* We will need the truncation glyph. */
2147 xassert (it->glyph_row == NULL);
2148 produce_special_glyphs (it, IT_TRUNCATION);
2149 it->truncation_pixel_width = it->pixel_width;
2150 }
2151 else
2152 {
2153 /* We will need the continuation glyph. */
2154 xassert (it->glyph_row == NULL);
2155 produce_special_glyphs (it, IT_CONTINUATION);
2156 it->continuation_pixel_width = it->pixel_width;
2157 }
2158
2159 /* Reset these values to zero because the produce_special_glyphs
2160 above has changed them. */
2161 it->pixel_width = it->ascent = it->descent = 0;
2162 it->phys_ascent = it->phys_descent = 0;
2163 }
2164
2165 /* Set this after getting the dimensions of truncation and
2166 continuation glyphs, so that we don't produce glyphs when calling
2167 produce_special_glyphs, above. */
2168 it->glyph_row = row;
2169 it->area = TEXT_AREA;
2170
2171 /* Get the dimensions of the display area. The display area
2172 consists of the visible window area plus a horizontally scrolled
2173 part to the left of the window. All x-values are relative to the
2174 start of this total display area. */
2175 if (base_face_id != DEFAULT_FACE_ID)
2176 {
2177 /* Mode lines, menu bar in terminal frames. */
2178 it->first_visible_x = 0;
2179 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2180 }
2181 else
2182 {
2183 it->first_visible_x
2184 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2185 it->last_visible_x = (it->first_visible_x
2186 + window_box_width (w, TEXT_AREA));
2187
2188 /* If we truncate lines, leave room for the truncator glyph(s) at
2189 the right margin. Otherwise, leave room for the continuation
2190 glyph(s). Truncation and continuation glyphs are not inserted
2191 for window-based redisplay. */
2192 if (!FRAME_WINDOW_P (it->f))
2193 {
2194 if (it->truncate_lines_p)
2195 it->last_visible_x -= it->truncation_pixel_width;
2196 else
2197 it->last_visible_x -= it->continuation_pixel_width;
2198 }
2199
2200 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2201 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2202 }
2203
2204 /* Leave room for a border glyph. */
2205 if (!FRAME_WINDOW_P (it->f)
2206 && !WINDOW_RIGHTMOST_P (it->w))
2207 it->last_visible_x -= 1;
2208
2209 it->last_visible_y = window_text_bottom_y (w);
2210
2211 /* For mode lines and alike, arrange for the first glyph having a
2212 left box line if the face specifies a box. */
2213 if (base_face_id != DEFAULT_FACE_ID)
2214 {
2215 struct face *face;
2216
2217 it->face_id = base_face_id;
2218
2219 /* If we have a boxed mode line, make the first character appear
2220 with a left box line. */
2221 face = FACE_FROM_ID (it->f, base_face_id);
2222 if (face->box != FACE_NO_BOX)
2223 it->start_of_box_run_p = 1;
2224 }
2225
2226 /* If a buffer position was specified, set the iterator there,
2227 getting overlays and face properties from that position. */
2228 if (charpos >= BUF_BEG (current_buffer))
2229 {
2230 it->end_charpos = ZV;
2231 it->face_id = -1;
2232 IT_CHARPOS (*it) = charpos;
2233
2234 /* Compute byte position if not specified. */
2235 if (bytepos < charpos)
2236 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2237 else
2238 IT_BYTEPOS (*it) = bytepos;
2239
2240 it->start = it->current;
2241
2242 /* Compute faces etc. */
2243 reseat (it, it->current.pos, 1);
2244 }
2245
2246 CHECK_IT (it);
2247 }
2248
2249
2250 /* Initialize IT for the display of window W with window start POS. */
2251
2252 void
2253 start_display (it, w, pos)
2254 struct it *it;
2255 struct window *w;
2256 struct text_pos pos;
2257 {
2258 struct glyph_row *row;
2259 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2260
2261 row = w->desired_matrix->rows + first_vpos;
2262 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2263 it->first_vpos = first_vpos;
2264
2265 if (!it->truncate_lines_p)
2266 {
2267 int start_at_line_beg_p;
2268 int first_y = it->current_y;
2269
2270 /* If window start is not at a line start, skip forward to POS to
2271 get the correct continuation lines width. */
2272 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2273 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2274 if (!start_at_line_beg_p)
2275 {
2276 int new_x;
2277
2278 reseat_at_previous_visible_line_start (it);
2279 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2280
2281 new_x = it->current_x + it->pixel_width;
2282
2283 /* If lines are continued, this line may end in the middle
2284 of a multi-glyph character (e.g. a control character
2285 displayed as \003, or in the middle of an overlay
2286 string). In this case move_it_to above will not have
2287 taken us to the start of the continuation line but to the
2288 end of the continued line. */
2289 if (it->current_x > 0
2290 && !it->truncate_lines_p /* Lines are continued. */
2291 && (/* And glyph doesn't fit on the line. */
2292 new_x > it->last_visible_x
2293 /* Or it fits exactly and we're on a window
2294 system frame. */
2295 || (new_x == it->last_visible_x
2296 && FRAME_WINDOW_P (it->f))))
2297 {
2298 if (it->current.dpvec_index >= 0
2299 || it->current.overlay_string_index >= 0)
2300 {
2301 set_iterator_to_next (it, 1);
2302 move_it_in_display_line_to (it, -1, -1, 0);
2303 }
2304
2305 it->continuation_lines_width += it->current_x;
2306 }
2307
2308 /* We're starting a new display line, not affected by the
2309 height of the continued line, so clear the appropriate
2310 fields in the iterator structure. */
2311 it->max_ascent = it->max_descent = 0;
2312 it->max_phys_ascent = it->max_phys_descent = 0;
2313
2314 it->current_y = first_y;
2315 it->vpos = 0;
2316 it->current_x = it->hpos = 0;
2317 }
2318 }
2319
2320 #if 0 /* Don't assert the following because start_display is sometimes
2321 called intentionally with a window start that is not at a
2322 line start. Please leave this code in as a comment. */
2323
2324 /* Window start should be on a line start, now. */
2325 xassert (it->continuation_lines_width
2326 || IT_CHARPOS (it) == BEGV
2327 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2328 #endif /* 0 */
2329 }
2330
2331
2332 /* Return 1 if POS is a position in ellipses displayed for invisible
2333 text. W is the window we display, for text property lookup. */
2334
2335 static int
2336 in_ellipses_for_invisible_text_p (pos, w)
2337 struct display_pos *pos;
2338 struct window *w;
2339 {
2340 Lisp_Object prop, window;
2341 int ellipses_p = 0;
2342 int charpos = CHARPOS (pos->pos);
2343
2344 /* If POS specifies a position in a display vector, this might
2345 be for an ellipsis displayed for invisible text. We won't
2346 get the iterator set up for delivering that ellipsis unless
2347 we make sure that it gets aware of the invisible text. */
2348 if (pos->dpvec_index >= 0
2349 && pos->overlay_string_index < 0
2350 && CHARPOS (pos->string_pos) < 0
2351 && charpos > BEGV
2352 && (XSETWINDOW (window, w),
2353 prop = Fget_char_property (make_number (charpos),
2354 Qinvisible, window),
2355 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2356 {
2357 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2358 window);
2359 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2360 }
2361
2362 return ellipses_p;
2363 }
2364
2365
2366 /* Initialize IT for stepping through current_buffer in window W,
2367 starting at position POS that includes overlay string and display
2368 vector/ control character translation position information. Value
2369 is zero if there are overlay strings with newlines at POS. */
2370
2371 static int
2372 init_from_display_pos (it, w, pos)
2373 struct it *it;
2374 struct window *w;
2375 struct display_pos *pos;
2376 {
2377 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2378 int i, overlay_strings_with_newlines = 0;
2379
2380 /* If POS specifies a position in a display vector, this might
2381 be for an ellipsis displayed for invisible text. We won't
2382 get the iterator set up for delivering that ellipsis unless
2383 we make sure that it gets aware of the invisible text. */
2384 if (in_ellipses_for_invisible_text_p (pos, w))
2385 {
2386 --charpos;
2387 bytepos = 0;
2388 }
2389
2390 /* Keep in mind: the call to reseat in init_iterator skips invisible
2391 text, so we might end up at a position different from POS. This
2392 is only a problem when POS is a row start after a newline and an
2393 overlay starts there with an after-string, and the overlay has an
2394 invisible property. Since we don't skip invisible text in
2395 display_line and elsewhere immediately after consuming the
2396 newline before the row start, such a POS will not be in a string,
2397 but the call to init_iterator below will move us to the
2398 after-string. */
2399 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2400
2401 for (i = 0; i < it->n_overlay_strings; ++i)
2402 {
2403 const char *s = SDATA (it->overlay_strings[i]);
2404 const char *e = s + SBYTES (it->overlay_strings[i]);
2405
2406 while (s < e && *s != '\n')
2407 ++s;
2408
2409 if (s < e)
2410 {
2411 overlay_strings_with_newlines = 1;
2412 break;
2413 }
2414 }
2415
2416 /* If position is within an overlay string, set up IT to the right
2417 overlay string. */
2418 if (pos->overlay_string_index >= 0)
2419 {
2420 int relative_index;
2421
2422 /* If the first overlay string happens to have a `display'
2423 property for an image, the iterator will be set up for that
2424 image, and we have to undo that setup first before we can
2425 correct the overlay string index. */
2426 if (it->method == next_element_from_image)
2427 pop_it (it);
2428
2429 /* We already have the first chunk of overlay strings in
2430 IT->overlay_strings. Load more until the one for
2431 pos->overlay_string_index is in IT->overlay_strings. */
2432 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2433 {
2434 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2435 it->current.overlay_string_index = 0;
2436 while (n--)
2437 {
2438 load_overlay_strings (it, 0);
2439 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2440 }
2441 }
2442
2443 it->current.overlay_string_index = pos->overlay_string_index;
2444 relative_index = (it->current.overlay_string_index
2445 % OVERLAY_STRING_CHUNK_SIZE);
2446 it->string = it->overlay_strings[relative_index];
2447 xassert (STRINGP (it->string));
2448 it->current.string_pos = pos->string_pos;
2449 it->method = next_element_from_string;
2450 }
2451
2452 #if 0 /* This is bogus because POS not having an overlay string
2453 position does not mean it's after the string. Example: A
2454 line starting with a before-string and initialization of IT
2455 to the previous row's end position. */
2456 else if (it->current.overlay_string_index >= 0)
2457 {
2458 /* If POS says we're already after an overlay string ending at
2459 POS, make sure to pop the iterator because it will be in
2460 front of that overlay string. When POS is ZV, we've thereby
2461 also ``processed'' overlay strings at ZV. */
2462 while (it->sp)
2463 pop_it (it);
2464 it->current.overlay_string_index = -1;
2465 it->method = next_element_from_buffer;
2466 if (CHARPOS (pos->pos) == ZV)
2467 it->overlay_strings_at_end_processed_p = 1;
2468 }
2469 #endif /* 0 */
2470
2471 if (CHARPOS (pos->string_pos) >= 0)
2472 {
2473 /* Recorded position is not in an overlay string, but in another
2474 string. This can only be a string from a `display' property.
2475 IT should already be filled with that string. */
2476 it->current.string_pos = pos->string_pos;
2477 xassert (STRINGP (it->string));
2478 }
2479
2480 /* Restore position in display vector translations, control
2481 character translations or ellipses. */
2482 if (pos->dpvec_index >= 0)
2483 {
2484 if (it->dpvec == NULL)
2485 get_next_display_element (it);
2486 xassert (it->dpvec && it->current.dpvec_index == 0);
2487 it->current.dpvec_index = pos->dpvec_index;
2488 }
2489
2490 CHECK_IT (it);
2491 return !overlay_strings_with_newlines;
2492 }
2493
2494
2495 /* Initialize IT for stepping through current_buffer in window W
2496 starting at ROW->start. */
2497
2498 static void
2499 init_to_row_start (it, w, row)
2500 struct it *it;
2501 struct window *w;
2502 struct glyph_row *row;
2503 {
2504 init_from_display_pos (it, w, &row->start);
2505 it->start = row->start;
2506 it->continuation_lines_width = row->continuation_lines_width;
2507 CHECK_IT (it);
2508 }
2509
2510
2511 /* Initialize IT for stepping through current_buffer in window W
2512 starting in the line following ROW, i.e. starting at ROW->end.
2513 Value is zero if there are overlay strings with newlines at ROW's
2514 end position. */
2515
2516 static int
2517 init_to_row_end (it, w, row)
2518 struct it *it;
2519 struct window *w;
2520 struct glyph_row *row;
2521 {
2522 int success = 0;
2523
2524 if (init_from_display_pos (it, w, &row->end))
2525 {
2526 if (row->continued_p)
2527 it->continuation_lines_width
2528 = row->continuation_lines_width + row->pixel_width;
2529 CHECK_IT (it);
2530 success = 1;
2531 }
2532
2533 return success;
2534 }
2535
2536
2537
2538 \f
2539 /***********************************************************************
2540 Text properties
2541 ***********************************************************************/
2542
2543 /* Called when IT reaches IT->stop_charpos. Handle text property and
2544 overlay changes. Set IT->stop_charpos to the next position where
2545 to stop. */
2546
2547 static void
2548 handle_stop (it)
2549 struct it *it;
2550 {
2551 enum prop_handled handled;
2552 int handle_overlay_change_p = 1;
2553 struct props *p;
2554
2555 it->dpvec = NULL;
2556 it->current.dpvec_index = -1;
2557
2558 do
2559 {
2560 handled = HANDLED_NORMALLY;
2561
2562 /* Call text property handlers. */
2563 for (p = it_props; p->handler; ++p)
2564 {
2565 handled = p->handler (it);
2566
2567 if (handled == HANDLED_RECOMPUTE_PROPS)
2568 break;
2569 else if (handled == HANDLED_RETURN)
2570 return;
2571 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2572 handle_overlay_change_p = 0;
2573 }
2574
2575 if (handled != HANDLED_RECOMPUTE_PROPS)
2576 {
2577 /* Don't check for overlay strings below when set to deliver
2578 characters from a display vector. */
2579 if (it->method == next_element_from_display_vector)
2580 handle_overlay_change_p = 0;
2581
2582 /* Handle overlay changes. */
2583 if (handle_overlay_change_p)
2584 handled = handle_overlay_change (it);
2585
2586 /* Determine where to stop next. */
2587 if (handled == HANDLED_NORMALLY)
2588 compute_stop_pos (it);
2589 }
2590 }
2591 while (handled == HANDLED_RECOMPUTE_PROPS);
2592 }
2593
2594
2595 /* Compute IT->stop_charpos from text property and overlay change
2596 information for IT's current position. */
2597
2598 static void
2599 compute_stop_pos (it)
2600 struct it *it;
2601 {
2602 register INTERVAL iv, next_iv;
2603 Lisp_Object object, limit, position;
2604
2605 /* If nowhere else, stop at the end. */
2606 it->stop_charpos = it->end_charpos;
2607
2608 if (STRINGP (it->string))
2609 {
2610 /* Strings are usually short, so don't limit the search for
2611 properties. */
2612 object = it->string;
2613 limit = Qnil;
2614 position = make_number (IT_STRING_CHARPOS (*it));
2615 }
2616 else
2617 {
2618 int charpos;
2619
2620 /* If next overlay change is in front of the current stop pos
2621 (which is IT->end_charpos), stop there. Note: value of
2622 next_overlay_change is point-max if no overlay change
2623 follows. */
2624 charpos = next_overlay_change (IT_CHARPOS (*it));
2625 if (charpos < it->stop_charpos)
2626 it->stop_charpos = charpos;
2627
2628 /* If showing the region, we have to stop at the region
2629 start or end because the face might change there. */
2630 if (it->region_beg_charpos > 0)
2631 {
2632 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2633 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2634 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2635 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2636 }
2637
2638 /* Set up variables for computing the stop position from text
2639 property changes. */
2640 XSETBUFFER (object, current_buffer);
2641 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2642 position = make_number (IT_CHARPOS (*it));
2643
2644 }
2645
2646 /* Get the interval containing IT's position. Value is a null
2647 interval if there isn't such an interval. */
2648 iv = validate_interval_range (object, &position, &position, 0);
2649 if (!NULL_INTERVAL_P (iv))
2650 {
2651 Lisp_Object values_here[LAST_PROP_IDX];
2652 struct props *p;
2653
2654 /* Get properties here. */
2655 for (p = it_props; p->handler; ++p)
2656 values_here[p->idx] = textget (iv->plist, *p->name);
2657
2658 /* Look for an interval following iv that has different
2659 properties. */
2660 for (next_iv = next_interval (iv);
2661 (!NULL_INTERVAL_P (next_iv)
2662 && (NILP (limit)
2663 || XFASTINT (limit) > next_iv->position));
2664 next_iv = next_interval (next_iv))
2665 {
2666 for (p = it_props; p->handler; ++p)
2667 {
2668 Lisp_Object new_value;
2669
2670 new_value = textget (next_iv->plist, *p->name);
2671 if (!EQ (values_here[p->idx], new_value))
2672 break;
2673 }
2674
2675 if (p->handler)
2676 break;
2677 }
2678
2679 if (!NULL_INTERVAL_P (next_iv))
2680 {
2681 if (INTEGERP (limit)
2682 && next_iv->position >= XFASTINT (limit))
2683 /* No text property change up to limit. */
2684 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2685 else
2686 /* Text properties change in next_iv. */
2687 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2688 }
2689 }
2690
2691 xassert (STRINGP (it->string)
2692 || (it->stop_charpos >= BEGV
2693 && it->stop_charpos >= IT_CHARPOS (*it)));
2694 }
2695
2696
2697 /* Return the position of the next overlay change after POS in
2698 current_buffer. Value is point-max if no overlay change
2699 follows. This is like `next-overlay-change' but doesn't use
2700 xmalloc. */
2701
2702 static int
2703 next_overlay_change (pos)
2704 int pos;
2705 {
2706 int noverlays;
2707 int endpos;
2708 Lisp_Object *overlays;
2709 int len;
2710 int i;
2711
2712 /* Get all overlays at the given position. */
2713 len = 10;
2714 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2715 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2716 if (noverlays > len)
2717 {
2718 len = noverlays;
2719 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2720 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2721 }
2722
2723 /* If any of these overlays ends before endpos,
2724 use its ending point instead. */
2725 for (i = 0; i < noverlays; ++i)
2726 {
2727 Lisp_Object oend;
2728 int oendpos;
2729
2730 oend = OVERLAY_END (overlays[i]);
2731 oendpos = OVERLAY_POSITION (oend);
2732 endpos = min (endpos, oendpos);
2733 }
2734
2735 return endpos;
2736 }
2737
2738
2739 \f
2740 /***********************************************************************
2741 Fontification
2742 ***********************************************************************/
2743
2744 /* Handle changes in the `fontified' property of the current buffer by
2745 calling hook functions from Qfontification_functions to fontify
2746 regions of text. */
2747
2748 static enum prop_handled
2749 handle_fontified_prop (it)
2750 struct it *it;
2751 {
2752 Lisp_Object prop, pos;
2753 enum prop_handled handled = HANDLED_NORMALLY;
2754
2755 /* Get the value of the `fontified' property at IT's current buffer
2756 position. (The `fontified' property doesn't have a special
2757 meaning in strings.) If the value is nil, call functions from
2758 Qfontification_functions. */
2759 if (!STRINGP (it->string)
2760 && it->s == NULL
2761 && !NILP (Vfontification_functions)
2762 && !NILP (Vrun_hooks)
2763 && (pos = make_number (IT_CHARPOS (*it)),
2764 prop = Fget_char_property (pos, Qfontified, Qnil),
2765 NILP (prop)))
2766 {
2767 int count = SPECPDL_INDEX ();
2768 Lisp_Object val;
2769
2770 val = Vfontification_functions;
2771 specbind (Qfontification_functions, Qnil);
2772
2773 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2774 safe_call1 (val, pos);
2775 else
2776 {
2777 Lisp_Object globals, fn;
2778 struct gcpro gcpro1, gcpro2;
2779
2780 globals = Qnil;
2781 GCPRO2 (val, globals);
2782
2783 for (; CONSP (val); val = XCDR (val))
2784 {
2785 fn = XCAR (val);
2786
2787 if (EQ (fn, Qt))
2788 {
2789 /* A value of t indicates this hook has a local
2790 binding; it means to run the global binding too.
2791 In a global value, t should not occur. If it
2792 does, we must ignore it to avoid an endless
2793 loop. */
2794 for (globals = Fdefault_value (Qfontification_functions);
2795 CONSP (globals);
2796 globals = XCDR (globals))
2797 {
2798 fn = XCAR (globals);
2799 if (!EQ (fn, Qt))
2800 safe_call1 (fn, pos);
2801 }
2802 }
2803 else
2804 safe_call1 (fn, pos);
2805 }
2806
2807 UNGCPRO;
2808 }
2809
2810 unbind_to (count, Qnil);
2811
2812 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2813 something. This avoids an endless loop if they failed to
2814 fontify the text for which reason ever. */
2815 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2816 handled = HANDLED_RECOMPUTE_PROPS;
2817 }
2818
2819 return handled;
2820 }
2821
2822
2823 \f
2824 /***********************************************************************
2825 Faces
2826 ***********************************************************************/
2827
2828 /* Set up iterator IT from face properties at its current position.
2829 Called from handle_stop. */
2830
2831 static enum prop_handled
2832 handle_face_prop (it)
2833 struct it *it;
2834 {
2835 int new_face_id, next_stop;
2836
2837 if (!STRINGP (it->string))
2838 {
2839 new_face_id
2840 = face_at_buffer_position (it->w,
2841 IT_CHARPOS (*it),
2842 it->region_beg_charpos,
2843 it->region_end_charpos,
2844 &next_stop,
2845 (IT_CHARPOS (*it)
2846 + TEXT_PROP_DISTANCE_LIMIT),
2847 0);
2848
2849 /* Is this a start of a run of characters with box face?
2850 Caveat: this can be called for a freshly initialized
2851 iterator; face_id is -1 in this case. We know that the new
2852 face will not change until limit, i.e. if the new face has a
2853 box, all characters up to limit will have one. But, as
2854 usual, we don't know whether limit is really the end. */
2855 if (new_face_id != it->face_id)
2856 {
2857 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2858
2859 /* If new face has a box but old face has not, this is
2860 the start of a run of characters with box, i.e. it has
2861 a shadow on the left side. The value of face_id of the
2862 iterator will be -1 if this is the initial call that gets
2863 the face. In this case, we have to look in front of IT's
2864 position and see whether there is a face != new_face_id. */
2865 it->start_of_box_run_p
2866 = (new_face->box != FACE_NO_BOX
2867 && (it->face_id >= 0
2868 || IT_CHARPOS (*it) == BEG
2869 || new_face_id != face_before_it_pos (it)));
2870 it->face_box_p = new_face->box != FACE_NO_BOX;
2871 }
2872 }
2873 else
2874 {
2875 int base_face_id, bufpos;
2876
2877 if (it->current.overlay_string_index >= 0)
2878 bufpos = IT_CHARPOS (*it);
2879 else
2880 bufpos = 0;
2881
2882 /* For strings from a buffer, i.e. overlay strings or strings
2883 from a `display' property, use the face at IT's current
2884 buffer position as the base face to merge with, so that
2885 overlay strings appear in the same face as surrounding
2886 text, unless they specify their own faces. */
2887 base_face_id = underlying_face_id (it);
2888
2889 new_face_id = face_at_string_position (it->w,
2890 it->string,
2891 IT_STRING_CHARPOS (*it),
2892 bufpos,
2893 it->region_beg_charpos,
2894 it->region_end_charpos,
2895 &next_stop,
2896 base_face_id, 0);
2897
2898 #if 0 /* This shouldn't be neccessary. Let's check it. */
2899 /* If IT is used to display a mode line we would really like to
2900 use the mode line face instead of the frame's default face. */
2901 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2902 && new_face_id == DEFAULT_FACE_ID)
2903 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2904 #endif
2905
2906 /* Is this a start of a run of characters with box? Caveat:
2907 this can be called for a freshly allocated iterator; face_id
2908 is -1 is this case. We know that the new face will not
2909 change until the next check pos, i.e. if the new face has a
2910 box, all characters up to that position will have a
2911 box. But, as usual, we don't know whether that position
2912 is really the end. */
2913 if (new_face_id != it->face_id)
2914 {
2915 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2916 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2917
2918 /* If new face has a box but old face hasn't, this is the
2919 start of a run of characters with box, i.e. it has a
2920 shadow on the left side. */
2921 it->start_of_box_run_p
2922 = new_face->box && (old_face == NULL || !old_face->box);
2923 it->face_box_p = new_face->box != FACE_NO_BOX;
2924 }
2925 }
2926
2927 it->face_id = new_face_id;
2928 return HANDLED_NORMALLY;
2929 }
2930
2931
2932 /* Return the ID of the face ``underlying'' IT's current position,
2933 which is in a string. If the iterator is associated with a
2934 buffer, return the face at IT's current buffer position.
2935 Otherwise, use the iterator's base_face_id. */
2936
2937 static int
2938 underlying_face_id (it)
2939 struct it *it;
2940 {
2941 int face_id = it->base_face_id, i;
2942
2943 xassert (STRINGP (it->string));
2944
2945 for (i = it->sp - 1; i >= 0; --i)
2946 if (NILP (it->stack[i].string))
2947 face_id = it->stack[i].face_id;
2948
2949 return face_id;
2950 }
2951
2952
2953 /* Compute the face one character before or after the current position
2954 of IT. BEFORE_P non-zero means get the face in front of IT's
2955 position. Value is the id of the face. */
2956
2957 static int
2958 face_before_or_after_it_pos (it, before_p)
2959 struct it *it;
2960 int before_p;
2961 {
2962 int face_id, limit;
2963 int next_check_charpos;
2964 struct text_pos pos;
2965
2966 xassert (it->s == NULL);
2967
2968 if (STRINGP (it->string))
2969 {
2970 int bufpos, base_face_id;
2971
2972 /* No face change past the end of the string (for the case
2973 we are padding with spaces). No face change before the
2974 string start. */
2975 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2976 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2977 return it->face_id;
2978
2979 /* Set pos to the position before or after IT's current position. */
2980 if (before_p)
2981 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2982 else
2983 /* For composition, we must check the character after the
2984 composition. */
2985 pos = (it->what == IT_COMPOSITION
2986 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2987 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2988
2989 if (it->current.overlay_string_index >= 0)
2990 bufpos = IT_CHARPOS (*it);
2991 else
2992 bufpos = 0;
2993
2994 base_face_id = underlying_face_id (it);
2995
2996 /* Get the face for ASCII, or unibyte. */
2997 face_id = face_at_string_position (it->w,
2998 it->string,
2999 CHARPOS (pos),
3000 bufpos,
3001 it->region_beg_charpos,
3002 it->region_end_charpos,
3003 &next_check_charpos,
3004 base_face_id, 0);
3005
3006 /* Correct the face for charsets different from ASCII. Do it
3007 for the multibyte case only. The face returned above is
3008 suitable for unibyte text if IT->string is unibyte. */
3009 if (STRING_MULTIBYTE (it->string))
3010 {
3011 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3012 int rest = SBYTES (it->string) - BYTEPOS (pos);
3013 int c, len;
3014 struct face *face = FACE_FROM_ID (it->f, face_id);
3015
3016 c = string_char_and_length (p, rest, &len);
3017 face_id = FACE_FOR_CHAR (it->f, face, c);
3018 }
3019 }
3020 else
3021 {
3022 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3023 || (IT_CHARPOS (*it) <= BEGV && before_p))
3024 return it->face_id;
3025
3026 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3027 pos = it->current.pos;
3028
3029 if (before_p)
3030 DEC_TEXT_POS (pos, it->multibyte_p);
3031 else
3032 {
3033 if (it->what == IT_COMPOSITION)
3034 /* For composition, we must check the position after the
3035 composition. */
3036 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3037 else
3038 INC_TEXT_POS (pos, it->multibyte_p);
3039 }
3040
3041 /* Determine face for CHARSET_ASCII, or unibyte. */
3042 face_id = face_at_buffer_position (it->w,
3043 CHARPOS (pos),
3044 it->region_beg_charpos,
3045 it->region_end_charpos,
3046 &next_check_charpos,
3047 limit, 0);
3048
3049 /* Correct the face for charsets different from ASCII. Do it
3050 for the multibyte case only. The face returned above is
3051 suitable for unibyte text if current_buffer is unibyte. */
3052 if (it->multibyte_p)
3053 {
3054 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3055 struct face *face = FACE_FROM_ID (it->f, face_id);
3056 face_id = FACE_FOR_CHAR (it->f, face, c);
3057 }
3058 }
3059
3060 return face_id;
3061 }
3062
3063
3064 \f
3065 /***********************************************************************
3066 Invisible text
3067 ***********************************************************************/
3068
3069 /* Set up iterator IT from invisible properties at its current
3070 position. Called from handle_stop. */
3071
3072 static enum prop_handled
3073 handle_invisible_prop (it)
3074 struct it *it;
3075 {
3076 enum prop_handled handled = HANDLED_NORMALLY;
3077
3078 if (STRINGP (it->string))
3079 {
3080 extern Lisp_Object Qinvisible;
3081 Lisp_Object prop, end_charpos, limit, charpos;
3082
3083 /* Get the value of the invisible text property at the
3084 current position. Value will be nil if there is no such
3085 property. */
3086 charpos = make_number (IT_STRING_CHARPOS (*it));
3087 prop = Fget_text_property (charpos, Qinvisible, it->string);
3088
3089 if (!NILP (prop)
3090 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3091 {
3092 handled = HANDLED_RECOMPUTE_PROPS;
3093
3094 /* Get the position at which the next change of the
3095 invisible text property can be found in IT->string.
3096 Value will be nil if the property value is the same for
3097 all the rest of IT->string. */
3098 XSETINT (limit, SCHARS (it->string));
3099 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3100 it->string, limit);
3101
3102 /* Text at current position is invisible. The next
3103 change in the property is at position end_charpos.
3104 Move IT's current position to that position. */
3105 if (INTEGERP (end_charpos)
3106 && XFASTINT (end_charpos) < XFASTINT (limit))
3107 {
3108 struct text_pos old;
3109 old = it->current.string_pos;
3110 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3111 compute_string_pos (&it->current.string_pos, old, it->string);
3112 }
3113 else
3114 {
3115 /* The rest of the string is invisible. If this is an
3116 overlay string, proceed with the next overlay string
3117 or whatever comes and return a character from there. */
3118 if (it->current.overlay_string_index >= 0)
3119 {
3120 next_overlay_string (it);
3121 /* Don't check for overlay strings when we just
3122 finished processing them. */
3123 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3124 }
3125 else
3126 {
3127 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3128 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3129 }
3130 }
3131 }
3132 }
3133 else
3134 {
3135 int invis_p, newpos, next_stop, start_charpos;
3136 Lisp_Object pos, prop, overlay;
3137
3138 /* First of all, is there invisible text at this position? */
3139 start_charpos = IT_CHARPOS (*it);
3140 pos = make_number (IT_CHARPOS (*it));
3141 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3142 &overlay);
3143 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3144
3145 /* If we are on invisible text, skip over it. */
3146 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3147 {
3148 /* Record whether we have to display an ellipsis for the
3149 invisible text. */
3150 int display_ellipsis_p = invis_p == 2;
3151
3152 handled = HANDLED_RECOMPUTE_PROPS;
3153
3154 /* Loop skipping over invisible text. The loop is left at
3155 ZV or with IT on the first char being visible again. */
3156 do
3157 {
3158 /* Try to skip some invisible text. Return value is the
3159 position reached which can be equal to IT's position
3160 if there is nothing invisible here. This skips both
3161 over invisible text properties and overlays with
3162 invisible property. */
3163 newpos = skip_invisible (IT_CHARPOS (*it),
3164 &next_stop, ZV, it->window);
3165
3166 /* If we skipped nothing at all we weren't at invisible
3167 text in the first place. If everything to the end of
3168 the buffer was skipped, end the loop. */
3169 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3170 invis_p = 0;
3171 else
3172 {
3173 /* We skipped some characters but not necessarily
3174 all there are. Check if we ended up on visible
3175 text. Fget_char_property returns the property of
3176 the char before the given position, i.e. if we
3177 get invis_p = 0, this means that the char at
3178 newpos is visible. */
3179 pos = make_number (newpos);
3180 prop = Fget_char_property (pos, Qinvisible, it->window);
3181 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3182 }
3183
3184 /* If we ended up on invisible text, proceed to
3185 skip starting with next_stop. */
3186 if (invis_p)
3187 IT_CHARPOS (*it) = next_stop;
3188 }
3189 while (invis_p);
3190
3191 /* The position newpos is now either ZV or on visible text. */
3192 IT_CHARPOS (*it) = newpos;
3193 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3194
3195 /* If there are before-strings at the start of invisible
3196 text, and the text is invisible because of a text
3197 property, arrange to show before-strings because 20.x did
3198 it that way. (If the text is invisible because of an
3199 overlay property instead of a text property, this is
3200 already handled in the overlay code.) */
3201 if (NILP (overlay)
3202 && get_overlay_strings (it, start_charpos))
3203 {
3204 handled = HANDLED_RECOMPUTE_PROPS;
3205 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3206 }
3207 else if (display_ellipsis_p)
3208 setup_for_ellipsis (it);
3209 }
3210 }
3211
3212 return handled;
3213 }
3214
3215
3216 /* Make iterator IT return `...' next. */
3217
3218 static void
3219 setup_for_ellipsis (it)
3220 struct it *it;
3221 {
3222 if (it->dp
3223 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3224 {
3225 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3226 it->dpvec = v->contents;
3227 it->dpend = v->contents + v->size;
3228 }
3229 else
3230 {
3231 /* Default `...'. */
3232 it->dpvec = default_invis_vector;
3233 it->dpend = default_invis_vector + 3;
3234 }
3235
3236 /* The ellipsis display does not replace the display of the
3237 character at the new position. Indicate this by setting
3238 IT->dpvec_char_len to zero. */
3239 it->dpvec_char_len = 0;
3240
3241 it->current.dpvec_index = 0;
3242 it->method = next_element_from_display_vector;
3243 }
3244
3245
3246 \f
3247 /***********************************************************************
3248 'display' property
3249 ***********************************************************************/
3250
3251 /* Set up iterator IT from `display' property at its current position.
3252 Called from handle_stop. */
3253
3254 static enum prop_handled
3255 handle_display_prop (it)
3256 struct it *it;
3257 {
3258 Lisp_Object prop, object;
3259 struct text_pos *position;
3260 int display_replaced_p = 0;
3261
3262 if (STRINGP (it->string))
3263 {
3264 object = it->string;
3265 position = &it->current.string_pos;
3266 }
3267 else
3268 {
3269 object = it->w->buffer;
3270 position = &it->current.pos;
3271 }
3272
3273 /* Reset those iterator values set from display property values. */
3274 it->font_height = Qnil;
3275 it->space_width = Qnil;
3276 it->voffset = 0;
3277
3278 /* We don't support recursive `display' properties, i.e. string
3279 values that have a string `display' property, that have a string
3280 `display' property etc. */
3281 if (!it->string_from_display_prop_p)
3282 it->area = TEXT_AREA;
3283
3284 prop = Fget_char_property (make_number (position->charpos),
3285 Qdisplay, object);
3286 if (NILP (prop))
3287 return HANDLED_NORMALLY;
3288
3289 if (CONSP (prop)
3290 /* Simple properties. */
3291 && !EQ (XCAR (prop), Qimage)
3292 && !EQ (XCAR (prop), Qspace)
3293 && !EQ (XCAR (prop), Qwhen)
3294 && !EQ (XCAR (prop), Qspace_width)
3295 && !EQ (XCAR (prop), Qheight)
3296 && !EQ (XCAR (prop), Qraise)
3297 /* Marginal area specifications. */
3298 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3299 && !EQ (XCAR (prop), Qleft_fringe)
3300 && !EQ (XCAR (prop), Qright_fringe)
3301 && !NILP (XCAR (prop)))
3302 {
3303 for (; CONSP (prop); prop = XCDR (prop))
3304 {
3305 if (handle_single_display_prop (it, XCAR (prop), object,
3306 position, display_replaced_p))
3307 display_replaced_p = 1;
3308 }
3309 }
3310 else if (VECTORP (prop))
3311 {
3312 int i;
3313 for (i = 0; i < ASIZE (prop); ++i)
3314 if (handle_single_display_prop (it, AREF (prop, i), object,
3315 position, display_replaced_p))
3316 display_replaced_p = 1;
3317 }
3318 else
3319 {
3320 if (handle_single_display_prop (it, prop, object, position, 0))
3321 display_replaced_p = 1;
3322 }
3323
3324 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3325 }
3326
3327
3328 /* Value is the position of the end of the `display' property starting
3329 at START_POS in OBJECT. */
3330
3331 static struct text_pos
3332 display_prop_end (it, object, start_pos)
3333 struct it *it;
3334 Lisp_Object object;
3335 struct text_pos start_pos;
3336 {
3337 Lisp_Object end;
3338 struct text_pos end_pos;
3339
3340 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3341 Qdisplay, object, Qnil);
3342 CHARPOS (end_pos) = XFASTINT (end);
3343 if (STRINGP (object))
3344 compute_string_pos (&end_pos, start_pos, it->string);
3345 else
3346 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3347
3348 return end_pos;
3349 }
3350
3351
3352 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3353 is the object in which the `display' property was found. *POSITION
3354 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3355 means that we previously saw a display sub-property which already
3356 replaced text display with something else, for example an image;
3357 ignore such properties after the first one has been processed.
3358
3359 If PROP is a `space' or `image' sub-property, set *POSITION to the
3360 end position of the `display' property.
3361
3362 Value is non-zero if something was found which replaces the display
3363 of buffer or string text. */
3364
3365 static int
3366 handle_single_display_prop (it, prop, object, position,
3367 display_replaced_before_p)
3368 struct it *it;
3369 Lisp_Object prop;
3370 Lisp_Object object;
3371 struct text_pos *position;
3372 int display_replaced_before_p;
3373 {
3374 Lisp_Object value;
3375 int replaces_text_display_p = 0;
3376 Lisp_Object form;
3377
3378 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3379 evaluated. If the result is nil, VALUE is ignored. */
3380 form = Qt;
3381 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3382 {
3383 prop = XCDR (prop);
3384 if (!CONSP (prop))
3385 return 0;
3386 form = XCAR (prop);
3387 prop = XCDR (prop);
3388 }
3389
3390 if (!NILP (form) && !EQ (form, Qt))
3391 {
3392 int count = SPECPDL_INDEX ();
3393 struct gcpro gcpro1;
3394
3395 /* Bind `object' to the object having the `display' property, a
3396 buffer or string. Bind `position' to the position in the
3397 object where the property was found, and `buffer-position'
3398 to the current position in the buffer. */
3399 specbind (Qobject, object);
3400 specbind (Qposition, make_number (CHARPOS (*position)));
3401 specbind (Qbuffer_position,
3402 make_number (STRINGP (object)
3403 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3404 GCPRO1 (form);
3405 form = safe_eval (form);
3406 UNGCPRO;
3407 unbind_to (count, Qnil);
3408 }
3409
3410 if (NILP (form))
3411 return 0;
3412
3413 if (CONSP (prop)
3414 && EQ (XCAR (prop), Qheight)
3415 && CONSP (XCDR (prop)))
3416 {
3417 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3418 return 0;
3419
3420 /* `(height HEIGHT)'. */
3421 it->font_height = XCAR (XCDR (prop));
3422 if (!NILP (it->font_height))
3423 {
3424 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3425 int new_height = -1;
3426
3427 if (CONSP (it->font_height)
3428 && (EQ (XCAR (it->font_height), Qplus)
3429 || EQ (XCAR (it->font_height), Qminus))
3430 && CONSP (XCDR (it->font_height))
3431 && INTEGERP (XCAR (XCDR (it->font_height))))
3432 {
3433 /* `(+ N)' or `(- N)' where N is an integer. */
3434 int steps = XINT (XCAR (XCDR (it->font_height)));
3435 if (EQ (XCAR (it->font_height), Qplus))
3436 steps = - steps;
3437 it->face_id = smaller_face (it->f, it->face_id, steps);
3438 }
3439 else if (FUNCTIONP (it->font_height))
3440 {
3441 /* Call function with current height as argument.
3442 Value is the new height. */
3443 Lisp_Object height;
3444 height = safe_call1 (it->font_height,
3445 face->lface[LFACE_HEIGHT_INDEX]);
3446 if (NUMBERP (height))
3447 new_height = XFLOATINT (height);
3448 }
3449 else if (NUMBERP (it->font_height))
3450 {
3451 /* Value is a multiple of the canonical char height. */
3452 struct face *face;
3453
3454 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3455 new_height = (XFLOATINT (it->font_height)
3456 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3457 }
3458 else
3459 {
3460 /* Evaluate IT->font_height with `height' bound to the
3461 current specified height to get the new height. */
3462 Lisp_Object value;
3463 int count = SPECPDL_INDEX ();
3464
3465 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3466 value = safe_eval (it->font_height);
3467 unbind_to (count, Qnil);
3468
3469 if (NUMBERP (value))
3470 new_height = XFLOATINT (value);
3471 }
3472
3473 if (new_height > 0)
3474 it->face_id = face_with_height (it->f, it->face_id, new_height);
3475 }
3476 }
3477 else if (CONSP (prop)
3478 && EQ (XCAR (prop), Qspace_width)
3479 && CONSP (XCDR (prop)))
3480 {
3481 /* `(space_width WIDTH)'. */
3482 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3483 return 0;
3484
3485 value = XCAR (XCDR (prop));
3486 if (NUMBERP (value) && XFLOATINT (value) > 0)
3487 it->space_width = value;
3488 }
3489 else if (CONSP (prop)
3490 && EQ (XCAR (prop), Qraise)
3491 && CONSP (XCDR (prop)))
3492 {
3493 /* `(raise FACTOR)'. */
3494 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3495 return 0;
3496
3497 #ifdef HAVE_WINDOW_SYSTEM
3498 value = XCAR (XCDR (prop));
3499 if (NUMBERP (value))
3500 {
3501 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3502 it->voffset = - (XFLOATINT (value)
3503 * (FONT_HEIGHT (face->font)));
3504 }
3505 #endif /* HAVE_WINDOW_SYSTEM */
3506 }
3507 else if (!it->string_from_display_prop_p)
3508 {
3509 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3510 VALUE) or `((margin nil) VALUE)' or VALUE. */
3511 Lisp_Object location, value;
3512 struct text_pos start_pos;
3513 int valid_p;
3514
3515 /* Characters having this form of property are not displayed, so
3516 we have to find the end of the property. */
3517 start_pos = *position;
3518 *position = display_prop_end (it, object, start_pos);
3519 value = Qnil;
3520
3521 /* Let's stop at the new position and assume that all
3522 text properties change there. */
3523 it->stop_charpos = position->charpos;
3524
3525 if (CONSP (prop)
3526 && (EQ (XCAR (prop), Qleft_fringe)
3527 || EQ (XCAR (prop), Qright_fringe))
3528 && CONSP (XCDR (prop)))
3529 {
3530 unsigned face_id = DEFAULT_FACE_ID;
3531
3532 /* Save current settings of IT so that we can restore them
3533 when we are finished with the glyph property value. */
3534
3535 /* `(left-fringe BITMAP FACE)'. */
3536 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3537 return 0;
3538
3539 #ifdef HAVE_WINDOW_SYSTEM
3540 value = XCAR (XCDR (prop));
3541 if (!NUMBERP (value)
3542 || !valid_fringe_bitmap_id_p (XINT (value)))
3543 return 0;
3544
3545 if (CONSP (XCDR (XCDR (prop))))
3546 {
3547 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3548
3549 face_id = lookup_named_face (it->f, face_name, 'A');
3550 if (face_id < 0)
3551 return 0;
3552 }
3553
3554 push_it (it);
3555
3556 it->area = TEXT_AREA;
3557 it->what = IT_IMAGE;
3558 it->image_id = -1; /* no image */
3559 it->position = start_pos;
3560 it->object = NILP (object) ? it->w->buffer : object;
3561 it->method = next_element_from_image;
3562 it->face_id = face_id;
3563
3564 /* Say that we haven't consumed the characters with
3565 `display' property yet. The call to pop_it in
3566 set_iterator_to_next will clean this up. */
3567 *position = start_pos;
3568
3569 if (EQ (XCAR (prop), Qleft_fringe))
3570 {
3571 it->left_user_fringe_bitmap = XINT (value);
3572 it->left_user_fringe_face_id = face_id;
3573 }
3574 else
3575 {
3576 it->right_user_fringe_bitmap = XINT (value);
3577 it->right_user_fringe_face_id = face_id;
3578 }
3579 #endif /* HAVE_WINDOW_SYSTEM */
3580 return 1;
3581 }
3582
3583 location = Qunbound;
3584 if (CONSP (prop) && CONSP (XCAR (prop)))
3585 {
3586 Lisp_Object tem;
3587
3588 value = XCDR (prop);
3589 if (CONSP (value))
3590 value = XCAR (value);
3591
3592 tem = XCAR (prop);
3593 if (EQ (XCAR (tem), Qmargin)
3594 && (tem = XCDR (tem),
3595 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3596 (NILP (tem)
3597 || EQ (tem, Qleft_margin)
3598 || EQ (tem, Qright_margin))))
3599 location = tem;
3600 }
3601
3602 if (EQ (location, Qunbound))
3603 {
3604 location = Qnil;
3605 value = prop;
3606 }
3607
3608 valid_p = (STRINGP (value)
3609 #ifdef HAVE_WINDOW_SYSTEM
3610 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3611 #endif /* not HAVE_WINDOW_SYSTEM */
3612 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3613
3614 if ((EQ (location, Qleft_margin)
3615 || EQ (location, Qright_margin)
3616 || NILP (location))
3617 && valid_p
3618 && !display_replaced_before_p)
3619 {
3620 replaces_text_display_p = 1;
3621
3622 /* Save current settings of IT so that we can restore them
3623 when we are finished with the glyph property value. */
3624 push_it (it);
3625
3626 if (NILP (location))
3627 it->area = TEXT_AREA;
3628 else if (EQ (location, Qleft_margin))
3629 it->area = LEFT_MARGIN_AREA;
3630 else
3631 it->area = RIGHT_MARGIN_AREA;
3632
3633 if (STRINGP (value))
3634 {
3635 it->string = value;
3636 it->multibyte_p = STRING_MULTIBYTE (it->string);
3637 it->current.overlay_string_index = -1;
3638 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3639 it->end_charpos = it->string_nchars = SCHARS (it->string);
3640 it->method = next_element_from_string;
3641 it->stop_charpos = 0;
3642 it->string_from_display_prop_p = 1;
3643 /* Say that we haven't consumed the characters with
3644 `display' property yet. The call to pop_it in
3645 set_iterator_to_next will clean this up. */
3646 *position = start_pos;
3647 }
3648 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3649 {
3650 it->method = next_element_from_stretch;
3651 it->object = value;
3652 it->current.pos = it->position = start_pos;
3653 }
3654 #ifdef HAVE_WINDOW_SYSTEM
3655 else
3656 {
3657 it->what = IT_IMAGE;
3658 it->image_id = lookup_image (it->f, value);
3659 it->position = start_pos;
3660 it->object = NILP (object) ? it->w->buffer : object;
3661 it->method = next_element_from_image;
3662
3663 /* Say that we haven't consumed the characters with
3664 `display' property yet. The call to pop_it in
3665 set_iterator_to_next will clean this up. */
3666 *position = start_pos;
3667 }
3668 #endif /* HAVE_WINDOW_SYSTEM */
3669 }
3670 else
3671 /* Invalid property or property not supported. Restore
3672 the position to what it was before. */
3673 *position = start_pos;
3674 }
3675
3676 return replaces_text_display_p;
3677 }
3678
3679
3680 /* Check if PROP is a display sub-property value whose text should be
3681 treated as intangible. */
3682
3683 static int
3684 single_display_prop_intangible_p (prop)
3685 Lisp_Object prop;
3686 {
3687 /* Skip over `when FORM'. */
3688 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3689 {
3690 prop = XCDR (prop);
3691 if (!CONSP (prop))
3692 return 0;
3693 prop = XCDR (prop);
3694 }
3695
3696 if (STRINGP (prop))
3697 return 1;
3698
3699 if (!CONSP (prop))
3700 return 0;
3701
3702 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3703 we don't need to treat text as intangible. */
3704 if (EQ (XCAR (prop), Qmargin))
3705 {
3706 prop = XCDR (prop);
3707 if (!CONSP (prop))
3708 return 0;
3709
3710 prop = XCDR (prop);
3711 if (!CONSP (prop)
3712 || EQ (XCAR (prop), Qleft_margin)
3713 || EQ (XCAR (prop), Qright_margin))
3714 return 0;
3715 }
3716
3717 return (CONSP (prop)
3718 && (EQ (XCAR (prop), Qimage)
3719 || EQ (XCAR (prop), Qspace)));
3720 }
3721
3722
3723 /* Check if PROP is a display property value whose text should be
3724 treated as intangible. */
3725
3726 int
3727 display_prop_intangible_p (prop)
3728 Lisp_Object prop;
3729 {
3730 if (CONSP (prop)
3731 && CONSP (XCAR (prop))
3732 && !EQ (Qmargin, XCAR (XCAR (prop))))
3733 {
3734 /* A list of sub-properties. */
3735 while (CONSP (prop))
3736 {
3737 if (single_display_prop_intangible_p (XCAR (prop)))
3738 return 1;
3739 prop = XCDR (prop);
3740 }
3741 }
3742 else if (VECTORP (prop))
3743 {
3744 /* A vector of sub-properties. */
3745 int i;
3746 for (i = 0; i < ASIZE (prop); ++i)
3747 if (single_display_prop_intangible_p (AREF (prop, i)))
3748 return 1;
3749 }
3750 else
3751 return single_display_prop_intangible_p (prop);
3752
3753 return 0;
3754 }
3755
3756
3757 /* Return 1 if PROP is a display sub-property value containing STRING. */
3758
3759 static int
3760 single_display_prop_string_p (prop, string)
3761 Lisp_Object prop, string;
3762 {
3763 if (EQ (string, prop))
3764 return 1;
3765
3766 /* Skip over `when FORM'. */
3767 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3768 {
3769 prop = XCDR (prop);
3770 if (!CONSP (prop))
3771 return 0;
3772 prop = XCDR (prop);
3773 }
3774
3775 if (CONSP (prop))
3776 /* Skip over `margin LOCATION'. */
3777 if (EQ (XCAR (prop), Qmargin))
3778 {
3779 prop = XCDR (prop);
3780 if (!CONSP (prop))
3781 return 0;
3782
3783 prop = XCDR (prop);
3784 if (!CONSP (prop))
3785 return 0;
3786 }
3787
3788 return CONSP (prop) && EQ (XCAR (prop), string);
3789 }
3790
3791
3792 /* Return 1 if STRING appears in the `display' property PROP. */
3793
3794 static int
3795 display_prop_string_p (prop, string)
3796 Lisp_Object prop, string;
3797 {
3798 if (CONSP (prop)
3799 && CONSP (XCAR (prop))
3800 && !EQ (Qmargin, XCAR (XCAR (prop))))
3801 {
3802 /* A list of sub-properties. */
3803 while (CONSP (prop))
3804 {
3805 if (single_display_prop_string_p (XCAR (prop), string))
3806 return 1;
3807 prop = XCDR (prop);
3808 }
3809 }
3810 else if (VECTORP (prop))
3811 {
3812 /* A vector of sub-properties. */
3813 int i;
3814 for (i = 0; i < ASIZE (prop); ++i)
3815 if (single_display_prop_string_p (AREF (prop, i), string))
3816 return 1;
3817 }
3818 else
3819 return single_display_prop_string_p (prop, string);
3820
3821 return 0;
3822 }
3823
3824
3825 /* Determine from which buffer position in W's buffer STRING comes
3826 from. AROUND_CHARPOS is an approximate position where it could
3827 be from. Value is the buffer position or 0 if it couldn't be
3828 determined.
3829
3830 W's buffer must be current.
3831
3832 This function is necessary because we don't record buffer positions
3833 in glyphs generated from strings (to keep struct glyph small).
3834 This function may only use code that doesn't eval because it is
3835 called asynchronously from note_mouse_highlight. */
3836
3837 int
3838 string_buffer_position (w, string, around_charpos)
3839 struct window *w;
3840 Lisp_Object string;
3841 int around_charpos;
3842 {
3843 Lisp_Object limit, prop, pos;
3844 const int MAX_DISTANCE = 1000;
3845 int found = 0;
3846
3847 pos = make_number (around_charpos);
3848 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3849 while (!found && !EQ (pos, limit))
3850 {
3851 prop = Fget_char_property (pos, Qdisplay, Qnil);
3852 if (!NILP (prop) && display_prop_string_p (prop, string))
3853 found = 1;
3854 else
3855 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3856 }
3857
3858 if (!found)
3859 {
3860 pos = make_number (around_charpos);
3861 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3862 while (!found && !EQ (pos, limit))
3863 {
3864 prop = Fget_char_property (pos, Qdisplay, Qnil);
3865 if (!NILP (prop) && display_prop_string_p (prop, string))
3866 found = 1;
3867 else
3868 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3869 limit);
3870 }
3871 }
3872
3873 return found ? XINT (pos) : 0;
3874 }
3875
3876
3877 \f
3878 /***********************************************************************
3879 `composition' property
3880 ***********************************************************************/
3881
3882 /* Set up iterator IT from `composition' property at its current
3883 position. Called from handle_stop. */
3884
3885 static enum prop_handled
3886 handle_composition_prop (it)
3887 struct it *it;
3888 {
3889 Lisp_Object prop, string;
3890 int pos, pos_byte, end;
3891 enum prop_handled handled = HANDLED_NORMALLY;
3892
3893 if (STRINGP (it->string))
3894 {
3895 pos = IT_STRING_CHARPOS (*it);
3896 pos_byte = IT_STRING_BYTEPOS (*it);
3897 string = it->string;
3898 }
3899 else
3900 {
3901 pos = IT_CHARPOS (*it);
3902 pos_byte = IT_BYTEPOS (*it);
3903 string = Qnil;
3904 }
3905
3906 /* If there's a valid composition and point is not inside of the
3907 composition (in the case that the composition is from the current
3908 buffer), draw a glyph composed from the composition components. */
3909 if (find_composition (pos, -1, &pos, &end, &prop, string)
3910 && COMPOSITION_VALID_P (pos, end, prop)
3911 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3912 {
3913 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3914
3915 if (id >= 0)
3916 {
3917 it->method = next_element_from_composition;
3918 it->cmp_id = id;
3919 it->cmp_len = COMPOSITION_LENGTH (prop);
3920 /* For a terminal, draw only the first character of the
3921 components. */
3922 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3923 it->len = (STRINGP (it->string)
3924 ? string_char_to_byte (it->string, end)
3925 : CHAR_TO_BYTE (end)) - pos_byte;
3926 it->stop_charpos = end;
3927 handled = HANDLED_RETURN;
3928 }
3929 }
3930
3931 return handled;
3932 }
3933
3934
3935 \f
3936 /***********************************************************************
3937 Overlay strings
3938 ***********************************************************************/
3939
3940 /* The following structure is used to record overlay strings for
3941 later sorting in load_overlay_strings. */
3942
3943 struct overlay_entry
3944 {
3945 Lisp_Object overlay;
3946 Lisp_Object string;
3947 int priority;
3948 int after_string_p;
3949 };
3950
3951
3952 /* Set up iterator IT from overlay strings at its current position.
3953 Called from handle_stop. */
3954
3955 static enum prop_handled
3956 handle_overlay_change (it)
3957 struct it *it;
3958 {
3959 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3960 return HANDLED_RECOMPUTE_PROPS;
3961 else
3962 return HANDLED_NORMALLY;
3963 }
3964
3965
3966 /* Set up the next overlay string for delivery by IT, if there is an
3967 overlay string to deliver. Called by set_iterator_to_next when the
3968 end of the current overlay string is reached. If there are more
3969 overlay strings to display, IT->string and
3970 IT->current.overlay_string_index are set appropriately here.
3971 Otherwise IT->string is set to nil. */
3972
3973 static void
3974 next_overlay_string (it)
3975 struct it *it;
3976 {
3977 ++it->current.overlay_string_index;
3978 if (it->current.overlay_string_index == it->n_overlay_strings)
3979 {
3980 /* No more overlay strings. Restore IT's settings to what
3981 they were before overlay strings were processed, and
3982 continue to deliver from current_buffer. */
3983 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3984
3985 pop_it (it);
3986 xassert (it->stop_charpos >= BEGV
3987 && it->stop_charpos <= it->end_charpos);
3988 it->string = Qnil;
3989 it->current.overlay_string_index = -1;
3990 SET_TEXT_POS (it->current.string_pos, -1, -1);
3991 it->n_overlay_strings = 0;
3992 it->method = next_element_from_buffer;
3993
3994 /* If we're at the end of the buffer, record that we have
3995 processed the overlay strings there already, so that
3996 next_element_from_buffer doesn't try it again. */
3997 if (IT_CHARPOS (*it) >= it->end_charpos)
3998 it->overlay_strings_at_end_processed_p = 1;
3999
4000 /* If we have to display `...' for invisible text, set
4001 the iterator up for that. */
4002 if (display_ellipsis_p)
4003 setup_for_ellipsis (it);
4004 }
4005 else
4006 {
4007 /* There are more overlay strings to process. If
4008 IT->current.overlay_string_index has advanced to a position
4009 where we must load IT->overlay_strings with more strings, do
4010 it. */
4011 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4012
4013 if (it->current.overlay_string_index && i == 0)
4014 load_overlay_strings (it, 0);
4015
4016 /* Initialize IT to deliver display elements from the overlay
4017 string. */
4018 it->string = it->overlay_strings[i];
4019 it->multibyte_p = STRING_MULTIBYTE (it->string);
4020 SET_TEXT_POS (it->current.string_pos, 0, 0);
4021 it->method = next_element_from_string;
4022 it->stop_charpos = 0;
4023 }
4024
4025 CHECK_IT (it);
4026 }
4027
4028
4029 /* Compare two overlay_entry structures E1 and E2. Used as a
4030 comparison function for qsort in load_overlay_strings. Overlay
4031 strings for the same position are sorted so that
4032
4033 1. All after-strings come in front of before-strings, except
4034 when they come from the same overlay.
4035
4036 2. Within after-strings, strings are sorted so that overlay strings
4037 from overlays with higher priorities come first.
4038
4039 2. Within before-strings, strings are sorted so that overlay
4040 strings from overlays with higher priorities come last.
4041
4042 Value is analogous to strcmp. */
4043
4044
4045 static int
4046 compare_overlay_entries (e1, e2)
4047 void *e1, *e2;
4048 {
4049 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4050 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4051 int result;
4052
4053 if (entry1->after_string_p != entry2->after_string_p)
4054 {
4055 /* Let after-strings appear in front of before-strings if
4056 they come from different overlays. */
4057 if (EQ (entry1->overlay, entry2->overlay))
4058 result = entry1->after_string_p ? 1 : -1;
4059 else
4060 result = entry1->after_string_p ? -1 : 1;
4061 }
4062 else if (entry1->after_string_p)
4063 /* After-strings sorted in order of decreasing priority. */
4064 result = entry2->priority - entry1->priority;
4065 else
4066 /* Before-strings sorted in order of increasing priority. */
4067 result = entry1->priority - entry2->priority;
4068
4069 return result;
4070 }
4071
4072
4073 /* Load the vector IT->overlay_strings with overlay strings from IT's
4074 current buffer position, or from CHARPOS if that is > 0. Set
4075 IT->n_overlays to the total number of overlay strings found.
4076
4077 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4078 a time. On entry into load_overlay_strings,
4079 IT->current.overlay_string_index gives the number of overlay
4080 strings that have already been loaded by previous calls to this
4081 function.
4082
4083 IT->add_overlay_start contains an additional overlay start
4084 position to consider for taking overlay strings from, if non-zero.
4085 This position comes into play when the overlay has an `invisible'
4086 property, and both before and after-strings. When we've skipped to
4087 the end of the overlay, because of its `invisible' property, we
4088 nevertheless want its before-string to appear.
4089 IT->add_overlay_start will contain the overlay start position
4090 in this case.
4091
4092 Overlay strings are sorted so that after-string strings come in
4093 front of before-string strings. Within before and after-strings,
4094 strings are sorted by overlay priority. See also function
4095 compare_overlay_entries. */
4096
4097 static void
4098 load_overlay_strings (it, charpos)
4099 struct it *it;
4100 int charpos;
4101 {
4102 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4103 Lisp_Object overlay, window, str, invisible;
4104 struct Lisp_Overlay *ov;
4105 int start, end;
4106 int size = 20;
4107 int n = 0, i, j, invis_p;
4108 struct overlay_entry *entries
4109 = (struct overlay_entry *) alloca (size * sizeof *entries);
4110
4111 if (charpos <= 0)
4112 charpos = IT_CHARPOS (*it);
4113
4114 /* Append the overlay string STRING of overlay OVERLAY to vector
4115 `entries' which has size `size' and currently contains `n'
4116 elements. AFTER_P non-zero means STRING is an after-string of
4117 OVERLAY. */
4118 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4119 do \
4120 { \
4121 Lisp_Object priority; \
4122 \
4123 if (n == size) \
4124 { \
4125 int new_size = 2 * size; \
4126 struct overlay_entry *old = entries; \
4127 entries = \
4128 (struct overlay_entry *) alloca (new_size \
4129 * sizeof *entries); \
4130 bcopy (old, entries, size * sizeof *entries); \
4131 size = new_size; \
4132 } \
4133 \
4134 entries[n].string = (STRING); \
4135 entries[n].overlay = (OVERLAY); \
4136 priority = Foverlay_get ((OVERLAY), Qpriority); \
4137 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4138 entries[n].after_string_p = (AFTER_P); \
4139 ++n; \
4140 } \
4141 while (0)
4142
4143 /* Process overlay before the overlay center. */
4144 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4145 {
4146 XSETMISC (overlay, ov);
4147 xassert (OVERLAYP (overlay));
4148 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4149 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4150
4151 if (end < charpos)
4152 break;
4153
4154 /* Skip this overlay if it doesn't start or end at IT's current
4155 position. */
4156 if (end != charpos && start != charpos)
4157 continue;
4158
4159 /* Skip this overlay if it doesn't apply to IT->w. */
4160 window = Foverlay_get (overlay, Qwindow);
4161 if (WINDOWP (window) && XWINDOW (window) != it->w)
4162 continue;
4163
4164 /* If the text ``under'' the overlay is invisible, both before-
4165 and after-strings from this overlay are visible; start and
4166 end position are indistinguishable. */
4167 invisible = Foverlay_get (overlay, Qinvisible);
4168 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4169
4170 /* If overlay has a non-empty before-string, record it. */
4171 if ((start == charpos || (end == charpos && invis_p))
4172 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4173 && SCHARS (str))
4174 RECORD_OVERLAY_STRING (overlay, str, 0);
4175
4176 /* If overlay has a non-empty after-string, record it. */
4177 if ((end == charpos || (start == charpos && invis_p))
4178 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4179 && SCHARS (str))
4180 RECORD_OVERLAY_STRING (overlay, str, 1);
4181 }
4182
4183 /* Process overlays after the overlay center. */
4184 for (ov = current_buffer->overlays_after; 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 (start > 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, it has a zero
4205 dimension, and both before- and after-strings apply. */
4206 invisible = Foverlay_get (overlay, Qinvisible);
4207 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4208
4209 /* If overlay has a non-empty before-string, record it. */
4210 if ((start == charpos || (end == charpos && invis_p))
4211 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4212 && SCHARS (str))
4213 RECORD_OVERLAY_STRING (overlay, str, 0);
4214
4215 /* If overlay has a non-empty after-string, record it. */
4216 if ((end == charpos || (start == charpos && invis_p))
4217 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4218 && SCHARS (str))
4219 RECORD_OVERLAY_STRING (overlay, str, 1);
4220 }
4221
4222 #undef RECORD_OVERLAY_STRING
4223
4224 /* Sort entries. */
4225 if (n > 1)
4226 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4227
4228 /* Record the total number of strings to process. */
4229 it->n_overlay_strings = n;
4230
4231 /* IT->current.overlay_string_index is the number of overlay strings
4232 that have already been consumed by IT. Copy some of the
4233 remaining overlay strings to IT->overlay_strings. */
4234 i = 0;
4235 j = it->current.overlay_string_index;
4236 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4237 it->overlay_strings[i++] = entries[j++].string;
4238
4239 CHECK_IT (it);
4240 }
4241
4242
4243 /* Get the first chunk of overlay strings at IT's current buffer
4244 position, or at CHARPOS if that is > 0. Value is non-zero if at
4245 least one overlay string was found. */
4246
4247 static int
4248 get_overlay_strings (it, charpos)
4249 struct it *it;
4250 int charpos;
4251 {
4252 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4253 process. This fills IT->overlay_strings with strings, and sets
4254 IT->n_overlay_strings to the total number of strings to process.
4255 IT->pos.overlay_string_index has to be set temporarily to zero
4256 because load_overlay_strings needs this; it must be set to -1
4257 when no overlay strings are found because a zero value would
4258 indicate a position in the first overlay string. */
4259 it->current.overlay_string_index = 0;
4260 load_overlay_strings (it, charpos);
4261
4262 /* If we found overlay strings, set up IT to deliver display
4263 elements from the first one. Otherwise set up IT to deliver
4264 from current_buffer. */
4265 if (it->n_overlay_strings)
4266 {
4267 /* Make sure we know settings in current_buffer, so that we can
4268 restore meaningful values when we're done with the overlay
4269 strings. */
4270 compute_stop_pos (it);
4271 xassert (it->face_id >= 0);
4272
4273 /* Save IT's settings. They are restored after all overlay
4274 strings have been processed. */
4275 xassert (it->sp == 0);
4276 push_it (it);
4277
4278 /* Set up IT to deliver display elements from the first overlay
4279 string. */
4280 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4281 it->string = it->overlay_strings[0];
4282 it->stop_charpos = 0;
4283 xassert (STRINGP (it->string));
4284 it->end_charpos = SCHARS (it->string);
4285 it->multibyte_p = STRING_MULTIBYTE (it->string);
4286 it->method = next_element_from_string;
4287 }
4288 else
4289 {
4290 it->string = Qnil;
4291 it->current.overlay_string_index = -1;
4292 it->method = next_element_from_buffer;
4293 }
4294
4295 CHECK_IT (it);
4296
4297 /* Value is non-zero if we found at least one overlay string. */
4298 return STRINGP (it->string);
4299 }
4300
4301
4302 \f
4303 /***********************************************************************
4304 Saving and restoring state
4305 ***********************************************************************/
4306
4307 /* Save current settings of IT on IT->stack. Called, for example,
4308 before setting up IT for an overlay string, to be able to restore
4309 IT's settings to what they were after the overlay string has been
4310 processed. */
4311
4312 static void
4313 push_it (it)
4314 struct it *it;
4315 {
4316 struct iterator_stack_entry *p;
4317
4318 xassert (it->sp < 2);
4319 p = it->stack + it->sp;
4320
4321 p->stop_charpos = it->stop_charpos;
4322 xassert (it->face_id >= 0);
4323 p->face_id = it->face_id;
4324 p->string = it->string;
4325 p->pos = it->current;
4326 p->end_charpos = it->end_charpos;
4327 p->string_nchars = it->string_nchars;
4328 p->area = it->area;
4329 p->multibyte_p = it->multibyte_p;
4330 p->space_width = it->space_width;
4331 p->font_height = it->font_height;
4332 p->voffset = it->voffset;
4333 p->string_from_display_prop_p = it->string_from_display_prop_p;
4334 p->display_ellipsis_p = 0;
4335 ++it->sp;
4336 }
4337
4338
4339 /* Restore IT's settings from IT->stack. Called, for example, when no
4340 more overlay strings must be processed, and we return to delivering
4341 display elements from a buffer, or when the end of a string from a
4342 `display' property is reached and we return to delivering display
4343 elements from an overlay string, or from a buffer. */
4344
4345 static void
4346 pop_it (it)
4347 struct it *it;
4348 {
4349 struct iterator_stack_entry *p;
4350
4351 xassert (it->sp > 0);
4352 --it->sp;
4353 p = it->stack + it->sp;
4354 it->stop_charpos = p->stop_charpos;
4355 it->face_id = p->face_id;
4356 it->string = p->string;
4357 it->current = p->pos;
4358 it->end_charpos = p->end_charpos;
4359 it->string_nchars = p->string_nchars;
4360 it->area = p->area;
4361 it->multibyte_p = p->multibyte_p;
4362 it->space_width = p->space_width;
4363 it->font_height = p->font_height;
4364 it->voffset = p->voffset;
4365 it->string_from_display_prop_p = p->string_from_display_prop_p;
4366 }
4367
4368
4369 \f
4370 /***********************************************************************
4371 Moving over lines
4372 ***********************************************************************/
4373
4374 /* Set IT's current position to the previous line start. */
4375
4376 static void
4377 back_to_previous_line_start (it)
4378 struct it *it;
4379 {
4380 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4381 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4382 }
4383
4384
4385 /* Move IT to the next line start.
4386
4387 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4388 we skipped over part of the text (as opposed to moving the iterator
4389 continuously over the text). Otherwise, don't change the value
4390 of *SKIPPED_P.
4391
4392 Newlines may come from buffer text, overlay strings, or strings
4393 displayed via the `display' property. That's the reason we can't
4394 simply use find_next_newline_no_quit.
4395
4396 Note that this function may not skip over invisible text that is so
4397 because of text properties and immediately follows a newline. If
4398 it would, function reseat_at_next_visible_line_start, when called
4399 from set_iterator_to_next, would effectively make invisible
4400 characters following a newline part of the wrong glyph row, which
4401 leads to wrong cursor motion. */
4402
4403 static int
4404 forward_to_next_line_start (it, skipped_p)
4405 struct it *it;
4406 int *skipped_p;
4407 {
4408 int old_selective, newline_found_p, n;
4409 const int MAX_NEWLINE_DISTANCE = 500;
4410
4411 /* If already on a newline, just consume it to avoid unintended
4412 skipping over invisible text below. */
4413 if (it->what == IT_CHARACTER
4414 && it->c == '\n'
4415 && CHARPOS (it->position) == IT_CHARPOS (*it))
4416 {
4417 set_iterator_to_next (it, 0);
4418 it->c = 0;
4419 return 1;
4420 }
4421
4422 /* Don't handle selective display in the following. It's (a)
4423 unnecessary because it's done by the caller, and (b) leads to an
4424 infinite recursion because next_element_from_ellipsis indirectly
4425 calls this function. */
4426 old_selective = it->selective;
4427 it->selective = 0;
4428
4429 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4430 from buffer text. */
4431 for (n = newline_found_p = 0;
4432 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4433 n += STRINGP (it->string) ? 0 : 1)
4434 {
4435 if (!get_next_display_element (it))
4436 return 0;
4437 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4438 set_iterator_to_next (it, 0);
4439 }
4440
4441 /* If we didn't find a newline near enough, see if we can use a
4442 short-cut. */
4443 if (!newline_found_p)
4444 {
4445 int start = IT_CHARPOS (*it);
4446 int limit = find_next_newline_no_quit (start, 1);
4447 Lisp_Object pos;
4448
4449 xassert (!STRINGP (it->string));
4450
4451 /* If there isn't any `display' property in sight, and no
4452 overlays, we can just use the position of the newline in
4453 buffer text. */
4454 if (it->stop_charpos >= limit
4455 || ((pos = Fnext_single_property_change (make_number (start),
4456 Qdisplay,
4457 Qnil, make_number (limit)),
4458 NILP (pos))
4459 && next_overlay_change (start) == ZV))
4460 {
4461 IT_CHARPOS (*it) = limit;
4462 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4463 *skipped_p = newline_found_p = 1;
4464 }
4465 else
4466 {
4467 while (get_next_display_element (it)
4468 && !newline_found_p)
4469 {
4470 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4471 set_iterator_to_next (it, 0);
4472 }
4473 }
4474 }
4475
4476 it->selective = old_selective;
4477 return newline_found_p;
4478 }
4479
4480
4481 /* Set IT's current position to the previous visible line start. Skip
4482 invisible text that is so either due to text properties or due to
4483 selective display. Caution: this does not change IT->current_x and
4484 IT->hpos. */
4485
4486 static void
4487 back_to_previous_visible_line_start (it)
4488 struct it *it;
4489 {
4490 int visible_p = 0;
4491
4492 /* Go back one newline if not on BEGV already. */
4493 if (IT_CHARPOS (*it) > BEGV)
4494 back_to_previous_line_start (it);
4495
4496 /* Move over lines that are invisible because of selective display
4497 or text properties. */
4498 while (IT_CHARPOS (*it) > BEGV
4499 && !visible_p)
4500 {
4501 visible_p = 1;
4502
4503 /* If selective > 0, then lines indented more than that values
4504 are invisible. */
4505 if (it->selective > 0
4506 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4507 (double) it->selective)) /* iftc */
4508 visible_p = 0;
4509 else
4510 {
4511 Lisp_Object prop;
4512
4513 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4514 Qinvisible, it->window);
4515 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4516 visible_p = 0;
4517 }
4518
4519 /* Back one more newline if the current one is invisible. */
4520 if (!visible_p)
4521 back_to_previous_line_start (it);
4522 }
4523
4524 xassert (IT_CHARPOS (*it) >= BEGV);
4525 xassert (IT_CHARPOS (*it) == BEGV
4526 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4527 CHECK_IT (it);
4528 }
4529
4530
4531 /* Reseat iterator IT at the previous visible line start. Skip
4532 invisible text that is so either due to text properties or due to
4533 selective display. At the end, update IT's overlay information,
4534 face information etc. */
4535
4536 static void
4537 reseat_at_previous_visible_line_start (it)
4538 struct it *it;
4539 {
4540 back_to_previous_visible_line_start (it);
4541 reseat (it, it->current.pos, 1);
4542 CHECK_IT (it);
4543 }
4544
4545
4546 /* Reseat iterator IT on the next visible line start in the current
4547 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4548 preceding the line start. Skip over invisible text that is so
4549 because of selective display. Compute faces, overlays etc at the
4550 new position. Note that this function does not skip over text that
4551 is invisible because of text properties. */
4552
4553 static void
4554 reseat_at_next_visible_line_start (it, on_newline_p)
4555 struct it *it;
4556 int on_newline_p;
4557 {
4558 int newline_found_p, skipped_p = 0;
4559
4560 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4561
4562 /* Skip over lines that are invisible because they are indented
4563 more than the value of IT->selective. */
4564 if (it->selective > 0)
4565 while (IT_CHARPOS (*it) < ZV
4566 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4567 (double) it->selective)) /* iftc */
4568 {
4569 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4570 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4571 }
4572
4573 /* Position on the newline if that's what's requested. */
4574 if (on_newline_p && newline_found_p)
4575 {
4576 if (STRINGP (it->string))
4577 {
4578 if (IT_STRING_CHARPOS (*it) > 0)
4579 {
4580 --IT_STRING_CHARPOS (*it);
4581 --IT_STRING_BYTEPOS (*it);
4582 }
4583 }
4584 else if (IT_CHARPOS (*it) > BEGV)
4585 {
4586 --IT_CHARPOS (*it);
4587 --IT_BYTEPOS (*it);
4588 reseat (it, it->current.pos, 0);
4589 }
4590 }
4591 else if (skipped_p)
4592 reseat (it, it->current.pos, 0);
4593
4594 CHECK_IT (it);
4595 }
4596
4597
4598 \f
4599 /***********************************************************************
4600 Changing an iterator's position
4601 ***********************************************************************/
4602
4603 /* Change IT's current position to POS in current_buffer. If FORCE_P
4604 is non-zero, always check for text properties at the new position.
4605 Otherwise, text properties are only looked up if POS >=
4606 IT->check_charpos of a property. */
4607
4608 static void
4609 reseat (it, pos, force_p)
4610 struct it *it;
4611 struct text_pos pos;
4612 int force_p;
4613 {
4614 int original_pos = IT_CHARPOS (*it);
4615
4616 reseat_1 (it, pos, 0);
4617
4618 /* Determine where to check text properties. Avoid doing it
4619 where possible because text property lookup is very expensive. */
4620 if (force_p
4621 || CHARPOS (pos) > it->stop_charpos
4622 || CHARPOS (pos) < original_pos)
4623 handle_stop (it);
4624
4625 CHECK_IT (it);
4626 }
4627
4628
4629 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4630 IT->stop_pos to POS, also. */
4631
4632 static void
4633 reseat_1 (it, pos, set_stop_p)
4634 struct it *it;
4635 struct text_pos pos;
4636 int set_stop_p;
4637 {
4638 /* Don't call this function when scanning a C string. */
4639 xassert (it->s == NULL);
4640
4641 /* POS must be a reasonable value. */
4642 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4643
4644 it->current.pos = it->position = pos;
4645 XSETBUFFER (it->object, current_buffer);
4646 it->end_charpos = ZV;
4647 it->dpvec = NULL;
4648 it->current.dpvec_index = -1;
4649 it->current.overlay_string_index = -1;
4650 IT_STRING_CHARPOS (*it) = -1;
4651 IT_STRING_BYTEPOS (*it) = -1;
4652 it->string = Qnil;
4653 it->method = next_element_from_buffer;
4654 /* RMS: I added this to fix a bug in move_it_vertically_backward
4655 where it->area continued to relate to the starting point
4656 for the backward motion. Bug report from
4657 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4658 However, I am not sure whether reseat still does the right thing
4659 in general after this change. */
4660 it->area = TEXT_AREA;
4661 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4662 it->sp = 0;
4663 it->face_before_selective_p = 0;
4664
4665 if (set_stop_p)
4666 it->stop_charpos = CHARPOS (pos);
4667 }
4668
4669
4670 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4671 If S is non-null, it is a C string to iterate over. Otherwise,
4672 STRING gives a Lisp string to iterate over.
4673
4674 If PRECISION > 0, don't return more then PRECISION number of
4675 characters from the string.
4676
4677 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4678 characters have been returned. FIELD_WIDTH < 0 means an infinite
4679 field width.
4680
4681 MULTIBYTE = 0 means disable processing of multibyte characters,
4682 MULTIBYTE > 0 means enable it,
4683 MULTIBYTE < 0 means use IT->multibyte_p.
4684
4685 IT must be initialized via a prior call to init_iterator before
4686 calling this function. */
4687
4688 static void
4689 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4690 struct it *it;
4691 unsigned char *s;
4692 Lisp_Object string;
4693 int charpos;
4694 int precision, field_width, multibyte;
4695 {
4696 /* No region in strings. */
4697 it->region_beg_charpos = it->region_end_charpos = -1;
4698
4699 /* No text property checks performed by default, but see below. */
4700 it->stop_charpos = -1;
4701
4702 /* Set iterator position and end position. */
4703 bzero (&it->current, sizeof it->current);
4704 it->current.overlay_string_index = -1;
4705 it->current.dpvec_index = -1;
4706 xassert (charpos >= 0);
4707
4708 /* If STRING is specified, use its multibyteness, otherwise use the
4709 setting of MULTIBYTE, if specified. */
4710 if (multibyte >= 0)
4711 it->multibyte_p = multibyte > 0;
4712
4713 if (s == NULL)
4714 {
4715 xassert (STRINGP (string));
4716 it->string = string;
4717 it->s = NULL;
4718 it->end_charpos = it->string_nchars = SCHARS (string);
4719 it->method = next_element_from_string;
4720 it->current.string_pos = string_pos (charpos, string);
4721 }
4722 else
4723 {
4724 it->s = s;
4725 it->string = Qnil;
4726
4727 /* Note that we use IT->current.pos, not it->current.string_pos,
4728 for displaying C strings. */
4729 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4730 if (it->multibyte_p)
4731 {
4732 it->current.pos = c_string_pos (charpos, s, 1);
4733 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4734 }
4735 else
4736 {
4737 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4738 it->end_charpos = it->string_nchars = strlen (s);
4739 }
4740
4741 it->method = next_element_from_c_string;
4742 }
4743
4744 /* PRECISION > 0 means don't return more than PRECISION characters
4745 from the string. */
4746 if (precision > 0 && it->end_charpos - charpos > precision)
4747 it->end_charpos = it->string_nchars = charpos + precision;
4748
4749 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4750 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4751 FIELD_WIDTH < 0 means infinite field width. This is useful for
4752 padding with `-' at the end of a mode line. */
4753 if (field_width < 0)
4754 field_width = INFINITY;
4755 if (field_width > it->end_charpos - charpos)
4756 it->end_charpos = charpos + field_width;
4757
4758 /* Use the standard display table for displaying strings. */
4759 if (DISP_TABLE_P (Vstandard_display_table))
4760 it->dp = XCHAR_TABLE (Vstandard_display_table);
4761
4762 it->stop_charpos = charpos;
4763 CHECK_IT (it);
4764 }
4765
4766
4767 \f
4768 /***********************************************************************
4769 Iteration
4770 ***********************************************************************/
4771
4772 /* Load IT's display element fields with information about the next
4773 display element from the current position of IT. Value is zero if
4774 end of buffer (or C string) is reached. */
4775
4776 int
4777 get_next_display_element (it)
4778 struct it *it;
4779 {
4780 /* Non-zero means that we found a display element. Zero means that
4781 we hit the end of what we iterate over. Performance note: the
4782 function pointer `method' used here turns out to be faster than
4783 using a sequence of if-statements. */
4784 int success_p = (*it->method) (it);
4785
4786 if (it->what == IT_CHARACTER)
4787 {
4788 /* Map via display table or translate control characters.
4789 IT->c, IT->len etc. have been set to the next character by
4790 the function call above. If we have a display table, and it
4791 contains an entry for IT->c, translate it. Don't do this if
4792 IT->c itself comes from a display table, otherwise we could
4793 end up in an infinite recursion. (An alternative could be to
4794 count the recursion depth of this function and signal an
4795 error when a certain maximum depth is reached.) Is it worth
4796 it? */
4797 if (success_p && it->dpvec == NULL)
4798 {
4799 Lisp_Object dv;
4800
4801 if (it->dp
4802 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4803 VECTORP (dv)))
4804 {
4805 struct Lisp_Vector *v = XVECTOR (dv);
4806
4807 /* Return the first character from the display table
4808 entry, if not empty. If empty, don't display the
4809 current character. */
4810 if (v->size)
4811 {
4812 it->dpvec_char_len = it->len;
4813 it->dpvec = v->contents;
4814 it->dpend = v->contents + v->size;
4815 it->current.dpvec_index = 0;
4816 it->method = next_element_from_display_vector;
4817 success_p = get_next_display_element (it);
4818 }
4819 else
4820 {
4821 set_iterator_to_next (it, 0);
4822 success_p = get_next_display_element (it);
4823 }
4824 }
4825
4826 /* Translate control characters into `\003' or `^C' form.
4827 Control characters coming from a display table entry are
4828 currently not translated because we use IT->dpvec to hold
4829 the translation. This could easily be changed but I
4830 don't believe that it is worth doing.
4831
4832 If it->multibyte_p is nonzero, eight-bit characters and
4833 non-printable multibyte characters are also translated to
4834 octal form.
4835
4836 If it->multibyte_p is zero, eight-bit characters that
4837 don't have corresponding multibyte char code are also
4838 translated to octal form. */
4839 else if ((it->c < ' '
4840 && (it->area != TEXT_AREA
4841 || (it->c != '\n' && it->c != '\t')))
4842 || (it->multibyte_p
4843 ? ((it->c >= 127
4844 && it->len == 1)
4845 || !CHAR_PRINTABLE_P (it->c))
4846 : (it->c >= 127
4847 && it->c == unibyte_char_to_multibyte (it->c))))
4848 {
4849 /* IT->c is a control character which must be displayed
4850 either as '\003' or as `^C' where the '\\' and '^'
4851 can be defined in the display table. Fill
4852 IT->ctl_chars with glyphs for what we have to
4853 display. Then, set IT->dpvec to these glyphs. */
4854 GLYPH g;
4855
4856 if (it->c < 128 && it->ctl_arrow_p)
4857 {
4858 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4859 if (it->dp
4860 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4861 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4862 g = XINT (DISP_CTRL_GLYPH (it->dp));
4863 else
4864 g = FAST_MAKE_GLYPH ('^', 0);
4865 XSETINT (it->ctl_chars[0], g);
4866
4867 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4868 XSETINT (it->ctl_chars[1], g);
4869
4870 /* Set up IT->dpvec and return first character from it. */
4871 it->dpvec_char_len = it->len;
4872 it->dpvec = it->ctl_chars;
4873 it->dpend = it->dpvec + 2;
4874 it->current.dpvec_index = 0;
4875 it->method = next_element_from_display_vector;
4876 get_next_display_element (it);
4877 }
4878 else
4879 {
4880 unsigned char str[MAX_MULTIBYTE_LENGTH];
4881 int len;
4882 int i;
4883 GLYPH escape_glyph;
4884
4885 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4886 if (it->dp
4887 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4888 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4889 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4890 else
4891 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4892
4893 if (SINGLE_BYTE_CHAR_P (it->c))
4894 str[0] = it->c, len = 1;
4895 else
4896 {
4897 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4898 if (len < 0)
4899 {
4900 /* It's an invalid character, which
4901 shouldn't happen actually, but due to
4902 bugs it may happen. Let's print the char
4903 as is, there's not much meaningful we can
4904 do with it. */
4905 str[0] = it->c;
4906 str[1] = it->c >> 8;
4907 str[2] = it->c >> 16;
4908 str[3] = it->c >> 24;
4909 len = 4;
4910 }
4911 }
4912
4913 for (i = 0; i < len; i++)
4914 {
4915 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4916 /* Insert three more glyphs into IT->ctl_chars for
4917 the octal display of the character. */
4918 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4919 XSETINT (it->ctl_chars[i * 4 + 1], g);
4920 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4921 XSETINT (it->ctl_chars[i * 4 + 2], g);
4922 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4923 XSETINT (it->ctl_chars[i * 4 + 3], g);
4924 }
4925
4926 /* Set up IT->dpvec and return the first character
4927 from it. */
4928 it->dpvec_char_len = it->len;
4929 it->dpvec = it->ctl_chars;
4930 it->dpend = it->dpvec + len * 4;
4931 it->current.dpvec_index = 0;
4932 it->method = next_element_from_display_vector;
4933 get_next_display_element (it);
4934 }
4935 }
4936 }
4937
4938 /* Adjust face id for a multibyte character. There are no
4939 multibyte character in unibyte text. */
4940 if (it->multibyte_p
4941 && success_p
4942 && FRAME_WINDOW_P (it->f))
4943 {
4944 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4945 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4946 }
4947 }
4948
4949 /* Is this character the last one of a run of characters with
4950 box? If yes, set IT->end_of_box_run_p to 1. */
4951 if (it->face_box_p
4952 && it->s == NULL)
4953 {
4954 int face_id;
4955 struct face *face;
4956
4957 it->end_of_box_run_p
4958 = ((face_id = face_after_it_pos (it),
4959 face_id != it->face_id)
4960 && (face = FACE_FROM_ID (it->f, face_id),
4961 face->box == FACE_NO_BOX));
4962 }
4963
4964 /* Value is 0 if end of buffer or string reached. */
4965 return success_p;
4966 }
4967
4968
4969 /* Move IT to the next display element.
4970
4971 RESEAT_P non-zero means if called on a newline in buffer text,
4972 skip to the next visible line start.
4973
4974 Functions get_next_display_element and set_iterator_to_next are
4975 separate because I find this arrangement easier to handle than a
4976 get_next_display_element function that also increments IT's
4977 position. The way it is we can first look at an iterator's current
4978 display element, decide whether it fits on a line, and if it does,
4979 increment the iterator position. The other way around we probably
4980 would either need a flag indicating whether the iterator has to be
4981 incremented the next time, or we would have to implement a
4982 decrement position function which would not be easy to write. */
4983
4984 void
4985 set_iterator_to_next (it, reseat_p)
4986 struct it *it;
4987 int reseat_p;
4988 {
4989 /* Reset flags indicating start and end of a sequence of characters
4990 with box. Reset them at the start of this function because
4991 moving the iterator to a new position might set them. */
4992 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4993
4994 if (it->method == next_element_from_buffer)
4995 {
4996 /* The current display element of IT is a character from
4997 current_buffer. Advance in the buffer, and maybe skip over
4998 invisible lines that are so because of selective display. */
4999 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5000 reseat_at_next_visible_line_start (it, 0);
5001 else
5002 {
5003 xassert (it->len != 0);
5004 IT_BYTEPOS (*it) += it->len;
5005 IT_CHARPOS (*it) += 1;
5006 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5007 }
5008 }
5009 else if (it->method == next_element_from_composition)
5010 {
5011 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
5012 if (STRINGP (it->string))
5013 {
5014 IT_STRING_BYTEPOS (*it) += it->len;
5015 IT_STRING_CHARPOS (*it) += it->cmp_len;
5016 it->method = next_element_from_string;
5017 goto consider_string_end;
5018 }
5019 else
5020 {
5021 IT_BYTEPOS (*it) += it->len;
5022 IT_CHARPOS (*it) += it->cmp_len;
5023 it->method = next_element_from_buffer;
5024 }
5025 }
5026 else if (it->method == next_element_from_c_string)
5027 {
5028 /* Current display element of IT is from a C string. */
5029 IT_BYTEPOS (*it) += it->len;
5030 IT_CHARPOS (*it) += 1;
5031 }
5032 else if (it->method == next_element_from_display_vector)
5033 {
5034 /* Current display element of IT is from a display table entry.
5035 Advance in the display table definition. Reset it to null if
5036 end reached, and continue with characters from buffers/
5037 strings. */
5038 ++it->current.dpvec_index;
5039
5040 /* Restore face of the iterator to what they were before the
5041 display vector entry (these entries may contain faces). */
5042 it->face_id = it->saved_face_id;
5043
5044 if (it->dpvec + it->current.dpvec_index == it->dpend)
5045 {
5046 if (it->s)
5047 it->method = next_element_from_c_string;
5048 else if (STRINGP (it->string))
5049 it->method = next_element_from_string;
5050 else
5051 it->method = next_element_from_buffer;
5052
5053 it->dpvec = NULL;
5054 it->current.dpvec_index = -1;
5055
5056 /* Skip over characters which were displayed via IT->dpvec. */
5057 if (it->dpvec_char_len < 0)
5058 reseat_at_next_visible_line_start (it, 1);
5059 else if (it->dpvec_char_len > 0)
5060 {
5061 it->len = it->dpvec_char_len;
5062 set_iterator_to_next (it, reseat_p);
5063 }
5064 }
5065 }
5066 else if (it->method == next_element_from_string)
5067 {
5068 /* Current display element is a character from a Lisp string. */
5069 xassert (it->s == NULL && STRINGP (it->string));
5070 IT_STRING_BYTEPOS (*it) += it->len;
5071 IT_STRING_CHARPOS (*it) += 1;
5072
5073 consider_string_end:
5074
5075 if (it->current.overlay_string_index >= 0)
5076 {
5077 /* IT->string is an overlay string. Advance to the
5078 next, if there is one. */
5079 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5080 next_overlay_string (it);
5081 }
5082 else
5083 {
5084 /* IT->string is not an overlay string. If we reached
5085 its end, and there is something on IT->stack, proceed
5086 with what is on the stack. This can be either another
5087 string, this time an overlay string, or a buffer. */
5088 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5089 && it->sp > 0)
5090 {
5091 pop_it (it);
5092 if (!STRINGP (it->string))
5093 it->method = next_element_from_buffer;
5094 else
5095 goto consider_string_end;
5096 }
5097 }
5098 }
5099 else if (it->method == next_element_from_image
5100 || it->method == next_element_from_stretch)
5101 {
5102 /* The position etc with which we have to proceed are on
5103 the stack. The position may be at the end of a string,
5104 if the `display' property takes up the whole string. */
5105 pop_it (it);
5106 it->image_id = 0;
5107 if (STRINGP (it->string))
5108 {
5109 it->method = next_element_from_string;
5110 goto consider_string_end;
5111 }
5112 else
5113 it->method = next_element_from_buffer;
5114 }
5115 else
5116 /* There are no other methods defined, so this should be a bug. */
5117 abort ();
5118
5119 xassert (it->method != next_element_from_string
5120 || (STRINGP (it->string)
5121 && IT_STRING_CHARPOS (*it) >= 0));
5122 }
5123
5124
5125 /* Load IT's display element fields with information about the next
5126 display element which comes from a display table entry or from the
5127 result of translating a control character to one of the forms `^C'
5128 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5129
5130 static int
5131 next_element_from_display_vector (it)
5132 struct it *it;
5133 {
5134 /* Precondition. */
5135 xassert (it->dpvec && it->current.dpvec_index >= 0);
5136
5137 /* Remember the current face id in case glyphs specify faces.
5138 IT's face is restored in set_iterator_to_next. */
5139 it->saved_face_id = it->face_id;
5140
5141 if (INTEGERP (*it->dpvec)
5142 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5143 {
5144 int lface_id;
5145 GLYPH g;
5146
5147 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5148 it->c = FAST_GLYPH_CHAR (g);
5149 it->len = CHAR_BYTES (it->c);
5150
5151 /* The entry may contain a face id to use. Such a face id is
5152 the id of a Lisp face, not a realized face. A face id of
5153 zero means no face is specified. */
5154 lface_id = FAST_GLYPH_FACE (g);
5155 if (lface_id)
5156 {
5157 /* The function returns -1 if lface_id is invalid. */
5158 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5159 if (face_id >= 0)
5160 it->face_id = face_id;
5161 }
5162 }
5163 else
5164 /* Display table entry is invalid. Return a space. */
5165 it->c = ' ', it->len = 1;
5166
5167 /* Don't change position and object of the iterator here. They are
5168 still the values of the character that had this display table
5169 entry or was translated, and that's what we want. */
5170 it->what = IT_CHARACTER;
5171 return 1;
5172 }
5173
5174
5175 /* Load IT with the next display element from Lisp string IT->string.
5176 IT->current.string_pos is the current position within the string.
5177 If IT->current.overlay_string_index >= 0, the Lisp string is an
5178 overlay string. */
5179
5180 static int
5181 next_element_from_string (it)
5182 struct it *it;
5183 {
5184 struct text_pos position;
5185
5186 xassert (STRINGP (it->string));
5187 xassert (IT_STRING_CHARPOS (*it) >= 0);
5188 position = it->current.string_pos;
5189
5190 /* Time to check for invisible text? */
5191 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5192 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5193 {
5194 handle_stop (it);
5195
5196 /* Since a handler may have changed IT->method, we must
5197 recurse here. */
5198 return get_next_display_element (it);
5199 }
5200
5201 if (it->current.overlay_string_index >= 0)
5202 {
5203 /* Get the next character from an overlay string. In overlay
5204 strings, There is no field width or padding with spaces to
5205 do. */
5206 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5207 {
5208 it->what = IT_EOB;
5209 return 0;
5210 }
5211 else if (STRING_MULTIBYTE (it->string))
5212 {
5213 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5214 const unsigned char *s = (SDATA (it->string)
5215 + IT_STRING_BYTEPOS (*it));
5216 it->c = string_char_and_length (s, remaining, &it->len);
5217 }
5218 else
5219 {
5220 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5221 it->len = 1;
5222 }
5223 }
5224 else
5225 {
5226 /* Get the next character from a Lisp string that is not an
5227 overlay string. Such strings come from the mode line, for
5228 example. We may have to pad with spaces, or truncate the
5229 string. See also next_element_from_c_string. */
5230 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5231 {
5232 it->what = IT_EOB;
5233 return 0;
5234 }
5235 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5236 {
5237 /* Pad with spaces. */
5238 it->c = ' ', it->len = 1;
5239 CHARPOS (position) = BYTEPOS (position) = -1;
5240 }
5241 else if (STRING_MULTIBYTE (it->string))
5242 {
5243 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5244 const unsigned char *s = (SDATA (it->string)
5245 + IT_STRING_BYTEPOS (*it));
5246 it->c = string_char_and_length (s, maxlen, &it->len);
5247 }
5248 else
5249 {
5250 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5251 it->len = 1;
5252 }
5253 }
5254
5255 /* Record what we have and where it came from. Note that we store a
5256 buffer position in IT->position although it could arguably be a
5257 string position. */
5258 it->what = IT_CHARACTER;
5259 it->object = it->string;
5260 it->position = position;
5261 return 1;
5262 }
5263
5264
5265 /* Load IT with next display element from C string IT->s.
5266 IT->string_nchars is the maximum number of characters to return
5267 from the string. IT->end_charpos may be greater than
5268 IT->string_nchars when this function is called, in which case we
5269 may have to return padding spaces. Value is zero if end of string
5270 reached, including padding spaces. */
5271
5272 static int
5273 next_element_from_c_string (it)
5274 struct it *it;
5275 {
5276 int success_p = 1;
5277
5278 xassert (it->s);
5279 it->what = IT_CHARACTER;
5280 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5281 it->object = Qnil;
5282
5283 /* IT's position can be greater IT->string_nchars in case a field
5284 width or precision has been specified when the iterator was
5285 initialized. */
5286 if (IT_CHARPOS (*it) >= it->end_charpos)
5287 {
5288 /* End of the game. */
5289 it->what = IT_EOB;
5290 success_p = 0;
5291 }
5292 else if (IT_CHARPOS (*it) >= it->string_nchars)
5293 {
5294 /* Pad with spaces. */
5295 it->c = ' ', it->len = 1;
5296 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5297 }
5298 else if (it->multibyte_p)
5299 {
5300 /* Implementation note: The calls to strlen apparently aren't a
5301 performance problem because there is no noticeable performance
5302 difference between Emacs running in unibyte or multibyte mode. */
5303 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5304 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5305 maxlen, &it->len);
5306 }
5307 else
5308 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5309
5310 return success_p;
5311 }
5312
5313
5314 /* Set up IT to return characters from an ellipsis, if appropriate.
5315 The definition of the ellipsis glyphs may come from a display table
5316 entry. This function Fills IT with the first glyph from the
5317 ellipsis if an ellipsis is to be displayed. */
5318
5319 static int
5320 next_element_from_ellipsis (it)
5321 struct it *it;
5322 {
5323 if (it->selective_display_ellipsis_p)
5324 {
5325 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5326 {
5327 /* Use the display table definition for `...'. Invalid glyphs
5328 will be handled by the method returning elements from dpvec. */
5329 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5330 it->dpvec_char_len = it->len;
5331 it->dpvec = v->contents;
5332 it->dpend = v->contents + v->size;
5333 it->current.dpvec_index = 0;
5334 it->method = next_element_from_display_vector;
5335 }
5336 else
5337 {
5338 /* Use default `...' which is stored in default_invis_vector. */
5339 it->dpvec_char_len = it->len;
5340 it->dpvec = default_invis_vector;
5341 it->dpend = default_invis_vector + 3;
5342 it->current.dpvec_index = 0;
5343 it->method = next_element_from_display_vector;
5344 }
5345 }
5346 else
5347 {
5348 /* The face at the current position may be different from the
5349 face we find after the invisible text. Remember what it
5350 was in IT->saved_face_id, and signal that it's there by
5351 setting face_before_selective_p. */
5352 it->saved_face_id = it->face_id;
5353 it->method = next_element_from_buffer;
5354 reseat_at_next_visible_line_start (it, 1);
5355 it->face_before_selective_p = 1;
5356 }
5357
5358 return get_next_display_element (it);
5359 }
5360
5361
5362 /* Deliver an image display element. The iterator IT is already
5363 filled with image information (done in handle_display_prop). Value
5364 is always 1. */
5365
5366
5367 static int
5368 next_element_from_image (it)
5369 struct it *it;
5370 {
5371 it->what = IT_IMAGE;
5372 return 1;
5373 }
5374
5375
5376 /* Fill iterator IT with next display element from a stretch glyph
5377 property. IT->object is the value of the text property. Value is
5378 always 1. */
5379
5380 static int
5381 next_element_from_stretch (it)
5382 struct it *it;
5383 {
5384 it->what = IT_STRETCH;
5385 return 1;
5386 }
5387
5388
5389 /* Load IT with the next display element from current_buffer. Value
5390 is zero if end of buffer reached. IT->stop_charpos is the next
5391 position at which to stop and check for text properties or buffer
5392 end. */
5393
5394 static int
5395 next_element_from_buffer (it)
5396 struct it *it;
5397 {
5398 int success_p = 1;
5399
5400 /* Check this assumption, otherwise, we would never enter the
5401 if-statement, below. */
5402 xassert (IT_CHARPOS (*it) >= BEGV
5403 && IT_CHARPOS (*it) <= it->stop_charpos);
5404
5405 if (IT_CHARPOS (*it) >= it->stop_charpos)
5406 {
5407 if (IT_CHARPOS (*it) >= it->end_charpos)
5408 {
5409 int overlay_strings_follow_p;
5410
5411 /* End of the game, except when overlay strings follow that
5412 haven't been returned yet. */
5413 if (it->overlay_strings_at_end_processed_p)
5414 overlay_strings_follow_p = 0;
5415 else
5416 {
5417 it->overlay_strings_at_end_processed_p = 1;
5418 overlay_strings_follow_p = get_overlay_strings (it, 0);
5419 }
5420
5421 if (overlay_strings_follow_p)
5422 success_p = get_next_display_element (it);
5423 else
5424 {
5425 it->what = IT_EOB;
5426 it->position = it->current.pos;
5427 success_p = 0;
5428 }
5429 }
5430 else
5431 {
5432 handle_stop (it);
5433 return get_next_display_element (it);
5434 }
5435 }
5436 else
5437 {
5438 /* No face changes, overlays etc. in sight, so just return a
5439 character from current_buffer. */
5440 unsigned char *p;
5441
5442 /* Maybe run the redisplay end trigger hook. Performance note:
5443 This doesn't seem to cost measurable time. */
5444 if (it->redisplay_end_trigger_charpos
5445 && it->glyph_row
5446 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5447 run_redisplay_end_trigger_hook (it);
5448
5449 /* Get the next character, maybe multibyte. */
5450 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5451 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5452 {
5453 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5454 - IT_BYTEPOS (*it));
5455 it->c = string_char_and_length (p, maxlen, &it->len);
5456 }
5457 else
5458 it->c = *p, it->len = 1;
5459
5460 /* Record what we have and where it came from. */
5461 it->what = IT_CHARACTER;;
5462 it->object = it->w->buffer;
5463 it->position = it->current.pos;
5464
5465 /* Normally we return the character found above, except when we
5466 really want to return an ellipsis for selective display. */
5467 if (it->selective)
5468 {
5469 if (it->c == '\n')
5470 {
5471 /* A value of selective > 0 means hide lines indented more
5472 than that number of columns. */
5473 if (it->selective > 0
5474 && IT_CHARPOS (*it) + 1 < ZV
5475 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5476 IT_BYTEPOS (*it) + 1,
5477 (double) it->selective)) /* iftc */
5478 {
5479 success_p = next_element_from_ellipsis (it);
5480 it->dpvec_char_len = -1;
5481 }
5482 }
5483 else if (it->c == '\r' && it->selective == -1)
5484 {
5485 /* A value of selective == -1 means that everything from the
5486 CR to the end of the line is invisible, with maybe an
5487 ellipsis displayed for it. */
5488 success_p = next_element_from_ellipsis (it);
5489 it->dpvec_char_len = -1;
5490 }
5491 }
5492 }
5493
5494 /* Value is zero if end of buffer reached. */
5495 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5496 return success_p;
5497 }
5498
5499
5500 /* Run the redisplay end trigger hook for IT. */
5501
5502 static void
5503 run_redisplay_end_trigger_hook (it)
5504 struct it *it;
5505 {
5506 Lisp_Object args[3];
5507
5508 /* IT->glyph_row should be non-null, i.e. we should be actually
5509 displaying something, or otherwise we should not run the hook. */
5510 xassert (it->glyph_row);
5511
5512 /* Set up hook arguments. */
5513 args[0] = Qredisplay_end_trigger_functions;
5514 args[1] = it->window;
5515 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5516 it->redisplay_end_trigger_charpos = 0;
5517
5518 /* Since we are *trying* to run these functions, don't try to run
5519 them again, even if they get an error. */
5520 it->w->redisplay_end_trigger = Qnil;
5521 Frun_hook_with_args (3, args);
5522
5523 /* Notice if it changed the face of the character we are on. */
5524 handle_face_prop (it);
5525 }
5526
5527
5528 /* Deliver a composition display element. The iterator IT is already
5529 filled with composition information (done in
5530 handle_composition_prop). Value is always 1. */
5531
5532 static int
5533 next_element_from_composition (it)
5534 struct it *it;
5535 {
5536 it->what = IT_COMPOSITION;
5537 it->position = (STRINGP (it->string)
5538 ? it->current.string_pos
5539 : it->current.pos);
5540 return 1;
5541 }
5542
5543
5544 \f
5545 /***********************************************************************
5546 Moving an iterator without producing glyphs
5547 ***********************************************************************/
5548
5549 /* Move iterator IT to a specified buffer or X position within one
5550 line on the display without producing glyphs.
5551
5552 OP should be a bit mask including some or all of these bits:
5553 MOVE_TO_X: Stop on reaching x-position TO_X.
5554 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5555 Regardless of OP's value, stop in reaching the end of the display line.
5556
5557 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5558 This means, in particular, that TO_X includes window's horizontal
5559 scroll amount.
5560
5561 The return value has several possible values that
5562 say what condition caused the scan to stop:
5563
5564 MOVE_POS_MATCH_OR_ZV
5565 - when TO_POS or ZV was reached.
5566
5567 MOVE_X_REACHED
5568 -when TO_X was reached before TO_POS or ZV were reached.
5569
5570 MOVE_LINE_CONTINUED
5571 - when we reached the end of the display area and the line must
5572 be continued.
5573
5574 MOVE_LINE_TRUNCATED
5575 - when we reached the end of the display area and the line is
5576 truncated.
5577
5578 MOVE_NEWLINE_OR_CR
5579 - when we stopped at a line end, i.e. a newline or a CR and selective
5580 display is on. */
5581
5582 static enum move_it_result
5583 move_it_in_display_line_to (it, to_charpos, to_x, op)
5584 struct it *it;
5585 int to_charpos, to_x, op;
5586 {
5587 enum move_it_result result = MOVE_UNDEFINED;
5588 struct glyph_row *saved_glyph_row;
5589
5590 /* Don't produce glyphs in produce_glyphs. */
5591 saved_glyph_row = it->glyph_row;
5592 it->glyph_row = NULL;
5593
5594 #define BUFFER_POS_REACHED_P() \
5595 ((op & MOVE_TO_POS) != 0 \
5596 && BUFFERP (it->object) \
5597 && IT_CHARPOS (*it) >= to_charpos)
5598
5599 while (1)
5600 {
5601 int x, i, ascent = 0, descent = 0;
5602
5603 /* Stop when ZV or TO_CHARPOS reached. */
5604 if (!get_next_display_element (it)
5605 || BUFFER_POS_REACHED_P ())
5606 {
5607 result = MOVE_POS_MATCH_OR_ZV;
5608 break;
5609 }
5610
5611 /* The call to produce_glyphs will get the metrics of the
5612 display element IT is loaded with. We record in x the
5613 x-position before this display element in case it does not
5614 fit on the line. */
5615 x = it->current_x;
5616
5617 /* Remember the line height so far in case the next element doesn't
5618 fit on the line. */
5619 if (!it->truncate_lines_p)
5620 {
5621 ascent = it->max_ascent;
5622 descent = it->max_descent;
5623 }
5624
5625 PRODUCE_GLYPHS (it);
5626
5627 if (it->area != TEXT_AREA)
5628 {
5629 set_iterator_to_next (it, 1);
5630 continue;
5631 }
5632
5633 /* The number of glyphs we get back in IT->nglyphs will normally
5634 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5635 character on a terminal frame, or (iii) a line end. For the
5636 second case, IT->nglyphs - 1 padding glyphs will be present
5637 (on X frames, there is only one glyph produced for a
5638 composite character.
5639
5640 The behavior implemented below means, for continuation lines,
5641 that as many spaces of a TAB as fit on the current line are
5642 displayed there. For terminal frames, as many glyphs of a
5643 multi-glyph character are displayed in the current line, too.
5644 This is what the old redisplay code did, and we keep it that
5645 way. Under X, the whole shape of a complex character must
5646 fit on the line or it will be completely displayed in the
5647 next line.
5648
5649 Note that both for tabs and padding glyphs, all glyphs have
5650 the same width. */
5651 if (it->nglyphs)
5652 {
5653 /* More than one glyph or glyph doesn't fit on line. All
5654 glyphs have the same width. */
5655 int single_glyph_width = it->pixel_width / it->nglyphs;
5656 int new_x;
5657
5658 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5659 {
5660 new_x = x + single_glyph_width;
5661
5662 /* We want to leave anything reaching TO_X to the caller. */
5663 if ((op & MOVE_TO_X) && new_x > to_x)
5664 {
5665 it->current_x = x;
5666 result = MOVE_X_REACHED;
5667 break;
5668 }
5669 else if (/* Lines are continued. */
5670 !it->truncate_lines_p
5671 && (/* And glyph doesn't fit on the line. */
5672 new_x > it->last_visible_x
5673 /* Or it fits exactly and we're on a window
5674 system frame. */
5675 || (new_x == it->last_visible_x
5676 && FRAME_WINDOW_P (it->f))))
5677 {
5678 if (/* IT->hpos == 0 means the very first glyph
5679 doesn't fit on the line, e.g. a wide image. */
5680 it->hpos == 0
5681 || (new_x == it->last_visible_x
5682 && FRAME_WINDOW_P (it->f)))
5683 {
5684 ++it->hpos;
5685 it->current_x = new_x;
5686 if (i == it->nglyphs - 1)
5687 {
5688 set_iterator_to_next (it, 1);
5689 #ifdef HAVE_WINDOW_SYSTEM
5690 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5691 {
5692 if (!get_next_display_element (it)
5693 || BUFFER_POS_REACHED_P ())
5694 {
5695 result = MOVE_POS_MATCH_OR_ZV;
5696 break;
5697 }
5698 if (ITERATOR_AT_END_OF_LINE_P (it))
5699 {
5700 result = MOVE_NEWLINE_OR_CR;
5701 break;
5702 }
5703 }
5704 #endif /* HAVE_WINDOW_SYSTEM */
5705 }
5706 }
5707 else
5708 {
5709 it->current_x = x;
5710 it->max_ascent = ascent;
5711 it->max_descent = descent;
5712 }
5713
5714 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5715 IT_CHARPOS (*it)));
5716 result = MOVE_LINE_CONTINUED;
5717 break;
5718 }
5719 else if (new_x > it->first_visible_x)
5720 {
5721 /* Glyph is visible. Increment number of glyphs that
5722 would be displayed. */
5723 ++it->hpos;
5724 }
5725 else
5726 {
5727 /* Glyph is completely off the left margin of the display
5728 area. Nothing to do. */
5729 }
5730 }
5731
5732 if (result != MOVE_UNDEFINED)
5733 break;
5734 }
5735 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5736 {
5737 /* Stop when TO_X specified and reached. This check is
5738 necessary here because of lines consisting of a line end,
5739 only. The line end will not produce any glyphs and we
5740 would never get MOVE_X_REACHED. */
5741 xassert (it->nglyphs == 0);
5742 result = MOVE_X_REACHED;
5743 break;
5744 }
5745
5746 /* Is this a line end? If yes, we're done. */
5747 if (ITERATOR_AT_END_OF_LINE_P (it))
5748 {
5749 result = MOVE_NEWLINE_OR_CR;
5750 break;
5751 }
5752
5753 /* The current display element has been consumed. Advance
5754 to the next. */
5755 set_iterator_to_next (it, 1);
5756
5757 /* Stop if lines are truncated and IT's current x-position is
5758 past the right edge of the window now. */
5759 if (it->truncate_lines_p
5760 && it->current_x >= it->last_visible_x)
5761 {
5762 #ifdef HAVE_WINDOW_SYSTEM
5763 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5764 {
5765 if (!get_next_display_element (it)
5766 || BUFFER_POS_REACHED_P ())
5767 {
5768 result = MOVE_POS_MATCH_OR_ZV;
5769 break;
5770 }
5771 if (ITERATOR_AT_END_OF_LINE_P (it))
5772 {
5773 result = MOVE_NEWLINE_OR_CR;
5774 break;
5775 }
5776 }
5777 #endif /* HAVE_WINDOW_SYSTEM */
5778 result = MOVE_LINE_TRUNCATED;
5779 break;
5780 }
5781 }
5782
5783 #undef BUFFER_POS_REACHED_P
5784
5785 /* Restore the iterator settings altered at the beginning of this
5786 function. */
5787 it->glyph_row = saved_glyph_row;
5788 return result;
5789 }
5790
5791
5792 /* Move IT forward until it satisfies one or more of the criteria in
5793 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5794
5795 OP is a bit-mask that specifies where to stop, and in particular,
5796 which of those four position arguments makes a difference. See the
5797 description of enum move_operation_enum.
5798
5799 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5800 screen line, this function will set IT to the next position >
5801 TO_CHARPOS. */
5802
5803 void
5804 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5805 struct it *it;
5806 int to_charpos, to_x, to_y, to_vpos;
5807 int op;
5808 {
5809 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5810 int line_height;
5811 int reached = 0;
5812
5813 for (;;)
5814 {
5815 if (op & MOVE_TO_VPOS)
5816 {
5817 /* If no TO_CHARPOS and no TO_X specified, stop at the
5818 start of the line TO_VPOS. */
5819 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5820 {
5821 if (it->vpos == to_vpos)
5822 {
5823 reached = 1;
5824 break;
5825 }
5826 else
5827 skip = move_it_in_display_line_to (it, -1, -1, 0);
5828 }
5829 else
5830 {
5831 /* TO_VPOS >= 0 means stop at TO_X in the line at
5832 TO_VPOS, or at TO_POS, whichever comes first. */
5833 if (it->vpos == to_vpos)
5834 {
5835 reached = 2;
5836 break;
5837 }
5838
5839 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5840
5841 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5842 {
5843 reached = 3;
5844 break;
5845 }
5846 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5847 {
5848 /* We have reached TO_X but not in the line we want. */
5849 skip = move_it_in_display_line_to (it, to_charpos,
5850 -1, MOVE_TO_POS);
5851 if (skip == MOVE_POS_MATCH_OR_ZV)
5852 {
5853 reached = 4;
5854 break;
5855 }
5856 }
5857 }
5858 }
5859 else if (op & MOVE_TO_Y)
5860 {
5861 struct it it_backup;
5862
5863 /* TO_Y specified means stop at TO_X in the line containing
5864 TO_Y---or at TO_CHARPOS if this is reached first. The
5865 problem is that we can't really tell whether the line
5866 contains TO_Y before we have completely scanned it, and
5867 this may skip past TO_X. What we do is to first scan to
5868 TO_X.
5869
5870 If TO_X is not specified, use a TO_X of zero. The reason
5871 is to make the outcome of this function more predictable.
5872 If we didn't use TO_X == 0, we would stop at the end of
5873 the line which is probably not what a caller would expect
5874 to happen. */
5875 skip = move_it_in_display_line_to (it, to_charpos,
5876 ((op & MOVE_TO_X)
5877 ? to_x : 0),
5878 (MOVE_TO_X
5879 | (op & MOVE_TO_POS)));
5880
5881 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5882 if (skip == MOVE_POS_MATCH_OR_ZV)
5883 {
5884 reached = 5;
5885 break;
5886 }
5887
5888 /* If TO_X was reached, we would like to know whether TO_Y
5889 is in the line. This can only be said if we know the
5890 total line height which requires us to scan the rest of
5891 the line. */
5892 if (skip == MOVE_X_REACHED)
5893 {
5894 it_backup = *it;
5895 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5896 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5897 op & MOVE_TO_POS);
5898 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5899 }
5900
5901 /* Now, decide whether TO_Y is in this line. */
5902 line_height = it->max_ascent + it->max_descent;
5903 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5904
5905 if (to_y >= it->current_y
5906 && to_y < it->current_y + line_height)
5907 {
5908 if (skip == MOVE_X_REACHED)
5909 /* If TO_Y is in this line and TO_X was reached above,
5910 we scanned too far. We have to restore IT's settings
5911 to the ones before skipping. */
5912 *it = it_backup;
5913 reached = 6;
5914 }
5915 else if (skip == MOVE_X_REACHED)
5916 {
5917 skip = skip2;
5918 if (skip == MOVE_POS_MATCH_OR_ZV)
5919 reached = 7;
5920 }
5921
5922 if (reached)
5923 break;
5924 }
5925 else
5926 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5927
5928 switch (skip)
5929 {
5930 case MOVE_POS_MATCH_OR_ZV:
5931 reached = 8;
5932 goto out;
5933
5934 case MOVE_NEWLINE_OR_CR:
5935 set_iterator_to_next (it, 1);
5936 it->continuation_lines_width = 0;
5937 break;
5938
5939 case MOVE_LINE_TRUNCATED:
5940 it->continuation_lines_width = 0;
5941 reseat_at_next_visible_line_start (it, 0);
5942 if ((op & MOVE_TO_POS) != 0
5943 && IT_CHARPOS (*it) > to_charpos)
5944 {
5945 reached = 9;
5946 goto out;
5947 }
5948 break;
5949
5950 case MOVE_LINE_CONTINUED:
5951 it->continuation_lines_width += it->current_x;
5952 break;
5953
5954 default:
5955 abort ();
5956 }
5957
5958 /* Reset/increment for the next run. */
5959 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5960 it->current_x = it->hpos = 0;
5961 it->current_y += it->max_ascent + it->max_descent;
5962 ++it->vpos;
5963 last_height = it->max_ascent + it->max_descent;
5964 last_max_ascent = it->max_ascent;
5965 it->max_ascent = it->max_descent = 0;
5966 }
5967
5968 out:
5969
5970 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5971 }
5972
5973
5974 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5975
5976 If DY > 0, move IT backward at least that many pixels. DY = 0
5977 means move IT backward to the preceding line start or BEGV. This
5978 function may move over more than DY pixels if IT->current_y - DY
5979 ends up in the middle of a line; in this case IT->current_y will be
5980 set to the top of the line moved to. */
5981
5982 void
5983 move_it_vertically_backward (it, dy)
5984 struct it *it;
5985 int dy;
5986 {
5987 int nlines, h;
5988 struct it it2, it3;
5989 int start_pos = IT_CHARPOS (*it);
5990
5991 xassert (dy >= 0);
5992
5993 /* Estimate how many newlines we must move back. */
5994 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5995
5996 /* Set the iterator's position that many lines back. */
5997 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5998 back_to_previous_visible_line_start (it);
5999
6000 /* Reseat the iterator here. When moving backward, we don't want
6001 reseat to skip forward over invisible text, set up the iterator
6002 to deliver from overlay strings at the new position etc. So,
6003 use reseat_1 here. */
6004 reseat_1 (it, it->current.pos, 1);
6005
6006 /* We are now surely at a line start. */
6007 it->current_x = it->hpos = 0;
6008 it->continuation_lines_width = 0;
6009
6010 /* Move forward and see what y-distance we moved. First move to the
6011 start of the next line so that we get its height. We need this
6012 height to be able to tell whether we reached the specified
6013 y-distance. */
6014 it2 = *it;
6015 it2.max_ascent = it2.max_descent = 0;
6016 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6017 MOVE_TO_POS | MOVE_TO_VPOS);
6018 xassert (IT_CHARPOS (*it) >= BEGV);
6019 it3 = it2;
6020
6021 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6022 xassert (IT_CHARPOS (*it) >= BEGV);
6023 /* H is the actual vertical distance from the position in *IT
6024 and the starting position. */
6025 h = it2.current_y - it->current_y;
6026 /* NLINES is the distance in number of lines. */
6027 nlines = it2.vpos - it->vpos;
6028
6029 /* Correct IT's y and vpos position
6030 so that they are relative to the starting point. */
6031 it->vpos -= nlines;
6032 it->current_y -= h;
6033
6034 if (dy == 0)
6035 {
6036 /* DY == 0 means move to the start of the screen line. The
6037 value of nlines is > 0 if continuation lines were involved. */
6038 if (nlines > 0)
6039 move_it_by_lines (it, nlines, 1);
6040 xassert (IT_CHARPOS (*it) <= start_pos);
6041 }
6042 else
6043 {
6044 /* The y-position we try to reach, relative to *IT.
6045 Note that H has been subtracted in front of the if-statement. */
6046 int target_y = it->current_y + h - dy;
6047 int y0 = it3.current_y;
6048 int y1 = line_bottom_y (&it3);
6049 int line_height = y1 - y0;
6050
6051 /* If we did not reach target_y, try to move further backward if
6052 we can. If we moved too far backward, try to move forward. */
6053 if (target_y < it->current_y
6054 /* This is heuristic. In a window that's 3 lines high, with
6055 a line height of 13 pixels each, recentering with point
6056 on the bottom line will try to move -39/2 = 19 pixels
6057 backward. Try to avoid moving into the first line. */
6058 && it->current_y - target_y > line_height / 3 * 2
6059 && IT_CHARPOS (*it) > BEGV)
6060 {
6061 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6062 target_y - it->current_y));
6063 move_it_vertically (it, target_y - it->current_y);
6064 xassert (IT_CHARPOS (*it) >= BEGV);
6065 }
6066 else if (target_y >= it->current_y + line_height
6067 && IT_CHARPOS (*it) < ZV)
6068 {
6069 /* Should move forward by at least one line, maybe more.
6070
6071 Note: Calling move_it_by_lines can be expensive on
6072 terminal frames, where compute_motion is used (via
6073 vmotion) to do the job, when there are very long lines
6074 and truncate-lines is nil. That's the reason for
6075 treating terminal frames specially here. */
6076
6077 if (!FRAME_WINDOW_P (it->f))
6078 move_it_vertically (it, target_y - (it->current_y + line_height));
6079 else
6080 {
6081 do
6082 {
6083 move_it_by_lines (it, 1, 1);
6084 }
6085 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6086 }
6087
6088 xassert (IT_CHARPOS (*it) >= BEGV);
6089 }
6090 }
6091 }
6092
6093
6094 /* Move IT by a specified amount of pixel lines DY. DY negative means
6095 move backwards. DY = 0 means move to start of screen line. At the
6096 end, IT will be on the start of a screen line. */
6097
6098 void
6099 move_it_vertically (it, dy)
6100 struct it *it;
6101 int dy;
6102 {
6103 if (dy <= 0)
6104 move_it_vertically_backward (it, -dy);
6105 else if (dy > 0)
6106 {
6107 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6108 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6109 MOVE_TO_POS | MOVE_TO_Y);
6110 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6111
6112 /* If buffer ends in ZV without a newline, move to the start of
6113 the line to satisfy the post-condition. */
6114 if (IT_CHARPOS (*it) == ZV
6115 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6116 move_it_by_lines (it, 0, 0);
6117 }
6118 }
6119
6120
6121 /* Move iterator IT past the end of the text line it is in. */
6122
6123 void
6124 move_it_past_eol (it)
6125 struct it *it;
6126 {
6127 enum move_it_result rc;
6128
6129 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6130 if (rc == MOVE_NEWLINE_OR_CR)
6131 set_iterator_to_next (it, 0);
6132 }
6133
6134
6135 #if 0 /* Currently not used. */
6136
6137 /* Return non-zero if some text between buffer positions START_CHARPOS
6138 and END_CHARPOS is invisible. IT->window is the window for text
6139 property lookup. */
6140
6141 static int
6142 invisible_text_between_p (it, start_charpos, end_charpos)
6143 struct it *it;
6144 int start_charpos, end_charpos;
6145 {
6146 Lisp_Object prop, limit;
6147 int invisible_found_p;
6148
6149 xassert (it != NULL && start_charpos <= end_charpos);
6150
6151 /* Is text at START invisible? */
6152 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6153 it->window);
6154 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6155 invisible_found_p = 1;
6156 else
6157 {
6158 limit = Fnext_single_char_property_change (make_number (start_charpos),
6159 Qinvisible, Qnil,
6160 make_number (end_charpos));
6161 invisible_found_p = XFASTINT (limit) < end_charpos;
6162 }
6163
6164 return invisible_found_p;
6165 }
6166
6167 #endif /* 0 */
6168
6169
6170 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6171 negative means move up. DVPOS == 0 means move to the start of the
6172 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6173 NEED_Y_P is zero, IT->current_y will be left unchanged.
6174
6175 Further optimization ideas: If we would know that IT->f doesn't use
6176 a face with proportional font, we could be faster for
6177 truncate-lines nil. */
6178
6179 void
6180 move_it_by_lines (it, dvpos, need_y_p)
6181 struct it *it;
6182 int dvpos, need_y_p;
6183 {
6184 struct position pos;
6185
6186 if (!FRAME_WINDOW_P (it->f))
6187 {
6188 struct text_pos textpos;
6189
6190 /* We can use vmotion on frames without proportional fonts. */
6191 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6192 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6193 reseat (it, textpos, 1);
6194 it->vpos += pos.vpos;
6195 it->current_y += pos.vpos;
6196 }
6197 else if (dvpos == 0)
6198 {
6199 /* DVPOS == 0 means move to the start of the screen line. */
6200 move_it_vertically_backward (it, 0);
6201 xassert (it->current_x == 0 && it->hpos == 0);
6202 }
6203 else if (dvpos > 0)
6204 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6205 else
6206 {
6207 struct it it2;
6208 int start_charpos, i;
6209
6210 /* Start at the beginning of the screen line containing IT's
6211 position. */
6212 move_it_vertically_backward (it, 0);
6213
6214 /* Go back -DVPOS visible lines and reseat the iterator there. */
6215 start_charpos = IT_CHARPOS (*it);
6216 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6217 back_to_previous_visible_line_start (it);
6218 reseat (it, it->current.pos, 1);
6219 it->current_x = it->hpos = 0;
6220
6221 /* Above call may have moved too far if continuation lines
6222 are involved. Scan forward and see if it did. */
6223 it2 = *it;
6224 it2.vpos = it2.current_y = 0;
6225 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6226 it->vpos -= it2.vpos;
6227 it->current_y -= it2.current_y;
6228 it->current_x = it->hpos = 0;
6229
6230 /* If we moved too far, move IT some lines forward. */
6231 if (it2.vpos > -dvpos)
6232 {
6233 int delta = it2.vpos + dvpos;
6234 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6235 }
6236 }
6237 }
6238
6239 /* Return 1 if IT points into the middle of a display vector. */
6240
6241 int
6242 in_display_vector_p (it)
6243 struct it *it;
6244 {
6245 return (it->method == next_element_from_display_vector
6246 && it->current.dpvec_index > 0
6247 && it->dpvec + it->current.dpvec_index != it->dpend);
6248 }
6249
6250 \f
6251 /***********************************************************************
6252 Messages
6253 ***********************************************************************/
6254
6255
6256 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6257 to *Messages*. */
6258
6259 void
6260 add_to_log (format, arg1, arg2)
6261 char *format;
6262 Lisp_Object arg1, arg2;
6263 {
6264 Lisp_Object args[3];
6265 Lisp_Object msg, fmt;
6266 char *buffer;
6267 int len;
6268 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6269
6270 /* Do nothing if called asynchronously. Inserting text into
6271 a buffer may call after-change-functions and alike and
6272 that would means running Lisp asynchronously. */
6273 if (handling_signal)
6274 return;
6275
6276 fmt = msg = Qnil;
6277 GCPRO4 (fmt, msg, arg1, arg2);
6278
6279 args[0] = fmt = build_string (format);
6280 args[1] = arg1;
6281 args[2] = arg2;
6282 msg = Fformat (3, args);
6283
6284 len = SBYTES (msg) + 1;
6285 buffer = (char *) alloca (len);
6286 bcopy (SDATA (msg), buffer, len);
6287
6288 message_dolog (buffer, len - 1, 1, 0);
6289 UNGCPRO;
6290 }
6291
6292
6293 /* Output a newline in the *Messages* buffer if "needs" one. */
6294
6295 void
6296 message_log_maybe_newline ()
6297 {
6298 if (message_log_need_newline)
6299 message_dolog ("", 0, 1, 0);
6300 }
6301
6302
6303 /* Add a string M of length NBYTES to the message log, optionally
6304 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6305 nonzero, means interpret the contents of M as multibyte. This
6306 function calls low-level routines in order to bypass text property
6307 hooks, etc. which might not be safe to run. */
6308
6309 void
6310 message_dolog (m, nbytes, nlflag, multibyte)
6311 const char *m;
6312 int nbytes, nlflag, multibyte;
6313 {
6314 if (!NILP (Vmemory_full))
6315 return;
6316
6317 if (!NILP (Vmessage_log_max))
6318 {
6319 struct buffer *oldbuf;
6320 Lisp_Object oldpoint, oldbegv, oldzv;
6321 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6322 int point_at_end = 0;
6323 int zv_at_end = 0;
6324 Lisp_Object old_deactivate_mark, tem;
6325 struct gcpro gcpro1;
6326
6327 old_deactivate_mark = Vdeactivate_mark;
6328 oldbuf = current_buffer;
6329 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6330 current_buffer->undo_list = Qt;
6331
6332 oldpoint = message_dolog_marker1;
6333 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6334 oldbegv = message_dolog_marker2;
6335 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6336 oldzv = message_dolog_marker3;
6337 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6338 GCPRO1 (old_deactivate_mark);
6339
6340 if (PT == Z)
6341 point_at_end = 1;
6342 if (ZV == Z)
6343 zv_at_end = 1;
6344
6345 BEGV = BEG;
6346 BEGV_BYTE = BEG_BYTE;
6347 ZV = Z;
6348 ZV_BYTE = Z_BYTE;
6349 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6350
6351 /* Insert the string--maybe converting multibyte to single byte
6352 or vice versa, so that all the text fits the buffer. */
6353 if (multibyte
6354 && NILP (current_buffer->enable_multibyte_characters))
6355 {
6356 int i, c, char_bytes;
6357 unsigned char work[1];
6358
6359 /* Convert a multibyte string to single-byte
6360 for the *Message* buffer. */
6361 for (i = 0; i < nbytes; i += char_bytes)
6362 {
6363 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6364 work[0] = (SINGLE_BYTE_CHAR_P (c)
6365 ? c
6366 : multibyte_char_to_unibyte (c, Qnil));
6367 insert_1_both (work, 1, 1, 1, 0, 0);
6368 }
6369 }
6370 else if (! multibyte
6371 && ! NILP (current_buffer->enable_multibyte_characters))
6372 {
6373 int i, c, char_bytes;
6374 unsigned char *msg = (unsigned char *) m;
6375 unsigned char str[MAX_MULTIBYTE_LENGTH];
6376 /* Convert a single-byte string to multibyte
6377 for the *Message* buffer. */
6378 for (i = 0; i < nbytes; i++)
6379 {
6380 c = unibyte_char_to_multibyte (msg[i]);
6381 char_bytes = CHAR_STRING (c, str);
6382 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6383 }
6384 }
6385 else if (nbytes)
6386 insert_1 (m, nbytes, 1, 0, 0);
6387
6388 if (nlflag)
6389 {
6390 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6391 insert_1 ("\n", 1, 1, 0, 0);
6392
6393 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6394 this_bol = PT;
6395 this_bol_byte = PT_BYTE;
6396
6397 /* See if this line duplicates the previous one.
6398 If so, combine duplicates. */
6399 if (this_bol > BEG)
6400 {
6401 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6402 prev_bol = PT;
6403 prev_bol_byte = PT_BYTE;
6404
6405 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6406 this_bol, this_bol_byte);
6407 if (dup)
6408 {
6409 del_range_both (prev_bol, prev_bol_byte,
6410 this_bol, this_bol_byte, 0);
6411 if (dup > 1)
6412 {
6413 char dupstr[40];
6414 int duplen;
6415
6416 /* If you change this format, don't forget to also
6417 change message_log_check_duplicate. */
6418 sprintf (dupstr, " [%d times]", dup);
6419 duplen = strlen (dupstr);
6420 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6421 insert_1 (dupstr, duplen, 1, 0, 1);
6422 }
6423 }
6424 }
6425
6426 /* If we have more than the desired maximum number of lines
6427 in the *Messages* buffer now, delete the oldest ones.
6428 This is safe because we don't have undo in this buffer. */
6429
6430 if (NATNUMP (Vmessage_log_max))
6431 {
6432 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6433 -XFASTINT (Vmessage_log_max) - 1, 0);
6434 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6435 }
6436 }
6437 BEGV = XMARKER (oldbegv)->charpos;
6438 BEGV_BYTE = marker_byte_position (oldbegv);
6439
6440 if (zv_at_end)
6441 {
6442 ZV = Z;
6443 ZV_BYTE = Z_BYTE;
6444 }
6445 else
6446 {
6447 ZV = XMARKER (oldzv)->charpos;
6448 ZV_BYTE = marker_byte_position (oldzv);
6449 }
6450
6451 if (point_at_end)
6452 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6453 else
6454 /* We can't do Fgoto_char (oldpoint) because it will run some
6455 Lisp code. */
6456 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6457 XMARKER (oldpoint)->bytepos);
6458
6459 UNGCPRO;
6460 unchain_marker (XMARKER (oldpoint));
6461 unchain_marker (XMARKER (oldbegv));
6462 unchain_marker (XMARKER (oldzv));
6463
6464 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6465 set_buffer_internal (oldbuf);
6466 if (NILP (tem))
6467 windows_or_buffers_changed = old_windows_or_buffers_changed;
6468 message_log_need_newline = !nlflag;
6469 Vdeactivate_mark = old_deactivate_mark;
6470 }
6471 }
6472
6473
6474 /* We are at the end of the buffer after just having inserted a newline.
6475 (Note: We depend on the fact we won't be crossing the gap.)
6476 Check to see if the most recent message looks a lot like the previous one.
6477 Return 0 if different, 1 if the new one should just replace it, or a
6478 value N > 1 if we should also append " [N times]". */
6479
6480 static int
6481 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6482 int prev_bol, this_bol;
6483 int prev_bol_byte, this_bol_byte;
6484 {
6485 int i;
6486 int len = Z_BYTE - 1 - this_bol_byte;
6487 int seen_dots = 0;
6488 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6489 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6490
6491 for (i = 0; i < len; i++)
6492 {
6493 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6494 seen_dots = 1;
6495 if (p1[i] != p2[i])
6496 return seen_dots;
6497 }
6498 p1 += len;
6499 if (*p1 == '\n')
6500 return 2;
6501 if (*p1++ == ' ' && *p1++ == '[')
6502 {
6503 int n = 0;
6504 while (*p1 >= '0' && *p1 <= '9')
6505 n = n * 10 + *p1++ - '0';
6506 if (strncmp (p1, " times]\n", 8) == 0)
6507 return n+1;
6508 }
6509 return 0;
6510 }
6511
6512
6513 /* Display an echo area message M with a specified length of NBYTES
6514 bytes. The string may include null characters. If M is 0, clear
6515 out any existing message, and let the mini-buffer text show
6516 through.
6517
6518 The buffer M must continue to exist until after the echo area gets
6519 cleared or some other message gets displayed there. This means do
6520 not pass text that is stored in a Lisp string; do not pass text in
6521 a buffer that was alloca'd. */
6522
6523 void
6524 message2 (m, nbytes, multibyte)
6525 const char *m;
6526 int nbytes;
6527 int multibyte;
6528 {
6529 /* First flush out any partial line written with print. */
6530 message_log_maybe_newline ();
6531 if (m)
6532 message_dolog (m, nbytes, 1, multibyte);
6533 message2_nolog (m, nbytes, multibyte);
6534 }
6535
6536
6537 /* The non-logging counterpart of message2. */
6538
6539 void
6540 message2_nolog (m, nbytes, multibyte)
6541 const char *m;
6542 int nbytes, multibyte;
6543 {
6544 struct frame *sf = SELECTED_FRAME ();
6545 message_enable_multibyte = multibyte;
6546
6547 if (noninteractive)
6548 {
6549 if (noninteractive_need_newline)
6550 putc ('\n', stderr);
6551 noninteractive_need_newline = 0;
6552 if (m)
6553 fwrite (m, nbytes, 1, stderr);
6554 if (cursor_in_echo_area == 0)
6555 fprintf (stderr, "\n");
6556 fflush (stderr);
6557 }
6558 /* A null message buffer means that the frame hasn't really been
6559 initialized yet. Error messages get reported properly by
6560 cmd_error, so this must be just an informative message; toss it. */
6561 else if (INTERACTIVE
6562 && sf->glyphs_initialized_p
6563 && FRAME_MESSAGE_BUF (sf))
6564 {
6565 Lisp_Object mini_window;
6566 struct frame *f;
6567
6568 /* Get the frame containing the mini-buffer
6569 that the selected frame is using. */
6570 mini_window = FRAME_MINIBUF_WINDOW (sf);
6571 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6572
6573 FRAME_SAMPLE_VISIBILITY (f);
6574 if (FRAME_VISIBLE_P (sf)
6575 && ! FRAME_VISIBLE_P (f))
6576 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6577
6578 if (m)
6579 {
6580 set_message (m, Qnil, nbytes, multibyte);
6581 if (minibuffer_auto_raise)
6582 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6583 }
6584 else
6585 clear_message (1, 1);
6586
6587 do_pending_window_change (0);
6588 echo_area_display (1);
6589 do_pending_window_change (0);
6590 if (FRAME_DISPLAY (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
6591 (*FRAME_DISPLAY (f)->frame_up_to_date_hook) (f);
6592 }
6593 }
6594
6595
6596 /* Display an echo area message M with a specified length of NBYTES
6597 bytes. The string may include null characters. If M is not a
6598 string, clear out any existing message, and let the mini-buffer
6599 text show through. */
6600
6601 void
6602 message3 (m, nbytes, multibyte)
6603 Lisp_Object m;
6604 int nbytes;
6605 int multibyte;
6606 {
6607 struct gcpro gcpro1;
6608
6609 GCPRO1 (m);
6610
6611 /* First flush out any partial line written with print. */
6612 message_log_maybe_newline ();
6613 if (STRINGP (m))
6614 message_dolog (SDATA (m), nbytes, 1, multibyte);
6615 message3_nolog (m, nbytes, multibyte);
6616
6617 UNGCPRO;
6618 }
6619
6620
6621 /* The non-logging version of message3. */
6622
6623 void
6624 message3_nolog (m, nbytes, multibyte)
6625 Lisp_Object m;
6626 int nbytes, multibyte;
6627 {
6628 struct frame *sf = SELECTED_FRAME ();
6629 message_enable_multibyte = multibyte;
6630
6631 if (noninteractive)
6632 {
6633 if (noninteractive_need_newline)
6634 putc ('\n', stderr);
6635 noninteractive_need_newline = 0;
6636 if (STRINGP (m))
6637 fwrite (SDATA (m), nbytes, 1, stderr);
6638 if (cursor_in_echo_area == 0)
6639 fprintf (stderr, "\n");
6640 fflush (stderr);
6641 }
6642 /* A null message buffer means that the frame hasn't really been
6643 initialized yet. Error messages get reported properly by
6644 cmd_error, so this must be just an informative message; toss it. */
6645 else if (INTERACTIVE
6646 && sf->glyphs_initialized_p
6647 && FRAME_MESSAGE_BUF (sf))
6648 {
6649 Lisp_Object mini_window;
6650 Lisp_Object frame;
6651 struct frame *f;
6652
6653 /* Get the frame containing the mini-buffer
6654 that the selected frame is using. */
6655 mini_window = FRAME_MINIBUF_WINDOW (sf);
6656 frame = XWINDOW (mini_window)->frame;
6657 f = XFRAME (frame);
6658
6659 FRAME_SAMPLE_VISIBILITY (f);
6660 if (FRAME_VISIBLE_P (sf)
6661 && !FRAME_VISIBLE_P (f))
6662 Fmake_frame_visible (frame);
6663
6664 if (STRINGP (m) && SCHARS (m) > 0)
6665 {
6666 set_message (NULL, m, nbytes, multibyte);
6667 if (minibuffer_auto_raise)
6668 Fraise_frame (frame);
6669 }
6670 else
6671 clear_message (1, 1);
6672
6673 do_pending_window_change (0);
6674 echo_area_display (1);
6675 do_pending_window_change (0);
6676 if (FRAME_DISPLAY (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
6677 (*FRAME_DISPLAY (f)->frame_up_to_date_hook) (f);
6678 }
6679 }
6680
6681
6682 /* Display a null-terminated echo area message M. If M is 0, clear
6683 out any existing message, and let the mini-buffer text show through.
6684
6685 The buffer M must continue to exist until after the echo area gets
6686 cleared or some other message gets displayed there. Do not pass
6687 text that is stored in a Lisp string. Do not pass text in a buffer
6688 that was alloca'd. */
6689
6690 void
6691 message1 (m)
6692 char *m;
6693 {
6694 message2 (m, (m ? strlen (m) : 0), 0);
6695 }
6696
6697
6698 /* The non-logging counterpart of message1. */
6699
6700 void
6701 message1_nolog (m)
6702 char *m;
6703 {
6704 message2_nolog (m, (m ? strlen (m) : 0), 0);
6705 }
6706
6707 /* Display a message M which contains a single %s
6708 which gets replaced with STRING. */
6709
6710 void
6711 message_with_string (m, string, log)
6712 char *m;
6713 Lisp_Object string;
6714 int log;
6715 {
6716 CHECK_STRING (string);
6717
6718 if (noninteractive)
6719 {
6720 if (m)
6721 {
6722 if (noninteractive_need_newline)
6723 putc ('\n', stderr);
6724 noninteractive_need_newline = 0;
6725 fprintf (stderr, m, SDATA (string));
6726 if (cursor_in_echo_area == 0)
6727 fprintf (stderr, "\n");
6728 fflush (stderr);
6729 }
6730 }
6731 else if (INTERACTIVE)
6732 {
6733 /* The frame whose minibuffer we're going to display the message on.
6734 It may be larger than the selected frame, so we need
6735 to use its buffer, not the selected frame's buffer. */
6736 Lisp_Object mini_window;
6737 struct frame *f, *sf = SELECTED_FRAME ();
6738
6739 /* Get the frame containing the minibuffer
6740 that the selected frame is using. */
6741 mini_window = FRAME_MINIBUF_WINDOW (sf);
6742 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6743
6744 /* A null message buffer means that the frame hasn't really been
6745 initialized yet. Error messages get reported properly by
6746 cmd_error, so this must be just an informative message; toss it. */
6747 if (FRAME_MESSAGE_BUF (f))
6748 {
6749 Lisp_Object args[2], message;
6750 struct gcpro gcpro1, gcpro2;
6751
6752 args[0] = build_string (m);
6753 args[1] = message = string;
6754 GCPRO2 (args[0], message);
6755 gcpro1.nvars = 2;
6756
6757 message = Fformat (2, args);
6758
6759 if (log)
6760 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6761 else
6762 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6763
6764 UNGCPRO;
6765
6766 /* Print should start at the beginning of the message
6767 buffer next time. */
6768 message_buf_print = 0;
6769 }
6770 }
6771 }
6772
6773
6774 /* Dump an informative message to the minibuf. If M is 0, clear out
6775 any existing message, and let the mini-buffer text show through. */
6776
6777 /* VARARGS 1 */
6778 void
6779 message (m, a1, a2, a3)
6780 char *m;
6781 EMACS_INT a1, a2, a3;
6782 {
6783 if (noninteractive)
6784 {
6785 if (m)
6786 {
6787 if (noninteractive_need_newline)
6788 putc ('\n', stderr);
6789 noninteractive_need_newline = 0;
6790 fprintf (stderr, m, a1, a2, a3);
6791 if (cursor_in_echo_area == 0)
6792 fprintf (stderr, "\n");
6793 fflush (stderr);
6794 }
6795 }
6796 else if (INTERACTIVE)
6797 {
6798 /* The frame whose mini-buffer we're going to display the message
6799 on. It may be larger than the selected frame, so we need to
6800 use its buffer, not the selected frame's buffer. */
6801 Lisp_Object mini_window;
6802 struct frame *f, *sf = SELECTED_FRAME ();
6803
6804 /* Get the frame containing the mini-buffer
6805 that the selected frame is using. */
6806 mini_window = FRAME_MINIBUF_WINDOW (sf);
6807 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6808
6809 /* A null message buffer means that the frame hasn't really been
6810 initialized yet. Error messages get reported properly by
6811 cmd_error, so this must be just an informative message; toss
6812 it. */
6813 if (FRAME_MESSAGE_BUF (f))
6814 {
6815 if (m)
6816 {
6817 int len;
6818 #ifdef NO_ARG_ARRAY
6819 char *a[3];
6820 a[0] = (char *) a1;
6821 a[1] = (char *) a2;
6822 a[2] = (char *) a3;
6823
6824 len = doprnt (FRAME_MESSAGE_BUF (f),
6825 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6826 #else
6827 len = doprnt (FRAME_MESSAGE_BUF (f),
6828 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6829 (char **) &a1);
6830 #endif /* NO_ARG_ARRAY */
6831
6832 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6833 }
6834 else
6835 message1 (0);
6836
6837 /* Print should start at the beginning of the message
6838 buffer next time. */
6839 message_buf_print = 0;
6840 }
6841 }
6842 }
6843
6844
6845 /* The non-logging version of message. */
6846
6847 void
6848 message_nolog (m, a1, a2, a3)
6849 char *m;
6850 EMACS_INT a1, a2, a3;
6851 {
6852 Lisp_Object old_log_max;
6853 old_log_max = Vmessage_log_max;
6854 Vmessage_log_max = Qnil;
6855 message (m, a1, a2, a3);
6856 Vmessage_log_max = old_log_max;
6857 }
6858
6859
6860 /* Display the current message in the current mini-buffer. This is
6861 only called from error handlers in process.c, and is not time
6862 critical. */
6863
6864 void
6865 update_echo_area ()
6866 {
6867 if (!NILP (echo_area_buffer[0]))
6868 {
6869 Lisp_Object string;
6870 string = Fcurrent_message ();
6871 message3 (string, SBYTES (string),
6872 !NILP (current_buffer->enable_multibyte_characters));
6873 }
6874 }
6875
6876
6877 /* Make sure echo area buffers in `echo_buffers' are live.
6878 If they aren't, make new ones. */
6879
6880 static void
6881 ensure_echo_area_buffers ()
6882 {
6883 int i;
6884
6885 for (i = 0; i < 2; ++i)
6886 if (!BUFFERP (echo_buffer[i])
6887 || NILP (XBUFFER (echo_buffer[i])->name))
6888 {
6889 char name[30];
6890 Lisp_Object old_buffer;
6891 int j;
6892
6893 old_buffer = echo_buffer[i];
6894 sprintf (name, " *Echo Area %d*", i);
6895 echo_buffer[i] = Fget_buffer_create (build_string (name));
6896 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6897
6898 for (j = 0; j < 2; ++j)
6899 if (EQ (old_buffer, echo_area_buffer[j]))
6900 echo_area_buffer[j] = echo_buffer[i];
6901 }
6902 }
6903
6904
6905 /* Call FN with args A1..A4 with either the current or last displayed
6906 echo_area_buffer as current buffer.
6907
6908 WHICH zero means use the current message buffer
6909 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6910 from echo_buffer[] and clear it.
6911
6912 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6913 suitable buffer from echo_buffer[] and clear it.
6914
6915 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6916 that the current message becomes the last displayed one, make
6917 choose a suitable buffer for echo_area_buffer[0], and clear it.
6918
6919 Value is what FN returns. */
6920
6921 static int
6922 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6923 struct window *w;
6924 int which;
6925 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6926 EMACS_INT a1;
6927 Lisp_Object a2;
6928 EMACS_INT a3, a4;
6929 {
6930 Lisp_Object buffer;
6931 int this_one, the_other, clear_buffer_p, rc;
6932 int count = SPECPDL_INDEX ();
6933
6934 /* If buffers aren't live, make new ones. */
6935 ensure_echo_area_buffers ();
6936
6937 clear_buffer_p = 0;
6938
6939 if (which == 0)
6940 this_one = 0, the_other = 1;
6941 else if (which > 0)
6942 this_one = 1, the_other = 0;
6943 else
6944 {
6945 this_one = 0, the_other = 1;
6946 clear_buffer_p = 1;
6947
6948 /* We need a fresh one in case the current echo buffer equals
6949 the one containing the last displayed echo area message. */
6950 if (!NILP (echo_area_buffer[this_one])
6951 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6952 echo_area_buffer[this_one] = Qnil;
6953 }
6954
6955 /* Choose a suitable buffer from echo_buffer[] is we don't
6956 have one. */
6957 if (NILP (echo_area_buffer[this_one]))
6958 {
6959 echo_area_buffer[this_one]
6960 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6961 ? echo_buffer[the_other]
6962 : echo_buffer[this_one]);
6963 clear_buffer_p = 1;
6964 }
6965
6966 buffer = echo_area_buffer[this_one];
6967
6968 /* Don't get confused by reusing the buffer used for echoing
6969 for a different purpose. */
6970 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6971 cancel_echoing ();
6972
6973 record_unwind_protect (unwind_with_echo_area_buffer,
6974 with_echo_area_buffer_unwind_data (w));
6975
6976 /* Make the echo area buffer current. Note that for display
6977 purposes, it is not necessary that the displayed window's buffer
6978 == current_buffer, except for text property lookup. So, let's
6979 only set that buffer temporarily here without doing a full
6980 Fset_window_buffer. We must also change w->pointm, though,
6981 because otherwise an assertions in unshow_buffer fails, and Emacs
6982 aborts. */
6983 set_buffer_internal_1 (XBUFFER (buffer));
6984 if (w)
6985 {
6986 w->buffer = buffer;
6987 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6988 }
6989
6990 current_buffer->undo_list = Qt;
6991 current_buffer->read_only = Qnil;
6992 specbind (Qinhibit_read_only, Qt);
6993 specbind (Qinhibit_modification_hooks, Qt);
6994
6995 if (clear_buffer_p && Z > BEG)
6996 del_range (BEG, Z);
6997
6998 xassert (BEGV >= BEG);
6999 xassert (ZV <= Z && ZV >= BEGV);
7000
7001 rc = fn (a1, a2, a3, a4);
7002
7003 xassert (BEGV >= BEG);
7004 xassert (ZV <= Z && ZV >= BEGV);
7005
7006 unbind_to (count, Qnil);
7007 return rc;
7008 }
7009
7010
7011 /* Save state that should be preserved around the call to the function
7012 FN called in with_echo_area_buffer. */
7013
7014 static Lisp_Object
7015 with_echo_area_buffer_unwind_data (w)
7016 struct window *w;
7017 {
7018 int i = 0;
7019 Lisp_Object vector;
7020
7021 /* Reduce consing by keeping one vector in
7022 Vwith_echo_area_save_vector. */
7023 vector = Vwith_echo_area_save_vector;
7024 Vwith_echo_area_save_vector = Qnil;
7025
7026 if (NILP (vector))
7027 vector = Fmake_vector (make_number (7), Qnil);
7028
7029 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7030 AREF (vector, i) = Vdeactivate_mark, ++i;
7031 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7032
7033 if (w)
7034 {
7035 XSETWINDOW (AREF (vector, i), w); ++i;
7036 AREF (vector, i) = w->buffer; ++i;
7037 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7038 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7039 }
7040 else
7041 {
7042 int end = i + 4;
7043 for (; i < end; ++i)
7044 AREF (vector, i) = Qnil;
7045 }
7046
7047 xassert (i == ASIZE (vector));
7048 return vector;
7049 }
7050
7051
7052 /* Restore global state from VECTOR which was created by
7053 with_echo_area_buffer_unwind_data. */
7054
7055 static Lisp_Object
7056 unwind_with_echo_area_buffer (vector)
7057 Lisp_Object vector;
7058 {
7059 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7060 Vdeactivate_mark = AREF (vector, 1);
7061 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7062
7063 if (WINDOWP (AREF (vector, 3)))
7064 {
7065 struct window *w;
7066 Lisp_Object buffer, charpos, bytepos;
7067
7068 w = XWINDOW (AREF (vector, 3));
7069 buffer = AREF (vector, 4);
7070 charpos = AREF (vector, 5);
7071 bytepos = AREF (vector, 6);
7072
7073 w->buffer = buffer;
7074 set_marker_both (w->pointm, buffer,
7075 XFASTINT (charpos), XFASTINT (bytepos));
7076 }
7077
7078 Vwith_echo_area_save_vector = vector;
7079 return Qnil;
7080 }
7081
7082
7083 /* Set up the echo area for use by print functions. MULTIBYTE_P
7084 non-zero means we will print multibyte. */
7085
7086 void
7087 setup_echo_area_for_printing (multibyte_p)
7088 int multibyte_p;
7089 {
7090 /* If we can't find an echo area any more, exit. */
7091 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7092 Fkill_emacs (Qnil);
7093
7094 ensure_echo_area_buffers ();
7095
7096 if (!message_buf_print)
7097 {
7098 /* A message has been output since the last time we printed.
7099 Choose a fresh echo area buffer. */
7100 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7101 echo_area_buffer[0] = echo_buffer[1];
7102 else
7103 echo_area_buffer[0] = echo_buffer[0];
7104
7105 /* Switch to that buffer and clear it. */
7106 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7107 current_buffer->truncate_lines = Qnil;
7108
7109 if (Z > BEG)
7110 {
7111 int count = SPECPDL_INDEX ();
7112 specbind (Qinhibit_read_only, Qt);
7113 /* Note that undo recording is always disabled. */
7114 del_range (BEG, Z);
7115 unbind_to (count, Qnil);
7116 }
7117 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7118
7119 /* Set up the buffer for the multibyteness we need. */
7120 if (multibyte_p
7121 != !NILP (current_buffer->enable_multibyte_characters))
7122 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7123
7124 /* Raise the frame containing the echo area. */
7125 if (minibuffer_auto_raise)
7126 {
7127 struct frame *sf = SELECTED_FRAME ();
7128 Lisp_Object mini_window;
7129 mini_window = FRAME_MINIBUF_WINDOW (sf);
7130 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7131 }
7132
7133 message_log_maybe_newline ();
7134 message_buf_print = 1;
7135 }
7136 else
7137 {
7138 if (NILP (echo_area_buffer[0]))
7139 {
7140 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7141 echo_area_buffer[0] = echo_buffer[1];
7142 else
7143 echo_area_buffer[0] = echo_buffer[0];
7144 }
7145
7146 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7147 {
7148 /* Someone switched buffers between print requests. */
7149 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7150 current_buffer->truncate_lines = Qnil;
7151 }
7152 }
7153 }
7154
7155
7156 /* Display an echo area message in window W. Value is non-zero if W's
7157 height is changed. If display_last_displayed_message_p is
7158 non-zero, display the message that was last displayed, otherwise
7159 display the current message. */
7160
7161 static int
7162 display_echo_area (w)
7163 struct window *w;
7164 {
7165 int i, no_message_p, window_height_changed_p, count;
7166
7167 /* Temporarily disable garbage collections while displaying the echo
7168 area. This is done because a GC can print a message itself.
7169 That message would modify the echo area buffer's contents while a
7170 redisplay of the buffer is going on, and seriously confuse
7171 redisplay. */
7172 count = inhibit_garbage_collection ();
7173
7174 /* If there is no message, we must call display_echo_area_1
7175 nevertheless because it resizes the window. But we will have to
7176 reset the echo_area_buffer in question to nil at the end because
7177 with_echo_area_buffer will sets it to an empty buffer. */
7178 i = display_last_displayed_message_p ? 1 : 0;
7179 no_message_p = NILP (echo_area_buffer[i]);
7180
7181 window_height_changed_p
7182 = with_echo_area_buffer (w, display_last_displayed_message_p,
7183 display_echo_area_1,
7184 (EMACS_INT) w, Qnil, 0, 0);
7185
7186 if (no_message_p)
7187 echo_area_buffer[i] = Qnil;
7188
7189 unbind_to (count, Qnil);
7190 return window_height_changed_p;
7191 }
7192
7193
7194 /* Helper for display_echo_area. Display the current buffer which
7195 contains the current echo area message in window W, a mini-window,
7196 a pointer to which is passed in A1. A2..A4 are currently not used.
7197 Change the height of W so that all of the message is displayed.
7198 Value is non-zero if height of W was changed. */
7199
7200 static int
7201 display_echo_area_1 (a1, a2, a3, a4)
7202 EMACS_INT a1;
7203 Lisp_Object a2;
7204 EMACS_INT a3, a4;
7205 {
7206 struct window *w = (struct window *) a1;
7207 Lisp_Object window;
7208 struct text_pos start;
7209 int window_height_changed_p = 0;
7210
7211 /* Do this before displaying, so that we have a large enough glyph
7212 matrix for the display. */
7213 window_height_changed_p = resize_mini_window (w, 0);
7214
7215 /* Display. */
7216 clear_glyph_matrix (w->desired_matrix);
7217 XSETWINDOW (window, w);
7218 SET_TEXT_POS (start, BEG, BEG_BYTE);
7219 try_window (window, start);
7220
7221 return window_height_changed_p;
7222 }
7223
7224
7225 /* Resize the echo area window to exactly the size needed for the
7226 currently displayed message, if there is one. If a mini-buffer
7227 is active, don't shrink it. */
7228
7229 void
7230 resize_echo_area_exactly ()
7231 {
7232 if (BUFFERP (echo_area_buffer[0])
7233 && WINDOWP (echo_area_window))
7234 {
7235 struct window *w = XWINDOW (echo_area_window);
7236 int resized_p;
7237 Lisp_Object resize_exactly;
7238
7239 if (minibuf_level == 0)
7240 resize_exactly = Qt;
7241 else
7242 resize_exactly = Qnil;
7243
7244 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7245 (EMACS_INT) w, resize_exactly, 0, 0);
7246 if (resized_p)
7247 {
7248 ++windows_or_buffers_changed;
7249 ++update_mode_lines;
7250 redisplay_internal (0);
7251 }
7252 }
7253 }
7254
7255
7256 /* Callback function for with_echo_area_buffer, when used from
7257 resize_echo_area_exactly. A1 contains a pointer to the window to
7258 resize, EXACTLY non-nil means resize the mini-window exactly to the
7259 size of the text displayed. A3 and A4 are not used. Value is what
7260 resize_mini_window returns. */
7261
7262 static int
7263 resize_mini_window_1 (a1, exactly, a3, a4)
7264 EMACS_INT a1;
7265 Lisp_Object exactly;
7266 EMACS_INT a3, a4;
7267 {
7268 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7269 }
7270
7271
7272 /* Resize mini-window W to fit the size of its contents. EXACT:P
7273 means size the window exactly to the size needed. Otherwise, it's
7274 only enlarged until W's buffer is empty. Value is non-zero if
7275 the window height has been changed. */
7276
7277 int
7278 resize_mini_window (w, exact_p)
7279 struct window *w;
7280 int exact_p;
7281 {
7282 struct frame *f = XFRAME (w->frame);
7283 int window_height_changed_p = 0;
7284
7285 xassert (MINI_WINDOW_P (w));
7286
7287 /* Don't resize windows while redisplaying a window; it would
7288 confuse redisplay functions when the size of the window they are
7289 displaying changes from under them. Such a resizing can happen,
7290 for instance, when which-func prints a long message while
7291 we are running fontification-functions. We're running these
7292 functions with safe_call which binds inhibit-redisplay to t. */
7293 if (!NILP (Vinhibit_redisplay))
7294 return 0;
7295
7296 /* Nil means don't try to resize. */
7297 if (NILP (Vresize_mini_windows)
7298 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7299 return 0;
7300
7301 if (!FRAME_MINIBUF_ONLY_P (f))
7302 {
7303 struct it it;
7304 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7305 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7306 int height, max_height;
7307 int unit = FRAME_LINE_HEIGHT (f);
7308 struct text_pos start;
7309 struct buffer *old_current_buffer = NULL;
7310
7311 if (current_buffer != XBUFFER (w->buffer))
7312 {
7313 old_current_buffer = current_buffer;
7314 set_buffer_internal (XBUFFER (w->buffer));
7315 }
7316
7317 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7318
7319 /* Compute the max. number of lines specified by the user. */
7320 if (FLOATP (Vmax_mini_window_height))
7321 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7322 else if (INTEGERP (Vmax_mini_window_height))
7323 max_height = XINT (Vmax_mini_window_height);
7324 else
7325 max_height = total_height / 4;
7326
7327 /* Correct that max. height if it's bogus. */
7328 max_height = max (1, max_height);
7329 max_height = min (total_height, max_height);
7330
7331 /* Find out the height of the text in the window. */
7332 if (it.truncate_lines_p)
7333 height = 1;
7334 else
7335 {
7336 last_height = 0;
7337 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7338 if (it.max_ascent == 0 && it.max_descent == 0)
7339 height = it.current_y + last_height;
7340 else
7341 height = it.current_y + it.max_ascent + it.max_descent;
7342 height -= it.extra_line_spacing;
7343 height = (height + unit - 1) / unit;
7344 }
7345
7346 /* Compute a suitable window start. */
7347 if (height > max_height)
7348 {
7349 height = max_height;
7350 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7351 move_it_vertically_backward (&it, (height - 1) * unit);
7352 start = it.current.pos;
7353 }
7354 else
7355 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7356 SET_MARKER_FROM_TEXT_POS (w->start, start);
7357
7358 if (EQ (Vresize_mini_windows, Qgrow_only))
7359 {
7360 /* Let it grow only, until we display an empty message, in which
7361 case the window shrinks again. */
7362 if (height > WINDOW_TOTAL_LINES (w))
7363 {
7364 int old_height = WINDOW_TOTAL_LINES (w);
7365 freeze_window_starts (f, 1);
7366 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7367 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7368 }
7369 else if (height < WINDOW_TOTAL_LINES (w)
7370 && (exact_p || BEGV == ZV))
7371 {
7372 int old_height = WINDOW_TOTAL_LINES (w);
7373 freeze_window_starts (f, 0);
7374 shrink_mini_window (w);
7375 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7376 }
7377 }
7378 else
7379 {
7380 /* Always resize to exact size needed. */
7381 if (height > WINDOW_TOTAL_LINES (w))
7382 {
7383 int old_height = WINDOW_TOTAL_LINES (w);
7384 freeze_window_starts (f, 1);
7385 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7386 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7387 }
7388 else if (height < WINDOW_TOTAL_LINES (w))
7389 {
7390 int old_height = WINDOW_TOTAL_LINES (w);
7391 freeze_window_starts (f, 0);
7392 shrink_mini_window (w);
7393
7394 if (height)
7395 {
7396 freeze_window_starts (f, 1);
7397 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7398 }
7399
7400 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7401 }
7402 }
7403
7404 if (old_current_buffer)
7405 set_buffer_internal (old_current_buffer);
7406 }
7407
7408 return window_height_changed_p;
7409 }
7410
7411
7412 /* Value is the current message, a string, or nil if there is no
7413 current message. */
7414
7415 Lisp_Object
7416 current_message ()
7417 {
7418 Lisp_Object msg;
7419
7420 if (NILP (echo_area_buffer[0]))
7421 msg = Qnil;
7422 else
7423 {
7424 with_echo_area_buffer (0, 0, current_message_1,
7425 (EMACS_INT) &msg, Qnil, 0, 0);
7426 if (NILP (msg))
7427 echo_area_buffer[0] = Qnil;
7428 }
7429
7430 return msg;
7431 }
7432
7433
7434 static int
7435 current_message_1 (a1, a2, a3, a4)
7436 EMACS_INT a1;
7437 Lisp_Object a2;
7438 EMACS_INT a3, a4;
7439 {
7440 Lisp_Object *msg = (Lisp_Object *) a1;
7441
7442 if (Z > BEG)
7443 *msg = make_buffer_string (BEG, Z, 1);
7444 else
7445 *msg = Qnil;
7446 return 0;
7447 }
7448
7449
7450 /* Push the current message on Vmessage_stack for later restauration
7451 by restore_message. Value is non-zero if the current message isn't
7452 empty. This is a relatively infrequent operation, so it's not
7453 worth optimizing. */
7454
7455 int
7456 push_message ()
7457 {
7458 Lisp_Object msg;
7459 msg = current_message ();
7460 Vmessage_stack = Fcons (msg, Vmessage_stack);
7461 return STRINGP (msg);
7462 }
7463
7464
7465 /* Restore message display from the top of Vmessage_stack. */
7466
7467 void
7468 restore_message ()
7469 {
7470 Lisp_Object msg;
7471
7472 xassert (CONSP (Vmessage_stack));
7473 msg = XCAR (Vmessage_stack);
7474 if (STRINGP (msg))
7475 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7476 else
7477 message3_nolog (msg, 0, 0);
7478 }
7479
7480
7481 /* Handler for record_unwind_protect calling pop_message. */
7482
7483 Lisp_Object
7484 pop_message_unwind (dummy)
7485 Lisp_Object dummy;
7486 {
7487 pop_message ();
7488 return Qnil;
7489 }
7490
7491 /* Pop the top-most entry off Vmessage_stack. */
7492
7493 void
7494 pop_message ()
7495 {
7496 xassert (CONSP (Vmessage_stack));
7497 Vmessage_stack = XCDR (Vmessage_stack);
7498 }
7499
7500
7501 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7502 exits. If the stack is not empty, we have a missing pop_message
7503 somewhere. */
7504
7505 void
7506 check_message_stack ()
7507 {
7508 if (!NILP (Vmessage_stack))
7509 abort ();
7510 }
7511
7512
7513 /* Truncate to NCHARS what will be displayed in the echo area the next
7514 time we display it---but don't redisplay it now. */
7515
7516 void
7517 truncate_echo_area (nchars)
7518 int nchars;
7519 {
7520 if (nchars == 0)
7521 echo_area_buffer[0] = Qnil;
7522 /* A null message buffer means that the frame hasn't really been
7523 initialized yet. Error messages get reported properly by
7524 cmd_error, so this must be just an informative message; toss it. */
7525 else if (!noninteractive
7526 && INTERACTIVE
7527 && !NILP (echo_area_buffer[0]))
7528 {
7529 struct frame *sf = SELECTED_FRAME ();
7530 if (FRAME_MESSAGE_BUF (sf))
7531 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7532 }
7533 }
7534
7535
7536 /* Helper function for truncate_echo_area. Truncate the current
7537 message to at most NCHARS characters. */
7538
7539 static int
7540 truncate_message_1 (nchars, a2, a3, a4)
7541 EMACS_INT nchars;
7542 Lisp_Object a2;
7543 EMACS_INT a3, a4;
7544 {
7545 if (BEG + nchars < Z)
7546 del_range (BEG + nchars, Z);
7547 if (Z == BEG)
7548 echo_area_buffer[0] = Qnil;
7549 return 0;
7550 }
7551
7552
7553 /* Set the current message to a substring of S or STRING.
7554
7555 If STRING is a Lisp string, set the message to the first NBYTES
7556 bytes from STRING. NBYTES zero means use the whole string. If
7557 STRING is multibyte, the message will be displayed multibyte.
7558
7559 If S is not null, set the message to the first LEN bytes of S. LEN
7560 zero means use the whole string. MULTIBYTE_P non-zero means S is
7561 multibyte. Display the message multibyte in that case. */
7562
7563 void
7564 set_message (s, string, nbytes, multibyte_p)
7565 const char *s;
7566 Lisp_Object string;
7567 int nbytes, multibyte_p;
7568 {
7569 message_enable_multibyte
7570 = ((s && multibyte_p)
7571 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7572
7573 with_echo_area_buffer (0, -1, set_message_1,
7574 (EMACS_INT) s, string, nbytes, multibyte_p);
7575 message_buf_print = 0;
7576 help_echo_showing_p = 0;
7577 }
7578
7579
7580 /* Helper function for set_message. Arguments have the same meaning
7581 as there, with A1 corresponding to S and A2 corresponding to STRING
7582 This function is called with the echo area buffer being
7583 current. */
7584
7585 static int
7586 set_message_1 (a1, a2, nbytes, multibyte_p)
7587 EMACS_INT a1;
7588 Lisp_Object a2;
7589 EMACS_INT nbytes, multibyte_p;
7590 {
7591 const char *s = (const char *) a1;
7592 Lisp_Object string = a2;
7593
7594 xassert (BEG == Z);
7595
7596 /* Change multibyteness of the echo buffer appropriately. */
7597 if (message_enable_multibyte
7598 != !NILP (current_buffer->enable_multibyte_characters))
7599 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7600
7601 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7602
7603 /* Insert new message at BEG. */
7604 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7605
7606 if (STRINGP (string))
7607 {
7608 int nchars;
7609
7610 if (nbytes == 0)
7611 nbytes = SBYTES (string);
7612 nchars = string_byte_to_char (string, nbytes);
7613
7614 /* This function takes care of single/multibyte conversion. We
7615 just have to ensure that the echo area buffer has the right
7616 setting of enable_multibyte_characters. */
7617 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7618 }
7619 else if (s)
7620 {
7621 if (nbytes == 0)
7622 nbytes = strlen (s);
7623
7624 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7625 {
7626 /* Convert from multi-byte to single-byte. */
7627 int i, c, n;
7628 unsigned char work[1];
7629
7630 /* Convert a multibyte string to single-byte. */
7631 for (i = 0; i < nbytes; i += n)
7632 {
7633 c = string_char_and_length (s + i, nbytes - i, &n);
7634 work[0] = (SINGLE_BYTE_CHAR_P (c)
7635 ? c
7636 : multibyte_char_to_unibyte (c, Qnil));
7637 insert_1_both (work, 1, 1, 1, 0, 0);
7638 }
7639 }
7640 else if (!multibyte_p
7641 && !NILP (current_buffer->enable_multibyte_characters))
7642 {
7643 /* Convert from single-byte to multi-byte. */
7644 int i, c, n;
7645 const unsigned char *msg = (const unsigned char *) s;
7646 unsigned char str[MAX_MULTIBYTE_LENGTH];
7647
7648 /* Convert a single-byte string to multibyte. */
7649 for (i = 0; i < nbytes; i++)
7650 {
7651 c = unibyte_char_to_multibyte (msg[i]);
7652 n = CHAR_STRING (c, str);
7653 insert_1_both (str, 1, n, 1, 0, 0);
7654 }
7655 }
7656 else
7657 insert_1 (s, nbytes, 1, 0, 0);
7658 }
7659
7660 return 0;
7661 }
7662
7663
7664 /* Clear messages. CURRENT_P non-zero means clear the current
7665 message. LAST_DISPLAYED_P non-zero means clear the message
7666 last displayed. */
7667
7668 void
7669 clear_message (current_p, last_displayed_p)
7670 int current_p, last_displayed_p;
7671 {
7672 if (current_p)
7673 {
7674 echo_area_buffer[0] = Qnil;
7675 message_cleared_p = 1;
7676 }
7677
7678 if (last_displayed_p)
7679 echo_area_buffer[1] = Qnil;
7680
7681 message_buf_print = 0;
7682 }
7683
7684 /* Clear garbaged frames.
7685
7686 This function is used where the old redisplay called
7687 redraw_garbaged_frames which in turn called redraw_frame which in
7688 turn called clear_frame. The call to clear_frame was a source of
7689 flickering. I believe a clear_frame is not necessary. It should
7690 suffice in the new redisplay to invalidate all current matrices,
7691 and ensure a complete redisplay of all windows. */
7692
7693 static void
7694 clear_garbaged_frames ()
7695 {
7696 if (frame_garbaged)
7697 {
7698 Lisp_Object tail, frame;
7699 int changed_count = 0;
7700
7701 FOR_EACH_FRAME (tail, frame)
7702 {
7703 struct frame *f = XFRAME (frame);
7704
7705 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7706 {
7707 if (f->resized_p)
7708 {
7709 Fredraw_frame (frame);
7710 f->force_flush_display_p = 1;
7711 }
7712 clear_current_matrices (f);
7713 changed_count++;
7714 f->garbaged = 0;
7715 f->resized_p = 0;
7716 }
7717 }
7718
7719 frame_garbaged = 0;
7720 if (changed_count)
7721 ++windows_or_buffers_changed;
7722 }
7723 }
7724
7725
7726 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7727 is non-zero update selected_frame. Value is non-zero if the
7728 mini-windows height has been changed. */
7729
7730 static int
7731 echo_area_display (update_frame_p)
7732 int update_frame_p;
7733 {
7734 Lisp_Object mini_window;
7735 struct window *w;
7736 struct frame *f;
7737 int window_height_changed_p = 0;
7738 struct frame *sf = SELECTED_FRAME ();
7739
7740 mini_window = FRAME_MINIBUF_WINDOW (sf);
7741 w = XWINDOW (mini_window);
7742 f = XFRAME (WINDOW_FRAME (w));
7743
7744 /* Don't display if frame is invisible or not yet initialized. */
7745 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7746 return 0;
7747
7748 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7749 #ifndef MAC_OS8
7750 #ifdef HAVE_WINDOW_SYSTEM
7751 /* When Emacs starts, selected_frame may be the initial terminal
7752 frame. If we let this through, a message would be displayed on
7753 the terminal. */
7754 if (FRAME_TERMCAP_P (XFRAME (selected_frame))
7755 && FRAME_TTY (XFRAME (selected_frame))->type == NULL)
7756 return 0;
7757 #endif /* HAVE_WINDOW_SYSTEM */
7758 #endif
7759
7760 /* Redraw garbaged frames. */
7761 if (frame_garbaged)
7762 clear_garbaged_frames ();
7763
7764 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7765 {
7766 echo_area_window = mini_window;
7767 window_height_changed_p = display_echo_area (w);
7768 w->must_be_updated_p = 1;
7769
7770 /* Update the display, unless called from redisplay_internal.
7771 Also don't update the screen during redisplay itself. The
7772 update will happen at the end of redisplay, and an update
7773 here could cause confusion. */
7774 if (update_frame_p && !redisplaying_p)
7775 {
7776 int n = 0;
7777
7778 /* If the display update has been interrupted by pending
7779 input, update mode lines in the frame. Due to the
7780 pending input, it might have been that redisplay hasn't
7781 been called, so that mode lines above the echo area are
7782 garbaged. This looks odd, so we prevent it here. */
7783 if (!display_completed)
7784 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7785
7786 if (window_height_changed_p
7787 /* Don't do this if Emacs is shutting down. Redisplay
7788 needs to run hooks. */
7789 && !NILP (Vrun_hooks))
7790 {
7791 /* Must update other windows. Likewise as in other
7792 cases, don't let this update be interrupted by
7793 pending input. */
7794 int count = SPECPDL_INDEX ();
7795 specbind (Qredisplay_dont_pause, Qt);
7796 windows_or_buffers_changed = 1;
7797 redisplay_internal (0);
7798 unbind_to (count, Qnil);
7799 }
7800 else if (FRAME_WINDOW_P (f) && n == 0)
7801 {
7802 /* Window configuration is the same as before.
7803 Can do with a display update of the echo area,
7804 unless we displayed some mode lines. */
7805 update_single_window (w, 1);
7806 FRAME_RIF (f)->flush_display (f);
7807 }
7808 else
7809 update_frame (f, 1, 1);
7810
7811 /* If cursor is in the echo area, make sure that the next
7812 redisplay displays the minibuffer, so that the cursor will
7813 be replaced with what the minibuffer wants. */
7814 if (cursor_in_echo_area)
7815 ++windows_or_buffers_changed;
7816 }
7817 }
7818 else if (!EQ (mini_window, selected_window))
7819 windows_or_buffers_changed++;
7820
7821 /* Last displayed message is now the current message. */
7822 echo_area_buffer[1] = echo_area_buffer[0];
7823
7824 /* Prevent redisplay optimization in redisplay_internal by resetting
7825 this_line_start_pos. This is done because the mini-buffer now
7826 displays the message instead of its buffer text. */
7827 if (EQ (mini_window, selected_window))
7828 CHARPOS (this_line_start_pos) = 0;
7829
7830 return window_height_changed_p;
7831 }
7832
7833
7834 \f
7835 /***********************************************************************
7836 Frame Titles
7837 ***********************************************************************/
7838
7839
7840 /* The frame title buffering code is also used by Fformat_mode_line.
7841 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7842
7843 /* A buffer for constructing frame titles in it; allocated from the
7844 heap in init_xdisp and resized as needed in store_frame_title_char. */
7845
7846 static char *frame_title_buf;
7847
7848 /* The buffer's end, and a current output position in it. */
7849
7850 static char *frame_title_buf_end;
7851 static char *frame_title_ptr;
7852
7853
7854 /* Store a single character C for the frame title in frame_title_buf.
7855 Re-allocate frame_title_buf if necessary. */
7856
7857 static void
7858 #ifdef PROTOTYPES
7859 store_frame_title_char (char c)
7860 #else
7861 store_frame_title_char (c)
7862 char c;
7863 #endif
7864 {
7865 /* If output position has reached the end of the allocated buffer,
7866 double the buffer's size. */
7867 if (frame_title_ptr == frame_title_buf_end)
7868 {
7869 int len = frame_title_ptr - frame_title_buf;
7870 int new_size = 2 * len * sizeof *frame_title_buf;
7871 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7872 frame_title_buf_end = frame_title_buf + new_size;
7873 frame_title_ptr = frame_title_buf + len;
7874 }
7875
7876 *frame_title_ptr++ = c;
7877 }
7878
7879
7880 /* Store part of a frame title in frame_title_buf, beginning at
7881 frame_title_ptr. STR is the string to store. Do not copy
7882 characters that yield more columns than PRECISION; PRECISION <= 0
7883 means copy the whole string. Pad with spaces until FIELD_WIDTH
7884 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7885 pad. Called from display_mode_element when it is used to build a
7886 frame title. */
7887
7888 static int
7889 store_frame_title (str, field_width, precision)
7890 const unsigned char *str;
7891 int field_width, precision;
7892 {
7893 int n = 0;
7894 int dummy, nbytes;
7895
7896 /* Copy at most PRECISION chars from STR. */
7897 nbytes = strlen (str);
7898 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7899 while (nbytes--)
7900 store_frame_title_char (*str++);
7901
7902 /* Fill up with spaces until FIELD_WIDTH reached. */
7903 while (field_width > 0
7904 && n < field_width)
7905 {
7906 store_frame_title_char (' ');
7907 ++n;
7908 }
7909
7910 return n;
7911 }
7912
7913 #ifdef HAVE_WINDOW_SYSTEM
7914
7915 /* Set the title of FRAME, if it has changed. The title format is
7916 Vicon_title_format if FRAME is iconified, otherwise it is
7917 frame_title_format. */
7918
7919 static void
7920 x_consider_frame_title (frame)
7921 Lisp_Object frame;
7922 {
7923 struct frame *f = XFRAME (frame);
7924
7925 if (FRAME_WINDOW_P (f)
7926 || FRAME_MINIBUF_ONLY_P (f)
7927 || f->explicit_name)
7928 {
7929 /* Do we have more than one visible frame on this X display? */
7930 Lisp_Object tail;
7931 Lisp_Object fmt;
7932 struct buffer *obuf;
7933 int len;
7934 struct it it;
7935
7936 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7937 {
7938 Lisp_Object other_frame = XCAR (tail);
7939 struct frame *tf = XFRAME (other_frame);
7940
7941 if (tf != f
7942 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7943 && !FRAME_MINIBUF_ONLY_P (tf)
7944 && !EQ (other_frame, tip_frame)
7945 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7946 break;
7947 }
7948
7949 /* Set global variable indicating that multiple frames exist. */
7950 multiple_frames = CONSP (tail);
7951
7952 /* Switch to the buffer of selected window of the frame. Set up
7953 frame_title_ptr so that display_mode_element will output into it;
7954 then display the title. */
7955 obuf = current_buffer;
7956 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7957 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7958 frame_title_ptr = frame_title_buf;
7959 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7960 NULL, DEFAULT_FACE_ID);
7961 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7962 len = frame_title_ptr - frame_title_buf;
7963 frame_title_ptr = NULL;
7964 set_buffer_internal_1 (obuf);
7965
7966 /* Set the title only if it's changed. This avoids consing in
7967 the common case where it hasn't. (If it turns out that we've
7968 already wasted too much time by walking through the list with
7969 display_mode_element, then we might need to optimize at a
7970 higher level than this.) */
7971 if (! STRINGP (f->name)
7972 || SBYTES (f->name) != len
7973 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7974 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7975 }
7976 }
7977
7978 #endif /* not HAVE_WINDOW_SYSTEM */
7979
7980
7981
7982 \f
7983 /***********************************************************************
7984 Menu Bars
7985 ***********************************************************************/
7986
7987
7988 /* Prepare for redisplay by updating menu-bar item lists when
7989 appropriate. This can call eval. */
7990
7991 void
7992 prepare_menu_bars ()
7993 {
7994 int all_windows;
7995 struct gcpro gcpro1, gcpro2;
7996 struct frame *f;
7997 Lisp_Object tooltip_frame;
7998
7999 #ifdef HAVE_WINDOW_SYSTEM
8000 tooltip_frame = tip_frame;
8001 #else
8002 tooltip_frame = Qnil;
8003 #endif
8004
8005 /* Update all frame titles based on their buffer names, etc. We do
8006 this before the menu bars so that the buffer-menu will show the
8007 up-to-date frame titles. */
8008 #ifdef HAVE_WINDOW_SYSTEM
8009 if (windows_or_buffers_changed || update_mode_lines)
8010 {
8011 Lisp_Object tail, frame;
8012
8013 FOR_EACH_FRAME (tail, frame)
8014 {
8015 f = XFRAME (frame);
8016 if (!EQ (frame, tooltip_frame)
8017 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8018 x_consider_frame_title (frame);
8019 }
8020 }
8021 #endif /* HAVE_WINDOW_SYSTEM */
8022
8023 /* Update the menu bar item lists, if appropriate. This has to be
8024 done before any actual redisplay or generation of display lines. */
8025 all_windows = (update_mode_lines
8026 || buffer_shared > 1
8027 || windows_or_buffers_changed);
8028 if (all_windows)
8029 {
8030 Lisp_Object tail, frame;
8031 int count = SPECPDL_INDEX ();
8032
8033 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8034
8035 FOR_EACH_FRAME (tail, frame)
8036 {
8037 f = XFRAME (frame);
8038
8039 /* Ignore tooltip frame. */
8040 if (EQ (frame, tooltip_frame))
8041 continue;
8042
8043 /* If a window on this frame changed size, report that to
8044 the user and clear the size-change flag. */
8045 if (FRAME_WINDOW_SIZES_CHANGED (f))
8046 {
8047 Lisp_Object functions;
8048
8049 /* Clear flag first in case we get an error below. */
8050 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8051 functions = Vwindow_size_change_functions;
8052 GCPRO2 (tail, functions);
8053
8054 while (CONSP (functions))
8055 {
8056 call1 (XCAR (functions), frame);
8057 functions = XCDR (functions);
8058 }
8059 UNGCPRO;
8060 }
8061
8062 GCPRO1 (tail);
8063 update_menu_bar (f, 0);
8064 #ifdef HAVE_WINDOW_SYSTEM
8065 update_tool_bar (f, 0);
8066 #endif
8067 UNGCPRO;
8068 }
8069
8070 unbind_to (count, Qnil);
8071 }
8072 else
8073 {
8074 struct frame *sf = SELECTED_FRAME ();
8075 update_menu_bar (sf, 1);
8076 #ifdef HAVE_WINDOW_SYSTEM
8077 update_tool_bar (sf, 1);
8078 #endif
8079 }
8080
8081 /* Motif needs this. See comment in xmenu.c. Turn it off when
8082 pending_menu_activation is not defined. */
8083 #ifdef USE_X_TOOLKIT
8084 pending_menu_activation = 0;
8085 #endif
8086 }
8087
8088
8089 /* Update the menu bar item list for frame F. This has to be done
8090 before we start to fill in any display lines, because it can call
8091 eval.
8092
8093 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8094
8095 static void
8096 update_menu_bar (f, save_match_data)
8097 struct frame *f;
8098 int save_match_data;
8099 {
8100 Lisp_Object window;
8101 register struct window *w;
8102
8103 /* If called recursively during a menu update, do nothing. This can
8104 happen when, for instance, an activate-menubar-hook causes a
8105 redisplay. */
8106 if (inhibit_menubar_update)
8107 return;
8108
8109 window = FRAME_SELECTED_WINDOW (f);
8110 w = XWINDOW (window);
8111
8112 #if 0 /* The if statement below this if statement used to include the
8113 condition !NILP (w->update_mode_line), rather than using
8114 update_mode_lines directly, and this if statement may have
8115 been added to make that condition work. Now the if
8116 statement below matches its comment, this isn't needed. */
8117 if (update_mode_lines)
8118 w->update_mode_line = Qt;
8119 #endif
8120
8121 if (FRAME_WINDOW_P (f)
8122 ?
8123 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8124 || defined (USE_GTK)
8125 FRAME_EXTERNAL_MENU_BAR (f)
8126 #else
8127 FRAME_MENU_BAR_LINES (f) > 0
8128 #endif
8129 : FRAME_MENU_BAR_LINES (f) > 0)
8130 {
8131 /* If the user has switched buffers or windows, we need to
8132 recompute to reflect the new bindings. But we'll
8133 recompute when update_mode_lines is set too; that means
8134 that people can use force-mode-line-update to request
8135 that the menu bar be recomputed. The adverse effect on
8136 the rest of the redisplay algorithm is about the same as
8137 windows_or_buffers_changed anyway. */
8138 if (windows_or_buffers_changed
8139 /* This used to test w->update_mode_line, but we believe
8140 there is no need to recompute the menu in that case. */
8141 || update_mode_lines
8142 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8143 < BUF_MODIFF (XBUFFER (w->buffer)))
8144 != !NILP (w->last_had_star))
8145 || ((!NILP (Vtransient_mark_mode)
8146 && !NILP (XBUFFER (w->buffer)->mark_active))
8147 != !NILP (w->region_showing)))
8148 {
8149 struct buffer *prev = current_buffer;
8150 int count = SPECPDL_INDEX ();
8151
8152 specbind (Qinhibit_menubar_update, Qt);
8153
8154 set_buffer_internal_1 (XBUFFER (w->buffer));
8155 if (save_match_data)
8156 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8157 if (NILP (Voverriding_local_map_menu_flag))
8158 {
8159 specbind (Qoverriding_terminal_local_map, Qnil);
8160 specbind (Qoverriding_local_map, Qnil);
8161 }
8162
8163 /* Run the Lucid hook. */
8164 safe_run_hooks (Qactivate_menubar_hook);
8165
8166 /* If it has changed current-menubar from previous value,
8167 really recompute the menu-bar from the value. */
8168 if (! NILP (Vlucid_menu_bar_dirty_flag))
8169 call0 (Qrecompute_lucid_menubar);
8170
8171 safe_run_hooks (Qmenu_bar_update_hook);
8172 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8173
8174 /* Redisplay the menu bar in case we changed it. */
8175 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8176 || defined (USE_GTK)
8177 if (FRAME_WINDOW_P (f)
8178 #if defined (MAC_OS)
8179 /* All frames on Mac OS share the same menubar. So only the
8180 selected frame should be allowed to set it. */
8181 && f == SELECTED_FRAME ()
8182 #endif
8183 )
8184 set_frame_menubar (f, 0, 0);
8185 else
8186 /* On a terminal screen, the menu bar is an ordinary screen
8187 line, and this makes it get updated. */
8188 w->update_mode_line = Qt;
8189 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8190 /* In the non-toolkit version, the menu bar is an ordinary screen
8191 line, and this makes it get updated. */
8192 w->update_mode_line = Qt;
8193 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8194
8195 unbind_to (count, Qnil);
8196 set_buffer_internal_1 (prev);
8197 }
8198 }
8199 }
8200
8201
8202 \f
8203 /***********************************************************************
8204 Output Cursor
8205 ***********************************************************************/
8206
8207 #ifdef HAVE_WINDOW_SYSTEM
8208
8209 /* EXPORT:
8210 Nominal cursor position -- where to draw output.
8211 HPOS and VPOS are window relative glyph matrix coordinates.
8212 X and Y are window relative pixel coordinates. */
8213
8214 struct cursor_pos output_cursor;
8215
8216
8217 /* EXPORT:
8218 Set the global variable output_cursor to CURSOR. All cursor
8219 positions are relative to updated_window. */
8220
8221 void
8222 set_output_cursor (cursor)
8223 struct cursor_pos *cursor;
8224 {
8225 output_cursor.hpos = cursor->hpos;
8226 output_cursor.vpos = cursor->vpos;
8227 output_cursor.x = cursor->x;
8228 output_cursor.y = cursor->y;
8229 }
8230
8231
8232 /* EXPORT for RIF:
8233 Set a nominal cursor position.
8234
8235 HPOS and VPOS are column/row positions in a window glyph matrix. X
8236 and Y are window text area relative pixel positions.
8237
8238 If this is done during an update, updated_window will contain the
8239 window that is being updated and the position is the future output
8240 cursor position for that window. If updated_window is null, use
8241 selected_window and display the cursor at the given position. */
8242
8243 void
8244 x_cursor_to (vpos, hpos, y, x)
8245 int vpos, hpos, y, x;
8246 {
8247 struct window *w;
8248
8249 /* If updated_window is not set, work on selected_window. */
8250 if (updated_window)
8251 w = updated_window;
8252 else
8253 w = XWINDOW (selected_window);
8254
8255 /* Set the output cursor. */
8256 output_cursor.hpos = hpos;
8257 output_cursor.vpos = vpos;
8258 output_cursor.x = x;
8259 output_cursor.y = y;
8260
8261 /* If not called as part of an update, really display the cursor.
8262 This will also set the cursor position of W. */
8263 if (updated_window == NULL)
8264 {
8265 BLOCK_INPUT;
8266 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8267 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
8268 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
8269 UNBLOCK_INPUT;
8270 }
8271 }
8272
8273 #endif /* HAVE_WINDOW_SYSTEM */
8274
8275 \f
8276 /***********************************************************************
8277 Tool-bars
8278 ***********************************************************************/
8279
8280 #ifdef HAVE_WINDOW_SYSTEM
8281
8282 /* Where the mouse was last time we reported a mouse event. */
8283
8284 FRAME_PTR last_mouse_frame;
8285
8286 /* Tool-bar item index of the item on which a mouse button was pressed
8287 or -1. */
8288
8289 int last_tool_bar_item;
8290
8291
8292 /* Update the tool-bar item list for frame F. This has to be done
8293 before we start to fill in any display lines. Called from
8294 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8295 and restore it here. */
8296
8297 static void
8298 update_tool_bar (f, save_match_data)
8299 struct frame *f;
8300 int save_match_data;
8301 {
8302 #ifdef USE_GTK
8303 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8304 #else
8305 int do_update = WINDOWP (f->tool_bar_window)
8306 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8307 #endif
8308
8309 if (do_update)
8310 {
8311 Lisp_Object window;
8312 struct window *w;
8313
8314 window = FRAME_SELECTED_WINDOW (f);
8315 w = XWINDOW (window);
8316
8317 /* If the user has switched buffers or windows, we need to
8318 recompute to reflect the new bindings. But we'll
8319 recompute when update_mode_lines is set too; that means
8320 that people can use force-mode-line-update to request
8321 that the menu bar be recomputed. The adverse effect on
8322 the rest of the redisplay algorithm is about the same as
8323 windows_or_buffers_changed anyway. */
8324 if (windows_or_buffers_changed
8325 || !NILP (w->update_mode_line)
8326 || update_mode_lines
8327 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8328 < BUF_MODIFF (XBUFFER (w->buffer)))
8329 != !NILP (w->last_had_star))
8330 || ((!NILP (Vtransient_mark_mode)
8331 && !NILP (XBUFFER (w->buffer)->mark_active))
8332 != !NILP (w->region_showing)))
8333 {
8334 struct buffer *prev = current_buffer;
8335 int count = SPECPDL_INDEX ();
8336 Lisp_Object old_tool_bar;
8337 struct gcpro gcpro1;
8338
8339 /* Set current_buffer to the buffer of the selected
8340 window of the frame, so that we get the right local
8341 keymaps. */
8342 set_buffer_internal_1 (XBUFFER (w->buffer));
8343
8344 /* Save match data, if we must. */
8345 if (save_match_data)
8346 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8347
8348 /* Make sure that we don't accidentally use bogus keymaps. */
8349 if (NILP (Voverriding_local_map_menu_flag))
8350 {
8351 specbind (Qoverriding_terminal_local_map, Qnil);
8352 specbind (Qoverriding_local_map, Qnil);
8353 }
8354
8355 old_tool_bar = f->tool_bar_items;
8356 GCPRO1 (old_tool_bar);
8357
8358 /* Build desired tool-bar items from keymaps. */
8359 BLOCK_INPUT;
8360 f->tool_bar_items
8361 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8362 UNBLOCK_INPUT;
8363
8364 /* Redisplay the tool-bar if we changed it. */
8365 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8366 w->update_mode_line = Qt;
8367
8368 UNGCPRO;
8369
8370 unbind_to (count, Qnil);
8371 set_buffer_internal_1 (prev);
8372 }
8373 }
8374 }
8375
8376
8377 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8378 F's desired tool-bar contents. F->tool_bar_items must have
8379 been set up previously by calling prepare_menu_bars. */
8380
8381 static void
8382 build_desired_tool_bar_string (f)
8383 struct frame *f;
8384 {
8385 int i, size, size_needed;
8386 struct gcpro gcpro1, gcpro2, gcpro3;
8387 Lisp_Object image, plist, props;
8388
8389 image = plist = props = Qnil;
8390 GCPRO3 (image, plist, props);
8391
8392 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8393 Otherwise, make a new string. */
8394
8395 /* The size of the string we might be able to reuse. */
8396 size = (STRINGP (f->desired_tool_bar_string)
8397 ? SCHARS (f->desired_tool_bar_string)
8398 : 0);
8399
8400 /* We need one space in the string for each image. */
8401 size_needed = f->n_tool_bar_items;
8402
8403 /* Reuse f->desired_tool_bar_string, if possible. */
8404 if (size < size_needed || NILP (f->desired_tool_bar_string))
8405 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8406 make_number (' '));
8407 else
8408 {
8409 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8410 Fremove_text_properties (make_number (0), make_number (size),
8411 props, f->desired_tool_bar_string);
8412 }
8413
8414 /* Put a `display' property on the string for the images to display,
8415 put a `menu_item' property on tool-bar items with a value that
8416 is the index of the item in F's tool-bar item vector. */
8417 for (i = 0; i < f->n_tool_bar_items; ++i)
8418 {
8419 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8420
8421 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8422 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8423 int hmargin, vmargin, relief, idx, end;
8424 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8425
8426 /* If image is a vector, choose the image according to the
8427 button state. */
8428 image = PROP (TOOL_BAR_ITEM_IMAGES);
8429 if (VECTORP (image))
8430 {
8431 if (enabled_p)
8432 idx = (selected_p
8433 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8434 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8435 else
8436 idx = (selected_p
8437 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8438 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8439
8440 xassert (ASIZE (image) >= idx);
8441 image = AREF (image, idx);
8442 }
8443 else
8444 idx = -1;
8445
8446 /* Ignore invalid image specifications. */
8447 if (!valid_image_p (image))
8448 continue;
8449
8450 /* Display the tool-bar button pressed, or depressed. */
8451 plist = Fcopy_sequence (XCDR (image));
8452
8453 /* Compute margin and relief to draw. */
8454 relief = (tool_bar_button_relief >= 0
8455 ? tool_bar_button_relief
8456 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8457 hmargin = vmargin = relief;
8458
8459 if (INTEGERP (Vtool_bar_button_margin)
8460 && XINT (Vtool_bar_button_margin) > 0)
8461 {
8462 hmargin += XFASTINT (Vtool_bar_button_margin);
8463 vmargin += XFASTINT (Vtool_bar_button_margin);
8464 }
8465 else if (CONSP (Vtool_bar_button_margin))
8466 {
8467 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8468 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8469 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8470
8471 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8472 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8473 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8474 }
8475
8476 if (auto_raise_tool_bar_buttons_p)
8477 {
8478 /* Add a `:relief' property to the image spec if the item is
8479 selected. */
8480 if (selected_p)
8481 {
8482 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8483 hmargin -= relief;
8484 vmargin -= relief;
8485 }
8486 }
8487 else
8488 {
8489 /* If image is selected, display it pressed, i.e. with a
8490 negative relief. If it's not selected, display it with a
8491 raised relief. */
8492 plist = Fplist_put (plist, QCrelief,
8493 (selected_p
8494 ? make_number (-relief)
8495 : make_number (relief)));
8496 hmargin -= relief;
8497 vmargin -= relief;
8498 }
8499
8500 /* Put a margin around the image. */
8501 if (hmargin || vmargin)
8502 {
8503 if (hmargin == vmargin)
8504 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8505 else
8506 plist = Fplist_put (plist, QCmargin,
8507 Fcons (make_number (hmargin),
8508 make_number (vmargin)));
8509 }
8510
8511 /* If button is not enabled, and we don't have special images
8512 for the disabled state, make the image appear disabled by
8513 applying an appropriate algorithm to it. */
8514 if (!enabled_p && idx < 0)
8515 plist = Fplist_put (plist, QCconversion, Qdisabled);
8516
8517 /* Put a `display' text property on the string for the image to
8518 display. Put a `menu-item' property on the string that gives
8519 the start of this item's properties in the tool-bar items
8520 vector. */
8521 image = Fcons (Qimage, plist);
8522 props = list4 (Qdisplay, image,
8523 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8524
8525 /* Let the last image hide all remaining spaces in the tool bar
8526 string. The string can be longer than needed when we reuse a
8527 previous string. */
8528 if (i + 1 == f->n_tool_bar_items)
8529 end = SCHARS (f->desired_tool_bar_string);
8530 else
8531 end = i + 1;
8532 Fadd_text_properties (make_number (i), make_number (end),
8533 props, f->desired_tool_bar_string);
8534 #undef PROP
8535 }
8536
8537 UNGCPRO;
8538 }
8539
8540
8541 /* Display one line of the tool-bar of frame IT->f. */
8542
8543 static void
8544 display_tool_bar_line (it)
8545 struct it *it;
8546 {
8547 struct glyph_row *row = it->glyph_row;
8548 int max_x = it->last_visible_x;
8549 struct glyph *last;
8550
8551 prepare_desired_row (row);
8552 row->y = it->current_y;
8553
8554 /* Note that this isn't made use of if the face hasn't a box,
8555 so there's no need to check the face here. */
8556 it->start_of_box_run_p = 1;
8557
8558 while (it->current_x < max_x)
8559 {
8560 int x_before, x, n_glyphs_before, i, nglyphs;
8561
8562 /* Get the next display element. */
8563 if (!get_next_display_element (it))
8564 break;
8565
8566 /* Produce glyphs. */
8567 x_before = it->current_x;
8568 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8569 PRODUCE_GLYPHS (it);
8570
8571 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8572 i = 0;
8573 x = x_before;
8574 while (i < nglyphs)
8575 {
8576 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8577
8578 if (x + glyph->pixel_width > max_x)
8579 {
8580 /* Glyph doesn't fit on line. */
8581 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8582 it->current_x = x;
8583 goto out;
8584 }
8585
8586 ++it->hpos;
8587 x += glyph->pixel_width;
8588 ++i;
8589 }
8590
8591 /* Stop at line ends. */
8592 if (ITERATOR_AT_END_OF_LINE_P (it))
8593 break;
8594
8595 set_iterator_to_next (it, 1);
8596 }
8597
8598 out:;
8599
8600 row->displays_text_p = row->used[TEXT_AREA] != 0;
8601 extend_face_to_end_of_line (it);
8602 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8603 last->right_box_line_p = 1;
8604 if (last == row->glyphs[TEXT_AREA])
8605 last->left_box_line_p = 1;
8606 compute_line_metrics (it);
8607
8608 /* If line is empty, make it occupy the rest of the tool-bar. */
8609 if (!row->displays_text_p)
8610 {
8611 row->height = row->phys_height = it->last_visible_y - row->y;
8612 row->ascent = row->phys_ascent = 0;
8613 }
8614
8615 row->full_width_p = 1;
8616 row->continued_p = 0;
8617 row->truncated_on_left_p = 0;
8618 row->truncated_on_right_p = 0;
8619
8620 it->current_x = it->hpos = 0;
8621 it->current_y += row->height;
8622 ++it->vpos;
8623 ++it->glyph_row;
8624 }
8625
8626
8627 /* Value is the number of screen lines needed to make all tool-bar
8628 items of frame F visible. */
8629
8630 static int
8631 tool_bar_lines_needed (f)
8632 struct frame *f;
8633 {
8634 struct window *w = XWINDOW (f->tool_bar_window);
8635 struct it it;
8636
8637 /* Initialize an iterator for iteration over
8638 F->desired_tool_bar_string in the tool-bar window of frame F. */
8639 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8640 it.first_visible_x = 0;
8641 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8642 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8643
8644 while (!ITERATOR_AT_END_P (&it))
8645 {
8646 it.glyph_row = w->desired_matrix->rows;
8647 clear_glyph_row (it.glyph_row);
8648 display_tool_bar_line (&it);
8649 }
8650
8651 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8652 }
8653
8654
8655 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8656 0, 1, 0,
8657 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8658 (frame)
8659 Lisp_Object frame;
8660 {
8661 struct frame *f;
8662 struct window *w;
8663 int nlines = 0;
8664
8665 if (NILP (frame))
8666 frame = selected_frame;
8667 else
8668 CHECK_FRAME (frame);
8669 f = XFRAME (frame);
8670
8671 if (WINDOWP (f->tool_bar_window)
8672 || (w = XWINDOW (f->tool_bar_window),
8673 WINDOW_TOTAL_LINES (w) > 0))
8674 {
8675 update_tool_bar (f, 1);
8676 if (f->n_tool_bar_items)
8677 {
8678 build_desired_tool_bar_string (f);
8679 nlines = tool_bar_lines_needed (f);
8680 }
8681 }
8682
8683 return make_number (nlines);
8684 }
8685
8686
8687 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8688 height should be changed. */
8689
8690 static int
8691 redisplay_tool_bar (f)
8692 struct frame *f;
8693 {
8694 struct window *w;
8695 struct it it;
8696 struct glyph_row *row;
8697 int change_height_p = 0;
8698
8699 #ifdef USE_GTK
8700 if (FRAME_EXTERNAL_TOOL_BAR (f))
8701 update_frame_tool_bar (f);
8702 return 0;
8703 #endif
8704
8705 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8706 do anything. This means you must start with tool-bar-lines
8707 non-zero to get the auto-sizing effect. Or in other words, you
8708 can turn off tool-bars by specifying tool-bar-lines zero. */
8709 if (!WINDOWP (f->tool_bar_window)
8710 || (w = XWINDOW (f->tool_bar_window),
8711 WINDOW_TOTAL_LINES (w) == 0))
8712 return 0;
8713
8714 /* Set up an iterator for the tool-bar window. */
8715 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8716 it.first_visible_x = 0;
8717 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8718 row = it.glyph_row;
8719
8720 /* Build a string that represents the contents of the tool-bar. */
8721 build_desired_tool_bar_string (f);
8722 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8723
8724 /* Display as many lines as needed to display all tool-bar items. */
8725 while (it.current_y < it.last_visible_y)
8726 display_tool_bar_line (&it);
8727
8728 /* It doesn't make much sense to try scrolling in the tool-bar
8729 window, so don't do it. */
8730 w->desired_matrix->no_scrolling_p = 1;
8731 w->must_be_updated_p = 1;
8732
8733 if (auto_resize_tool_bars_p)
8734 {
8735 int nlines;
8736
8737 /* If we couldn't display everything, change the tool-bar's
8738 height. */
8739 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8740 change_height_p = 1;
8741
8742 /* If there are blank lines at the end, except for a partially
8743 visible blank line at the end that is smaller than
8744 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8745 row = it.glyph_row - 1;
8746 if (!row->displays_text_p
8747 && row->height >= FRAME_LINE_HEIGHT (f))
8748 change_height_p = 1;
8749
8750 /* If row displays tool-bar items, but is partially visible,
8751 change the tool-bar's height. */
8752 if (row->displays_text_p
8753 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8754 change_height_p = 1;
8755
8756 /* Resize windows as needed by changing the `tool-bar-lines'
8757 frame parameter. */
8758 if (change_height_p
8759 && (nlines = tool_bar_lines_needed (f),
8760 nlines != WINDOW_TOTAL_LINES (w)))
8761 {
8762 extern Lisp_Object Qtool_bar_lines;
8763 Lisp_Object frame;
8764 int old_height = WINDOW_TOTAL_LINES (w);
8765
8766 XSETFRAME (frame, f);
8767 clear_glyph_matrix (w->desired_matrix);
8768 Fmodify_frame_parameters (frame,
8769 Fcons (Fcons (Qtool_bar_lines,
8770 make_number (nlines)),
8771 Qnil));
8772 if (WINDOW_TOTAL_LINES (w) != old_height)
8773 fonts_changed_p = 1;
8774 }
8775 }
8776
8777 return change_height_p;
8778 }
8779
8780
8781 /* Get information about the tool-bar item which is displayed in GLYPH
8782 on frame F. Return in *PROP_IDX the index where tool-bar item
8783 properties start in F->tool_bar_items. Value is zero if
8784 GLYPH doesn't display a tool-bar item. */
8785
8786 static int
8787 tool_bar_item_info (f, glyph, prop_idx)
8788 struct frame *f;
8789 struct glyph *glyph;
8790 int *prop_idx;
8791 {
8792 Lisp_Object prop;
8793 int success_p;
8794 int charpos;
8795
8796 /* This function can be called asynchronously, which means we must
8797 exclude any possibility that Fget_text_property signals an
8798 error. */
8799 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8800 charpos = max (0, charpos);
8801
8802 /* Get the text property `menu-item' at pos. The value of that
8803 property is the start index of this item's properties in
8804 F->tool_bar_items. */
8805 prop = Fget_text_property (make_number (charpos),
8806 Qmenu_item, f->current_tool_bar_string);
8807 if (INTEGERP (prop))
8808 {
8809 *prop_idx = XINT (prop);
8810 success_p = 1;
8811 }
8812 else
8813 success_p = 0;
8814
8815 return success_p;
8816 }
8817
8818 \f
8819 /* Get information about the tool-bar item at position X/Y on frame F.
8820 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8821 the current matrix of the tool-bar window of F, or NULL if not
8822 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8823 item in F->tool_bar_items. Value is
8824
8825 -1 if X/Y is not on a tool-bar item
8826 0 if X/Y is on the same item that was highlighted before.
8827 1 otherwise. */
8828
8829 static int
8830 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8831 struct frame *f;
8832 int x, y;
8833 struct glyph **glyph;
8834 int *hpos, *vpos, *prop_idx;
8835 {
8836 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8837 struct window *w = XWINDOW (f->tool_bar_window);
8838 int area;
8839
8840 /* Find the glyph under X/Y. */
8841 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8842 if (*glyph == NULL)
8843 return -1;
8844
8845 /* Get the start of this tool-bar item's properties in
8846 f->tool_bar_items. */
8847 if (!tool_bar_item_info (f, *glyph, prop_idx))
8848 return -1;
8849
8850 /* Is mouse on the highlighted item? */
8851 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8852 && *vpos >= dpyinfo->mouse_face_beg_row
8853 && *vpos <= dpyinfo->mouse_face_end_row
8854 && (*vpos > dpyinfo->mouse_face_beg_row
8855 || *hpos >= dpyinfo->mouse_face_beg_col)
8856 && (*vpos < dpyinfo->mouse_face_end_row
8857 || *hpos < dpyinfo->mouse_face_end_col
8858 || dpyinfo->mouse_face_past_end))
8859 return 0;
8860
8861 return 1;
8862 }
8863
8864
8865 /* EXPORT:
8866 Handle mouse button event on the tool-bar of frame F, at
8867 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8868 0 for button release. MODIFIERS is event modifiers for button
8869 release. */
8870
8871 void
8872 handle_tool_bar_click (f, x, y, down_p, modifiers)
8873 struct frame *f;
8874 int x, y, down_p;
8875 unsigned int modifiers;
8876 {
8877 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8878 struct window *w = XWINDOW (f->tool_bar_window);
8879 int hpos, vpos, prop_idx;
8880 struct glyph *glyph;
8881 Lisp_Object enabled_p;
8882
8883 /* If not on the highlighted tool-bar item, return. */
8884 frame_to_window_pixel_xy (w, &x, &y);
8885 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8886 return;
8887
8888 /* If item is disabled, do nothing. */
8889 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8890 if (NILP (enabled_p))
8891 return;
8892
8893 if (down_p)
8894 {
8895 /* Show item in pressed state. */
8896 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8897 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8898 last_tool_bar_item = prop_idx;
8899 }
8900 else
8901 {
8902 Lisp_Object key, frame;
8903 struct input_event event;
8904 EVENT_INIT (event);
8905
8906 /* Show item in released state. */
8907 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8908 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8909
8910 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8911
8912 XSETFRAME (frame, f);
8913 event.kind = TOOL_BAR_EVENT;
8914 event.frame_or_window = frame;
8915 event.arg = frame;
8916 kbd_buffer_store_event (&event);
8917
8918 event.kind = TOOL_BAR_EVENT;
8919 event.frame_or_window = frame;
8920 event.arg = key;
8921 event.modifiers = modifiers;
8922 kbd_buffer_store_event (&event);
8923 last_tool_bar_item = -1;
8924 }
8925 }
8926
8927
8928 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8929 tool-bar window-relative coordinates X/Y. Called from
8930 note_mouse_highlight. */
8931
8932 static void
8933 note_tool_bar_highlight (f, x, y)
8934 struct frame *f;
8935 int x, y;
8936 {
8937 Lisp_Object window = f->tool_bar_window;
8938 struct window *w = XWINDOW (window);
8939 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8940 int hpos, vpos;
8941 struct glyph *glyph;
8942 struct glyph_row *row;
8943 int i;
8944 Lisp_Object enabled_p;
8945 int prop_idx;
8946 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8947 int mouse_down_p, rc;
8948
8949 /* Function note_mouse_highlight is called with negative x(y
8950 values when mouse moves outside of the frame. */
8951 if (x <= 0 || y <= 0)
8952 {
8953 clear_mouse_face (dpyinfo);
8954 return;
8955 }
8956
8957 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8958 if (rc < 0)
8959 {
8960 /* Not on tool-bar item. */
8961 clear_mouse_face (dpyinfo);
8962 return;
8963 }
8964 else if (rc == 0)
8965 /* On same tool-bar item as before. */
8966 goto set_help_echo;
8967
8968 clear_mouse_face (dpyinfo);
8969
8970 /* Mouse is down, but on different tool-bar item? */
8971 mouse_down_p = (dpyinfo->grabbed
8972 && f == last_mouse_frame
8973 && FRAME_LIVE_P (f));
8974 if (mouse_down_p
8975 && last_tool_bar_item != prop_idx)
8976 return;
8977
8978 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8979 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8980
8981 /* If tool-bar item is not enabled, don't highlight it. */
8982 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8983 if (!NILP (enabled_p))
8984 {
8985 /* Compute the x-position of the glyph. In front and past the
8986 image is a space. We include this in the highlighted area. */
8987 row = MATRIX_ROW (w->current_matrix, vpos);
8988 for (i = x = 0; i < hpos; ++i)
8989 x += row->glyphs[TEXT_AREA][i].pixel_width;
8990
8991 /* Record this as the current active region. */
8992 dpyinfo->mouse_face_beg_col = hpos;
8993 dpyinfo->mouse_face_beg_row = vpos;
8994 dpyinfo->mouse_face_beg_x = x;
8995 dpyinfo->mouse_face_beg_y = row->y;
8996 dpyinfo->mouse_face_past_end = 0;
8997
8998 dpyinfo->mouse_face_end_col = hpos + 1;
8999 dpyinfo->mouse_face_end_row = vpos;
9000 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9001 dpyinfo->mouse_face_end_y = row->y;
9002 dpyinfo->mouse_face_window = window;
9003 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9004
9005 /* Display it as active. */
9006 show_mouse_face (dpyinfo, draw);
9007 dpyinfo->mouse_face_image_state = draw;
9008 }
9009
9010 set_help_echo:
9011
9012 /* Set help_echo_string to a help string to display for this tool-bar item.
9013 XTread_socket does the rest. */
9014 help_echo_object = help_echo_window = Qnil;
9015 help_echo_pos = -1;
9016 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9017 if (NILP (help_echo_string))
9018 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9019 }
9020
9021 #endif /* HAVE_WINDOW_SYSTEM */
9022
9023
9024 \f
9025 /************************************************************************
9026 Horizontal scrolling
9027 ************************************************************************/
9028
9029 static int hscroll_window_tree P_ ((Lisp_Object));
9030 static int hscroll_windows P_ ((Lisp_Object));
9031
9032 /* For all leaf windows in the window tree rooted at WINDOW, set their
9033 hscroll value so that PT is (i) visible in the window, and (ii) so
9034 that it is not within a certain margin at the window's left and
9035 right border. Value is non-zero if any window's hscroll has been
9036 changed. */
9037
9038 static int
9039 hscroll_window_tree (window)
9040 Lisp_Object window;
9041 {
9042 int hscrolled_p = 0;
9043 int hscroll_relative_p = FLOATP (Vhscroll_step);
9044 int hscroll_step_abs = 0;
9045 double hscroll_step_rel = 0;
9046
9047 if (hscroll_relative_p)
9048 {
9049 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9050 if (hscroll_step_rel < 0)
9051 {
9052 hscroll_relative_p = 0;
9053 hscroll_step_abs = 0;
9054 }
9055 }
9056 else if (INTEGERP (Vhscroll_step))
9057 {
9058 hscroll_step_abs = XINT (Vhscroll_step);
9059 if (hscroll_step_abs < 0)
9060 hscroll_step_abs = 0;
9061 }
9062 else
9063 hscroll_step_abs = 0;
9064
9065 while (WINDOWP (window))
9066 {
9067 struct window *w = XWINDOW (window);
9068
9069 if (WINDOWP (w->hchild))
9070 hscrolled_p |= hscroll_window_tree (w->hchild);
9071 else if (WINDOWP (w->vchild))
9072 hscrolled_p |= hscroll_window_tree (w->vchild);
9073 else if (w->cursor.vpos >= 0)
9074 {
9075 int h_margin;
9076 int text_area_width;
9077 struct glyph_row *current_cursor_row
9078 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9079 struct glyph_row *desired_cursor_row
9080 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9081 struct glyph_row *cursor_row
9082 = (desired_cursor_row->enabled_p
9083 ? desired_cursor_row
9084 : current_cursor_row);
9085
9086 text_area_width = window_box_width (w, TEXT_AREA);
9087
9088 /* Scroll when cursor is inside this scroll margin. */
9089 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9090
9091 if ((XFASTINT (w->hscroll)
9092 && w->cursor.x <= h_margin)
9093 || (cursor_row->enabled_p
9094 && cursor_row->truncated_on_right_p
9095 && (w->cursor.x >= text_area_width - h_margin)))
9096 {
9097 struct it it;
9098 int hscroll;
9099 struct buffer *saved_current_buffer;
9100 int pt;
9101 int wanted_x;
9102
9103 /* Find point in a display of infinite width. */
9104 saved_current_buffer = current_buffer;
9105 current_buffer = XBUFFER (w->buffer);
9106
9107 if (w == XWINDOW (selected_window))
9108 pt = BUF_PT (current_buffer);
9109 else
9110 {
9111 pt = marker_position (w->pointm);
9112 pt = max (BEGV, pt);
9113 pt = min (ZV, pt);
9114 }
9115
9116 /* Move iterator to pt starting at cursor_row->start in
9117 a line with infinite width. */
9118 init_to_row_start (&it, w, cursor_row);
9119 it.last_visible_x = INFINITY;
9120 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9121 current_buffer = saved_current_buffer;
9122
9123 /* Position cursor in window. */
9124 if (!hscroll_relative_p && hscroll_step_abs == 0)
9125 hscroll = max (0, (it.current_x
9126 - (ITERATOR_AT_END_OF_LINE_P (&it)
9127 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9128 : (text_area_width / 2))))
9129 / FRAME_COLUMN_WIDTH (it.f);
9130 else if (w->cursor.x >= text_area_width - h_margin)
9131 {
9132 if (hscroll_relative_p)
9133 wanted_x = text_area_width * (1 - hscroll_step_rel)
9134 - h_margin;
9135 else
9136 wanted_x = text_area_width
9137 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9138 - h_margin;
9139 hscroll
9140 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9141 }
9142 else
9143 {
9144 if (hscroll_relative_p)
9145 wanted_x = text_area_width * hscroll_step_rel
9146 + h_margin;
9147 else
9148 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9149 + h_margin;
9150 hscroll
9151 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9152 }
9153 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9154
9155 /* Don't call Fset_window_hscroll if value hasn't
9156 changed because it will prevent redisplay
9157 optimizations. */
9158 if (XFASTINT (w->hscroll) != hscroll)
9159 {
9160 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9161 w->hscroll = make_number (hscroll);
9162 hscrolled_p = 1;
9163 }
9164 }
9165 }
9166
9167 window = w->next;
9168 }
9169
9170 /* Value is non-zero if hscroll of any leaf window has been changed. */
9171 return hscrolled_p;
9172 }
9173
9174
9175 /* Set hscroll so that cursor is visible and not inside horizontal
9176 scroll margins for all windows in the tree rooted at WINDOW. See
9177 also hscroll_window_tree above. Value is non-zero if any window's
9178 hscroll has been changed. If it has, desired matrices on the frame
9179 of WINDOW are cleared. */
9180
9181 static int
9182 hscroll_windows (window)
9183 Lisp_Object window;
9184 {
9185 int hscrolled_p;
9186
9187 if (automatic_hscrolling_p)
9188 {
9189 hscrolled_p = hscroll_window_tree (window);
9190 if (hscrolled_p)
9191 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9192 }
9193 else
9194 hscrolled_p = 0;
9195 return hscrolled_p;
9196 }
9197
9198
9199 \f
9200 /************************************************************************
9201 Redisplay
9202 ************************************************************************/
9203
9204 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9205 to a non-zero value. This is sometimes handy to have in a debugger
9206 session. */
9207
9208 #if GLYPH_DEBUG
9209
9210 /* First and last unchanged row for try_window_id. */
9211
9212 int debug_first_unchanged_at_end_vpos;
9213 int debug_last_unchanged_at_beg_vpos;
9214
9215 /* Delta vpos and y. */
9216
9217 int debug_dvpos, debug_dy;
9218
9219 /* Delta in characters and bytes for try_window_id. */
9220
9221 int debug_delta, debug_delta_bytes;
9222
9223 /* Values of window_end_pos and window_end_vpos at the end of
9224 try_window_id. */
9225
9226 EMACS_INT debug_end_pos, debug_end_vpos;
9227
9228 /* Append a string to W->desired_matrix->method. FMT is a printf
9229 format string. A1...A9 are a supplement for a variable-length
9230 argument list. If trace_redisplay_p is non-zero also printf the
9231 resulting string to stderr. */
9232
9233 static void
9234 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9235 struct window *w;
9236 char *fmt;
9237 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9238 {
9239 char buffer[512];
9240 char *method = w->desired_matrix->method;
9241 int len = strlen (method);
9242 int size = sizeof w->desired_matrix->method;
9243 int remaining = size - len - 1;
9244
9245 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9246 if (len && remaining)
9247 {
9248 method[len] = '|';
9249 --remaining, ++len;
9250 }
9251
9252 strncpy (method + len, buffer, remaining);
9253
9254 if (trace_redisplay_p)
9255 fprintf (stderr, "%p (%s): %s\n",
9256 w,
9257 ((BUFFERP (w->buffer)
9258 && STRINGP (XBUFFER (w->buffer)->name))
9259 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9260 : "no buffer"),
9261 buffer);
9262 }
9263
9264 #endif /* GLYPH_DEBUG */
9265
9266
9267 /* Value is non-zero if all changes in window W, which displays
9268 current_buffer, are in the text between START and END. START is a
9269 buffer position, END is given as a distance from Z. Used in
9270 redisplay_internal for display optimization. */
9271
9272 static INLINE int
9273 text_outside_line_unchanged_p (w, start, end)
9274 struct window *w;
9275 int start, end;
9276 {
9277 int unchanged_p = 1;
9278
9279 /* If text or overlays have changed, see where. */
9280 if (XFASTINT (w->last_modified) < MODIFF
9281 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9282 {
9283 /* Gap in the line? */
9284 if (GPT < start || Z - GPT < end)
9285 unchanged_p = 0;
9286
9287 /* Changes start in front of the line, or end after it? */
9288 if (unchanged_p
9289 && (BEG_UNCHANGED < start - 1
9290 || END_UNCHANGED < end))
9291 unchanged_p = 0;
9292
9293 /* If selective display, can't optimize if changes start at the
9294 beginning of the line. */
9295 if (unchanged_p
9296 && INTEGERP (current_buffer->selective_display)
9297 && XINT (current_buffer->selective_display) > 0
9298 && (BEG_UNCHANGED < start || GPT <= start))
9299 unchanged_p = 0;
9300
9301 /* If there are overlays at the start or end of the line, these
9302 may have overlay strings with newlines in them. A change at
9303 START, for instance, may actually concern the display of such
9304 overlay strings as well, and they are displayed on different
9305 lines. So, quickly rule out this case. (For the future, it
9306 might be desirable to implement something more telling than
9307 just BEG/END_UNCHANGED.) */
9308 if (unchanged_p)
9309 {
9310 if (BEG + BEG_UNCHANGED == start
9311 && overlay_touches_p (start))
9312 unchanged_p = 0;
9313 if (END_UNCHANGED == end
9314 && overlay_touches_p (Z - end))
9315 unchanged_p = 0;
9316 }
9317 }
9318
9319 return unchanged_p;
9320 }
9321
9322
9323 /* Do a frame update, taking possible shortcuts into account. This is
9324 the main external entry point for redisplay.
9325
9326 If the last redisplay displayed an echo area message and that message
9327 is no longer requested, we clear the echo area or bring back the
9328 mini-buffer if that is in use. */
9329
9330 void
9331 redisplay ()
9332 {
9333 redisplay_internal (0);
9334 }
9335
9336
9337 static Lisp_Object
9338 overlay_arrow_string_or_property (var, pbitmap)
9339 Lisp_Object var;
9340 int *pbitmap;
9341 {
9342 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9343 Lisp_Object bitmap;
9344
9345 if (pbitmap)
9346 {
9347 *pbitmap = 0;
9348 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9349 *pbitmap = XINT (bitmap);
9350 }
9351
9352 if (!NILP (pstr))
9353 return pstr;
9354 return Voverlay_arrow_string;
9355 }
9356
9357 /* Return 1 if there are any overlay-arrows in current_buffer. */
9358 static int
9359 overlay_arrow_in_current_buffer_p ()
9360 {
9361 Lisp_Object vlist;
9362
9363 for (vlist = Voverlay_arrow_variable_list;
9364 CONSP (vlist);
9365 vlist = XCDR (vlist))
9366 {
9367 Lisp_Object var = XCAR (vlist);
9368 Lisp_Object val;
9369
9370 if (!SYMBOLP (var))
9371 continue;
9372 val = find_symbol_value (var);
9373 if (MARKERP (val)
9374 && current_buffer == XMARKER (val)->buffer)
9375 return 1;
9376 }
9377 return 0;
9378 }
9379
9380
9381 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9382 has changed. */
9383
9384 static int
9385 overlay_arrows_changed_p ()
9386 {
9387 Lisp_Object vlist;
9388
9389 for (vlist = Voverlay_arrow_variable_list;
9390 CONSP (vlist);
9391 vlist = XCDR (vlist))
9392 {
9393 Lisp_Object var = XCAR (vlist);
9394 Lisp_Object val, pstr;
9395
9396 if (!SYMBOLP (var))
9397 continue;
9398 val = find_symbol_value (var);
9399 if (!MARKERP (val))
9400 continue;
9401 if (! EQ (COERCE_MARKER (val),
9402 Fget (var, Qlast_arrow_position))
9403 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9404 EQ (pstr, Fget (var, Qlast_arrow_string))))
9405 return 1;
9406 }
9407 return 0;
9408 }
9409
9410 /* Mark overlay arrows to be updated on next redisplay. */
9411
9412 static void
9413 update_overlay_arrows (up_to_date)
9414 int up_to_date;
9415 {
9416 Lisp_Object vlist;
9417
9418 for (vlist = Voverlay_arrow_variable_list;
9419 CONSP (vlist);
9420 vlist = XCDR (vlist))
9421 {
9422 Lisp_Object var = XCAR (vlist);
9423
9424 if (!SYMBOLP (var))
9425 continue;
9426
9427 if (up_to_date > 0)
9428 {
9429 Lisp_Object val = find_symbol_value (var);
9430 Fput (var, Qlast_arrow_position,
9431 COERCE_MARKER (val));
9432 Fput (var, Qlast_arrow_string,
9433 overlay_arrow_string_or_property (var, 0));
9434 }
9435 else if (up_to_date < 0
9436 || !NILP (Fget (var, Qlast_arrow_position)))
9437 {
9438 Fput (var, Qlast_arrow_position, Qt);
9439 Fput (var, Qlast_arrow_string, Qt);
9440 }
9441 }
9442 }
9443
9444
9445 /* Return overlay arrow string at row, or nil. */
9446
9447 static Lisp_Object
9448 overlay_arrow_at_row (f, row, pbitmap)
9449 struct frame *f;
9450 struct glyph_row *row;
9451 int *pbitmap;
9452 {
9453 Lisp_Object vlist;
9454
9455 for (vlist = Voverlay_arrow_variable_list;
9456 CONSP (vlist);
9457 vlist = XCDR (vlist))
9458 {
9459 Lisp_Object var = XCAR (vlist);
9460 Lisp_Object val;
9461
9462 if (!SYMBOLP (var))
9463 continue;
9464
9465 val = find_symbol_value (var);
9466
9467 if (MARKERP (val)
9468 && current_buffer == XMARKER (val)->buffer
9469 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9470 {
9471 val = overlay_arrow_string_or_property (var, pbitmap);
9472 if (FRAME_WINDOW_P (f))
9473 return Qt;
9474 else if (STRINGP (val))
9475 return val;
9476 break;
9477 }
9478 }
9479
9480 *pbitmap = 0;
9481 return Qnil;
9482 }
9483
9484 /* Return 1 if point moved out of or into a composition. Otherwise
9485 return 0. PREV_BUF and PREV_PT are the last point buffer and
9486 position. BUF and PT are the current point buffer and position. */
9487
9488 int
9489 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9490 struct buffer *prev_buf, *buf;
9491 int prev_pt, pt;
9492 {
9493 int start, end;
9494 Lisp_Object prop;
9495 Lisp_Object buffer;
9496
9497 XSETBUFFER (buffer, buf);
9498 /* Check a composition at the last point if point moved within the
9499 same buffer. */
9500 if (prev_buf == buf)
9501 {
9502 if (prev_pt == pt)
9503 /* Point didn't move. */
9504 return 0;
9505
9506 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9507 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9508 && COMPOSITION_VALID_P (start, end, prop)
9509 && start < prev_pt && end > prev_pt)
9510 /* The last point was within the composition. Return 1 iff
9511 point moved out of the composition. */
9512 return (pt <= start || pt >= end);
9513 }
9514
9515 /* Check a composition at the current point. */
9516 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9517 && find_composition (pt, -1, &start, &end, &prop, buffer)
9518 && COMPOSITION_VALID_P (start, end, prop)
9519 && start < pt && end > pt);
9520 }
9521
9522
9523 /* Reconsider the setting of B->clip_changed which is displayed
9524 in window W. */
9525
9526 static INLINE void
9527 reconsider_clip_changes (w, b)
9528 struct window *w;
9529 struct buffer *b;
9530 {
9531 if (b->clip_changed
9532 && !NILP (w->window_end_valid)
9533 && w->current_matrix->buffer == b
9534 && w->current_matrix->zv == BUF_ZV (b)
9535 && w->current_matrix->begv == BUF_BEGV (b))
9536 b->clip_changed = 0;
9537
9538 /* If display wasn't paused, and W is not a tool bar window, see if
9539 point has been moved into or out of a composition. In that case,
9540 we set b->clip_changed to 1 to force updating the screen. If
9541 b->clip_changed has already been set to 1, we can skip this
9542 check. */
9543 if (!b->clip_changed
9544 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9545 {
9546 int pt;
9547
9548 if (w == XWINDOW (selected_window))
9549 pt = BUF_PT (current_buffer);
9550 else
9551 pt = marker_position (w->pointm);
9552
9553 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9554 || pt != XINT (w->last_point))
9555 && check_point_in_composition (w->current_matrix->buffer,
9556 XINT (w->last_point),
9557 XBUFFER (w->buffer), pt))
9558 b->clip_changed = 1;
9559 }
9560 }
9561 \f
9562
9563 /* Select FRAME to forward the values of frame-local variables into C
9564 variables so that the redisplay routines can access those values
9565 directly. */
9566
9567 static void
9568 select_frame_for_redisplay (frame)
9569 Lisp_Object frame;
9570 {
9571 Lisp_Object tail, sym, val;
9572 Lisp_Object old = selected_frame;
9573
9574 selected_frame = frame;
9575
9576 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9577 if (CONSP (XCAR (tail))
9578 && (sym = XCAR (XCAR (tail)),
9579 SYMBOLP (sym))
9580 && (sym = indirect_variable (sym),
9581 val = SYMBOL_VALUE (sym),
9582 (BUFFER_LOCAL_VALUEP (val)
9583 || SOME_BUFFER_LOCAL_VALUEP (val)))
9584 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9585 Fsymbol_value (sym);
9586
9587 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9588 if (CONSP (XCAR (tail))
9589 && (sym = XCAR (XCAR (tail)),
9590 SYMBOLP (sym))
9591 && (sym = indirect_variable (sym),
9592 val = SYMBOL_VALUE (sym),
9593 (BUFFER_LOCAL_VALUEP (val)
9594 || SOME_BUFFER_LOCAL_VALUEP (val)))
9595 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9596 Fsymbol_value (sym);
9597 }
9598
9599
9600 #define STOP_POLLING \
9601 do { if (! polling_stopped_here) stop_polling (); \
9602 polling_stopped_here = 1; } while (0)
9603
9604 #define RESUME_POLLING \
9605 do { if (polling_stopped_here) start_polling (); \
9606 polling_stopped_here = 0; } while (0)
9607
9608
9609 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9610 response to any user action; therefore, we should preserve the echo
9611 area. (Actually, our caller does that job.) Perhaps in the future
9612 avoid recentering windows if it is not necessary; currently that
9613 causes some problems. */
9614
9615 static void
9616 redisplay_internal (preserve_echo_area)
9617 int preserve_echo_area;
9618 {
9619 struct window *w = XWINDOW (selected_window);
9620 struct frame *f = XFRAME (w->frame);
9621 int pause;
9622 int must_finish = 0;
9623 struct text_pos tlbufpos, tlendpos;
9624 int number_of_visible_frames;
9625 int count;
9626 struct frame *sf = SELECTED_FRAME ();
9627 int polling_stopped_here = 0;
9628
9629 /* Non-zero means redisplay has to consider all windows on all
9630 frames. Zero means, only selected_window is considered. */
9631 int consider_all_windows_p;
9632
9633 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9634
9635 /* No redisplay if running in batch mode or frame is not yet fully
9636 initialized, or redisplay is explicitly turned off by setting
9637 Vinhibit_redisplay. */
9638 if (noninteractive
9639 || !NILP (Vinhibit_redisplay)
9640 || !f->glyphs_initialized_p)
9641 return;
9642
9643 /* The flag redisplay_performed_directly_p is set by
9644 direct_output_for_insert when it already did the whole screen
9645 update necessary. */
9646 if (redisplay_performed_directly_p)
9647 {
9648 redisplay_performed_directly_p = 0;
9649 if (!hscroll_windows (selected_window))
9650 return;
9651 }
9652
9653 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9654 if (popup_activated ())
9655 return;
9656 #endif
9657
9658 /* I don't think this happens but let's be paranoid. */
9659 if (redisplaying_p)
9660 return;
9661
9662 /* Record a function that resets redisplaying_p to its old value
9663 when we leave this function. */
9664 count = SPECPDL_INDEX ();
9665 record_unwind_protect (unwind_redisplay,
9666 Fcons (make_number (redisplaying_p), selected_frame));
9667 ++redisplaying_p;
9668 specbind (Qinhibit_free_realized_faces, Qnil);
9669
9670 retry:
9671 pause = 0;
9672 reconsider_clip_changes (w, current_buffer);
9673
9674 /* If new fonts have been loaded that make a glyph matrix adjustment
9675 necessary, do it. */
9676 if (fonts_changed_p)
9677 {
9678 adjust_glyphs (NULL);
9679 ++windows_or_buffers_changed;
9680 fonts_changed_p = 0;
9681 }
9682
9683 /* If face_change_count is non-zero, init_iterator will free all
9684 realized faces, which includes the faces referenced from current
9685 matrices. So, we can't reuse current matrices in this case. */
9686 if (face_change_count)
9687 ++windows_or_buffers_changed;
9688
9689 if (FRAME_TERMCAP_P (sf)
9690 && FRAME_TTY (sf)->previous_terminal_frame != sf)
9691 {
9692 /* Since frames on a single ASCII terminal share the same
9693 display area, displaying a different frame means redisplay
9694 the whole thing. */
9695 windows_or_buffers_changed++;
9696 SET_FRAME_GARBAGED (sf);
9697 FRAME_TTY (sf)->previous_terminal_frame = sf;
9698 }
9699
9700 /* Set the visible flags for all frames. Do this before checking
9701 for resized or garbaged frames; they want to know if their frames
9702 are visible. See the comment in frame.h for
9703 FRAME_SAMPLE_VISIBILITY. */
9704 {
9705 Lisp_Object tail, frame;
9706
9707 number_of_visible_frames = 0;
9708
9709 FOR_EACH_FRAME (tail, frame)
9710 {
9711 struct frame *f = XFRAME (frame);
9712
9713 FRAME_SAMPLE_VISIBILITY (f);
9714 if (FRAME_VISIBLE_P (f))
9715 ++number_of_visible_frames;
9716 clear_desired_matrices (f);
9717 }
9718 }
9719
9720
9721 /* Notice any pending interrupt request to change frame size. */
9722 do_pending_window_change (1);
9723
9724 /* Clear frames marked as garbaged. */
9725 if (frame_garbaged)
9726 clear_garbaged_frames ();
9727
9728 /* Build menubar and tool-bar items. */
9729 prepare_menu_bars ();
9730
9731 if (windows_or_buffers_changed)
9732 update_mode_lines++;
9733
9734 /* Detect case that we need to write or remove a star in the mode line. */
9735 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9736 {
9737 w->update_mode_line = Qt;
9738 if (buffer_shared > 1)
9739 update_mode_lines++;
9740 }
9741
9742 /* If %c is in the mode line, update it if needed. */
9743 if (!NILP (w->column_number_displayed)
9744 /* This alternative quickly identifies a common case
9745 where no change is needed. */
9746 && !(PT == XFASTINT (w->last_point)
9747 && XFASTINT (w->last_modified) >= MODIFF
9748 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9749 && (XFASTINT (w->column_number_displayed)
9750 != (int) current_column ())) /* iftc */
9751 w->update_mode_line = Qt;
9752
9753 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9754
9755 /* The variable buffer_shared is set in redisplay_window and
9756 indicates that we redisplay a buffer in different windows. See
9757 there. */
9758 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9759 || cursor_type_changed);
9760
9761 /* If specs for an arrow have changed, do thorough redisplay
9762 to ensure we remove any arrow that should no longer exist. */
9763 if (overlay_arrows_changed_p ())
9764 consider_all_windows_p = windows_or_buffers_changed = 1;
9765
9766 /* Normally the message* functions will have already displayed and
9767 updated the echo area, but the frame may have been trashed, or
9768 the update may have been preempted, so display the echo area
9769 again here. Checking message_cleared_p captures the case that
9770 the echo area should be cleared. */
9771 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9772 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9773 || (message_cleared_p
9774 && minibuf_level == 0
9775 /* If the mini-window is currently selected, this means the
9776 echo-area doesn't show through. */
9777 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9778 {
9779 int window_height_changed_p = echo_area_display (0);
9780 must_finish = 1;
9781
9782 /* If we don't display the current message, don't clear the
9783 message_cleared_p flag, because, if we did, we wouldn't clear
9784 the echo area in the next redisplay which doesn't preserve
9785 the echo area. */
9786 if (!display_last_displayed_message_p)
9787 message_cleared_p = 0;
9788
9789 if (fonts_changed_p)
9790 goto retry;
9791 else if (window_height_changed_p)
9792 {
9793 consider_all_windows_p = 1;
9794 ++update_mode_lines;
9795 ++windows_or_buffers_changed;
9796
9797 /* If window configuration was changed, frames may have been
9798 marked garbaged. Clear them or we will experience
9799 surprises wrt scrolling. */
9800 if (frame_garbaged)
9801 clear_garbaged_frames ();
9802 }
9803 }
9804 else if (EQ (selected_window, minibuf_window)
9805 && (current_buffer->clip_changed
9806 || XFASTINT (w->last_modified) < MODIFF
9807 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9808 && resize_mini_window (w, 0))
9809 {
9810 /* Resized active mini-window to fit the size of what it is
9811 showing if its contents might have changed. */
9812 must_finish = 1;
9813 consider_all_windows_p = 1;
9814 ++windows_or_buffers_changed;
9815 ++update_mode_lines;
9816
9817 /* If window configuration was changed, frames may have been
9818 marked garbaged. Clear them or we will experience
9819 surprises wrt scrolling. */
9820 if (frame_garbaged)
9821 clear_garbaged_frames ();
9822 }
9823
9824
9825 /* If showing the region, and mark has changed, we must redisplay
9826 the whole window. The assignment to this_line_start_pos prevents
9827 the optimization directly below this if-statement. */
9828 if (((!NILP (Vtransient_mark_mode)
9829 && !NILP (XBUFFER (w->buffer)->mark_active))
9830 != !NILP (w->region_showing))
9831 || (!NILP (w->region_showing)
9832 && !EQ (w->region_showing,
9833 Fmarker_position (XBUFFER (w->buffer)->mark))))
9834 CHARPOS (this_line_start_pos) = 0;
9835
9836 /* Optimize the case that only the line containing the cursor in the
9837 selected window has changed. Variables starting with this_ are
9838 set in display_line and record information about the line
9839 containing the cursor. */
9840 tlbufpos = this_line_start_pos;
9841 tlendpos = this_line_end_pos;
9842 if (!consider_all_windows_p
9843 && CHARPOS (tlbufpos) > 0
9844 && NILP (w->update_mode_line)
9845 && !current_buffer->clip_changed
9846 && !current_buffer->prevent_redisplay_optimizations_p
9847 && FRAME_VISIBLE_P (XFRAME (w->frame))
9848 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9849 /* Make sure recorded data applies to current buffer, etc. */
9850 && this_line_buffer == current_buffer
9851 && current_buffer == XBUFFER (w->buffer)
9852 && NILP (w->force_start)
9853 && NILP (w->optional_new_start)
9854 /* Point must be on the line that we have info recorded about. */
9855 && PT >= CHARPOS (tlbufpos)
9856 && PT <= Z - CHARPOS (tlendpos)
9857 /* All text outside that line, including its final newline,
9858 must be unchanged */
9859 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9860 CHARPOS (tlendpos)))
9861 {
9862 if (CHARPOS (tlbufpos) > BEGV
9863 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9864 && (CHARPOS (tlbufpos) == ZV
9865 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9866 /* Former continuation line has disappeared by becoming empty */
9867 goto cancel;
9868 else if (XFASTINT (w->last_modified) < MODIFF
9869 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9870 || MINI_WINDOW_P (w))
9871 {
9872 /* We have to handle the case of continuation around a
9873 wide-column character (See the comment in indent.c around
9874 line 885).
9875
9876 For instance, in the following case:
9877
9878 -------- Insert --------
9879 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9880 J_I_ ==> J_I_ `^^' are cursors.
9881 ^^ ^^
9882 -------- --------
9883
9884 As we have to redraw the line above, we should goto cancel. */
9885
9886 struct it it;
9887 int line_height_before = this_line_pixel_height;
9888
9889 /* Note that start_display will handle the case that the
9890 line starting at tlbufpos is a continuation lines. */
9891 start_display (&it, w, tlbufpos);
9892
9893 /* Implementation note: It this still necessary? */
9894 if (it.current_x != this_line_start_x)
9895 goto cancel;
9896
9897 TRACE ((stderr, "trying display optimization 1\n"));
9898 w->cursor.vpos = -1;
9899 overlay_arrow_seen = 0;
9900 it.vpos = this_line_vpos;
9901 it.current_y = this_line_y;
9902 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9903 display_line (&it);
9904
9905 /* If line contains point, is not continued,
9906 and ends at same distance from eob as before, we win */
9907 if (w->cursor.vpos >= 0
9908 /* Line is not continued, otherwise this_line_start_pos
9909 would have been set to 0 in display_line. */
9910 && CHARPOS (this_line_start_pos)
9911 /* Line ends as before. */
9912 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9913 /* Line has same height as before. Otherwise other lines
9914 would have to be shifted up or down. */
9915 && this_line_pixel_height == line_height_before)
9916 {
9917 /* If this is not the window's last line, we must adjust
9918 the charstarts of the lines below. */
9919 if (it.current_y < it.last_visible_y)
9920 {
9921 struct glyph_row *row
9922 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9923 int delta, delta_bytes;
9924
9925 if (Z - CHARPOS (tlendpos) == ZV)
9926 {
9927 /* This line ends at end of (accessible part of)
9928 buffer. There is no newline to count. */
9929 delta = (Z
9930 - CHARPOS (tlendpos)
9931 - MATRIX_ROW_START_CHARPOS (row));
9932 delta_bytes = (Z_BYTE
9933 - BYTEPOS (tlendpos)
9934 - MATRIX_ROW_START_BYTEPOS (row));
9935 }
9936 else
9937 {
9938 /* This line ends in a newline. Must take
9939 account of the newline and the rest of the
9940 text that follows. */
9941 delta = (Z
9942 - CHARPOS (tlendpos)
9943 - MATRIX_ROW_START_CHARPOS (row));
9944 delta_bytes = (Z_BYTE
9945 - BYTEPOS (tlendpos)
9946 - MATRIX_ROW_START_BYTEPOS (row));
9947 }
9948
9949 increment_matrix_positions (w->current_matrix,
9950 this_line_vpos + 1,
9951 w->current_matrix->nrows,
9952 delta, delta_bytes);
9953 }
9954
9955 /* If this row displays text now but previously didn't,
9956 or vice versa, w->window_end_vpos may have to be
9957 adjusted. */
9958 if ((it.glyph_row - 1)->displays_text_p)
9959 {
9960 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
9961 XSETINT (w->window_end_vpos, this_line_vpos);
9962 }
9963 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
9964 && this_line_vpos > 0)
9965 XSETINT (w->window_end_vpos, this_line_vpos - 1);
9966 w->window_end_valid = Qnil;
9967
9968 /* Update hint: No need to try to scroll in update_window. */
9969 w->desired_matrix->no_scrolling_p = 1;
9970
9971 #if GLYPH_DEBUG
9972 *w->desired_matrix->method = 0;
9973 debug_method_add (w, "optimization 1");
9974 #endif
9975 #ifdef HAVE_WINDOW_SYSTEM
9976 update_window_fringes (w, 0);
9977 #endif
9978 goto update;
9979 }
9980 else
9981 goto cancel;
9982 }
9983 else if (/* Cursor position hasn't changed. */
9984 PT == XFASTINT (w->last_point)
9985 /* Make sure the cursor was last displayed
9986 in this window. Otherwise we have to reposition it. */
9987 && 0 <= w->cursor.vpos
9988 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
9989 {
9990 if (!must_finish)
9991 {
9992 do_pending_window_change (1);
9993
9994 /* We used to always goto end_of_redisplay here, but this
9995 isn't enough if we have a blinking cursor. */
9996 if (w->cursor_off_p == w->last_cursor_off_p)
9997 goto end_of_redisplay;
9998 }
9999 goto update;
10000 }
10001 /* If highlighting the region, or if the cursor is in the echo area,
10002 then we can't just move the cursor. */
10003 else if (! (!NILP (Vtransient_mark_mode)
10004 && !NILP (current_buffer->mark_active))
10005 && (EQ (selected_window, current_buffer->last_selected_window)
10006 || highlight_nonselected_windows)
10007 && NILP (w->region_showing)
10008 && NILP (Vshow_trailing_whitespace)
10009 && !cursor_in_echo_area)
10010 {
10011 struct it it;
10012 struct glyph_row *row;
10013
10014 /* Skip from tlbufpos to PT and see where it is. Note that
10015 PT may be in invisible text. If so, we will end at the
10016 next visible position. */
10017 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10018 NULL, DEFAULT_FACE_ID);
10019 it.current_x = this_line_start_x;
10020 it.current_y = this_line_y;
10021 it.vpos = this_line_vpos;
10022
10023 /* The call to move_it_to stops in front of PT, but
10024 moves over before-strings. */
10025 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10026
10027 if (it.vpos == this_line_vpos
10028 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10029 row->enabled_p))
10030 {
10031 xassert (this_line_vpos == it.vpos);
10032 xassert (this_line_y == it.current_y);
10033 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10034 #if GLYPH_DEBUG
10035 *w->desired_matrix->method = 0;
10036 debug_method_add (w, "optimization 3");
10037 #endif
10038 goto update;
10039 }
10040 else
10041 goto cancel;
10042 }
10043
10044 cancel:
10045 /* Text changed drastically or point moved off of line. */
10046 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10047 }
10048
10049 CHARPOS (this_line_start_pos) = 0;
10050 consider_all_windows_p |= buffer_shared > 1;
10051 ++clear_face_cache_count;
10052
10053
10054 /* Build desired matrices, and update the display. If
10055 consider_all_windows_p is non-zero, do it for all windows on all
10056 frames. Otherwise do it for selected_window, only. */
10057
10058 if (consider_all_windows_p)
10059 {
10060 Lisp_Object tail, frame;
10061 int i, n = 0, size = 50;
10062 struct frame **updated
10063 = (struct frame **) alloca (size * sizeof *updated);
10064
10065 /* Clear the face cache eventually. */
10066 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10067 {
10068 clear_face_cache (0);
10069 clear_face_cache_count = 0;
10070 }
10071
10072 /* Recompute # windows showing selected buffer. This will be
10073 incremented each time such a window is displayed. */
10074 buffer_shared = 0;
10075
10076 FOR_EACH_FRAME (tail, frame)
10077 {
10078 struct frame *f = XFRAME (frame);
10079
10080 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
10081 {
10082 if (! EQ (frame, selected_frame))
10083 /* Select the frame, for the sake of frame-local
10084 variables. */
10085 select_frame_for_redisplay (frame);
10086
10087 #ifdef HAVE_WINDOW_SYSTEM
10088 if (clear_face_cache_count % 50 == 0
10089 && FRAME_WINDOW_P (f))
10090 clear_image_cache (f, 0);
10091 #endif /* HAVE_WINDOW_SYSTEM */
10092
10093 /* Mark all the scroll bars to be removed; we'll redeem
10094 the ones we want when we redisplay their windows. */
10095 if (FRAME_DISPLAY (f)->condemn_scroll_bars_hook)
10096 FRAME_DISPLAY (f)->condemn_scroll_bars_hook (f);
10097
10098 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10099 redisplay_windows (FRAME_ROOT_WINDOW (f));
10100
10101 /* Any scroll bars which redisplay_windows should have
10102 nuked should now go away. */
10103 if (FRAME_DISPLAY (f)->judge_scroll_bars_hook)
10104 FRAME_DISPLAY (f)->judge_scroll_bars_hook (f);
10105
10106 /* If fonts changed, display again. */
10107 /* ??? rms: I suspect it is a mistake to jump all the way
10108 back to retry here. It should just retry this frame. */
10109 if (fonts_changed_p)
10110 goto retry;
10111
10112 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10113 {
10114 /* See if we have to hscroll. */
10115 if (hscroll_windows (f->root_window))
10116 goto retry;
10117
10118 /* Prevent various kinds of signals during display
10119 update. stdio is not robust about handling
10120 signals, which can cause an apparent I/O
10121 error. */
10122 if (interrupt_input)
10123 unrequest_sigio ();
10124 STOP_POLLING;
10125
10126 /* Update the display. */
10127 set_window_update_flags (XWINDOW (f->root_window), 1);
10128 pause |= update_frame (f, 0, 0);
10129 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10130 if (pause)
10131 break;
10132 #endif
10133
10134 if (n == size)
10135 {
10136 int nbytes = size * sizeof *updated;
10137 struct frame **p = (struct frame **) alloca (2 * nbytes);
10138 bcopy (updated, p, nbytes);
10139 size *= 2;
10140 }
10141
10142 updated[n++] = f;
10143 }
10144 }
10145 }
10146
10147 if (!pause)
10148 {
10149 /* Do the mark_window_display_accurate after all windows have
10150 been redisplayed because this call resets flags in buffers
10151 which are needed for proper redisplay. */
10152 for (i = 0; i < n; ++i)
10153 {
10154 struct frame *f = updated[i];
10155 mark_window_display_accurate (f->root_window, 1);
10156 if (FRAME_DISPLAY (f)->frame_up_to_date_hook)
10157 FRAME_DISPLAY (f)->frame_up_to_date_hook (f);
10158 }
10159 }
10160 }
10161 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10162 {
10163 Lisp_Object mini_window;
10164 struct frame *mini_frame;
10165
10166 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10167 /* Use list_of_error, not Qerror, so that
10168 we catch only errors and don't run the debugger. */
10169 internal_condition_case_1 (redisplay_window_1, selected_window,
10170 list_of_error,
10171 redisplay_window_error);
10172
10173 /* Compare desired and current matrices, perform output. */
10174
10175 update:
10176 /* If fonts changed, display again. */
10177 if (fonts_changed_p)
10178 goto retry;
10179
10180 /* Prevent various kinds of signals during display update.
10181 stdio is not robust about handling signals,
10182 which can cause an apparent I/O error. */
10183 if (interrupt_input)
10184 unrequest_sigio ();
10185 STOP_POLLING;
10186
10187 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10188 {
10189 if (hscroll_windows (selected_window))
10190 goto retry;
10191
10192 XWINDOW (selected_window)->must_be_updated_p = 1;
10193 pause = update_frame (sf, 0, 0);
10194 }
10195
10196 /* We may have called echo_area_display at the top of this
10197 function. If the echo area is on another frame, that may
10198 have put text on a frame other than the selected one, so the
10199 above call to update_frame would not have caught it. Catch
10200 it here. */
10201 mini_window = FRAME_MINIBUF_WINDOW (sf);
10202 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10203
10204 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10205 {
10206 XWINDOW (mini_window)->must_be_updated_p = 1;
10207 pause |= update_frame (mini_frame, 0, 0);
10208 if (!pause && hscroll_windows (mini_window))
10209 goto retry;
10210 }
10211 }
10212
10213 /* If display was paused because of pending input, make sure we do a
10214 thorough update the next time. */
10215 if (pause)
10216 {
10217 /* Prevent the optimization at the beginning of
10218 redisplay_internal that tries a single-line update of the
10219 line containing the cursor in the selected window. */
10220 CHARPOS (this_line_start_pos) = 0;
10221
10222 /* Let the overlay arrow be updated the next time. */
10223 update_overlay_arrows (0);
10224
10225 /* If we pause after scrolling, some rows in the current
10226 matrices of some windows are not valid. */
10227 if (!WINDOW_FULL_WIDTH_P (w)
10228 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10229 update_mode_lines = 1;
10230 }
10231 else
10232 {
10233 if (!consider_all_windows_p)
10234 {
10235 /* This has already been done above if
10236 consider_all_windows_p is set. */
10237 mark_window_display_accurate_1 (w, 1);
10238
10239 /* Say overlay arrows are up to date. */
10240 update_overlay_arrows (1);
10241
10242 if (FRAME_DISPLAY (sf)->frame_up_to_date_hook != 0)
10243 FRAME_DISPLAY (sf)->frame_up_to_date_hook (sf);
10244 }
10245
10246 update_mode_lines = 0;
10247 windows_or_buffers_changed = 0;
10248 cursor_type_changed = 0;
10249 }
10250
10251 /* Start SIGIO interrupts coming again. Having them off during the
10252 code above makes it less likely one will discard output, but not
10253 impossible, since there might be stuff in the system buffer here.
10254 But it is much hairier to try to do anything about that. */
10255 if (interrupt_input)
10256 request_sigio ();
10257 RESUME_POLLING;
10258
10259 /* If a frame has become visible which was not before, redisplay
10260 again, so that we display it. Expose events for such a frame
10261 (which it gets when becoming visible) don't call the parts of
10262 redisplay constructing glyphs, so simply exposing a frame won't
10263 display anything in this case. So, we have to display these
10264 frames here explicitly. */
10265 if (!pause)
10266 {
10267 Lisp_Object tail, frame;
10268 int new_count = 0;
10269
10270 FOR_EACH_FRAME (tail, frame)
10271 {
10272 int this_is_visible = 0;
10273
10274 if (XFRAME (frame)->visible)
10275 this_is_visible = 1;
10276 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10277 if (XFRAME (frame)->visible)
10278 this_is_visible = 1;
10279
10280 if (this_is_visible)
10281 new_count++;
10282 }
10283
10284 if (new_count != number_of_visible_frames)
10285 windows_or_buffers_changed++;
10286 }
10287
10288 /* Change frame size now if a change is pending. */
10289 do_pending_window_change (1);
10290
10291 /* If we just did a pending size change, or have additional
10292 visible frames, redisplay again. */
10293 if (windows_or_buffers_changed && !pause)
10294 goto retry;
10295
10296 end_of_redisplay:
10297 unbind_to (count, Qnil);
10298 RESUME_POLLING;
10299 }
10300
10301
10302 /* Redisplay, but leave alone any recent echo area message unless
10303 another message has been requested in its place.
10304
10305 This is useful in situations where you need to redisplay but no
10306 user action has occurred, making it inappropriate for the message
10307 area to be cleared. See tracking_off and
10308 wait_reading_process_input for examples of these situations.
10309
10310 FROM_WHERE is an integer saying from where this function was
10311 called. This is useful for debugging. */
10312
10313 void
10314 redisplay_preserve_echo_area (from_where)
10315 int from_where;
10316 {
10317 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10318
10319 if (!NILP (echo_area_buffer[1]))
10320 {
10321 /* We have a previously displayed message, but no current
10322 message. Redisplay the previous message. */
10323 display_last_displayed_message_p = 1;
10324 redisplay_internal (1);
10325 display_last_displayed_message_p = 0;
10326 }
10327 else
10328 redisplay_internal (1);
10329 }
10330
10331
10332 /* Function registered with record_unwind_protect in
10333 redisplay_internal. Reset redisplaying_p to the value it had
10334 before redisplay_internal was called, and clear
10335 prevent_freeing_realized_faces_p. It also selects the previously
10336 selected frame. */
10337
10338 static Lisp_Object
10339 unwind_redisplay (val)
10340 Lisp_Object val;
10341 {
10342 Lisp_Object old_redisplaying_p, old_frame;
10343
10344 old_redisplaying_p = XCAR (val);
10345 redisplaying_p = XFASTINT (old_redisplaying_p);
10346 old_frame = XCDR (val);
10347 if (! EQ (old_frame, selected_frame))
10348 select_frame_for_redisplay (old_frame);
10349 return Qnil;
10350 }
10351
10352
10353 /* Mark the display of window W as accurate or inaccurate. If
10354 ACCURATE_P is non-zero mark display of W as accurate. If
10355 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10356 redisplay_internal is called. */
10357
10358 static void
10359 mark_window_display_accurate_1 (w, accurate_p)
10360 struct window *w;
10361 int accurate_p;
10362 {
10363 if (BUFFERP (w->buffer))
10364 {
10365 struct buffer *b = XBUFFER (w->buffer);
10366
10367 w->last_modified
10368 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10369 w->last_overlay_modified
10370 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10371 w->last_had_star
10372 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10373
10374 if (accurate_p)
10375 {
10376 b->clip_changed = 0;
10377 b->prevent_redisplay_optimizations_p = 0;
10378
10379 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10380 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10381 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10382 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10383
10384 w->current_matrix->buffer = b;
10385 w->current_matrix->begv = BUF_BEGV (b);
10386 w->current_matrix->zv = BUF_ZV (b);
10387
10388 w->last_cursor = w->cursor;
10389 w->last_cursor_off_p = w->cursor_off_p;
10390
10391 if (w == XWINDOW (selected_window))
10392 w->last_point = make_number (BUF_PT (b));
10393 else
10394 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10395 }
10396 }
10397
10398 if (accurate_p)
10399 {
10400 w->window_end_valid = w->buffer;
10401 #if 0 /* This is incorrect with variable-height lines. */
10402 xassert (XINT (w->window_end_vpos)
10403 < (WINDOW_TOTAL_LINES (w)
10404 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10405 #endif
10406 w->update_mode_line = Qnil;
10407 }
10408 }
10409
10410
10411 /* Mark the display of windows in the window tree rooted at WINDOW as
10412 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10413 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10414 be redisplayed the next time redisplay_internal is called. */
10415
10416 void
10417 mark_window_display_accurate (window, accurate_p)
10418 Lisp_Object window;
10419 int accurate_p;
10420 {
10421 struct window *w;
10422
10423 for (; !NILP (window); window = w->next)
10424 {
10425 w = XWINDOW (window);
10426 mark_window_display_accurate_1 (w, accurate_p);
10427
10428 if (!NILP (w->vchild))
10429 mark_window_display_accurate (w->vchild, accurate_p);
10430 if (!NILP (w->hchild))
10431 mark_window_display_accurate (w->hchild, accurate_p);
10432 }
10433
10434 if (accurate_p)
10435 {
10436 update_overlay_arrows (1);
10437 }
10438 else
10439 {
10440 /* Force a thorough redisplay the next time by setting
10441 last_arrow_position and last_arrow_string to t, which is
10442 unequal to any useful value of Voverlay_arrow_... */
10443 update_overlay_arrows (-1);
10444 }
10445 }
10446
10447
10448 /* Return value in display table DP (Lisp_Char_Table *) for character
10449 C. Since a display table doesn't have any parent, we don't have to
10450 follow parent. Do not call this function directly but use the
10451 macro DISP_CHAR_VECTOR. */
10452
10453 Lisp_Object
10454 disp_char_vector (dp, c)
10455 struct Lisp_Char_Table *dp;
10456 int c;
10457 {
10458 int code[4], i;
10459 Lisp_Object val;
10460
10461 if (SINGLE_BYTE_CHAR_P (c))
10462 return (dp->contents[c]);
10463
10464 SPLIT_CHAR (c, code[0], code[1], code[2]);
10465 if (code[1] < 32)
10466 code[1] = -1;
10467 else if (code[2] < 32)
10468 code[2] = -1;
10469
10470 /* Here, the possible range of code[0] (== charset ID) is
10471 128..max_charset. Since the top level char table contains data
10472 for multibyte characters after 256th element, we must increment
10473 code[0] by 128 to get a correct index. */
10474 code[0] += 128;
10475 code[3] = -1; /* anchor */
10476
10477 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10478 {
10479 val = dp->contents[code[i]];
10480 if (!SUB_CHAR_TABLE_P (val))
10481 return (NILP (val) ? dp->defalt : val);
10482 }
10483
10484 /* Here, val is a sub char table. We return the default value of
10485 it. */
10486 return (dp->defalt);
10487 }
10488
10489
10490 \f
10491 /***********************************************************************
10492 Window Redisplay
10493 ***********************************************************************/
10494
10495 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10496
10497 static void
10498 redisplay_windows (window)
10499 Lisp_Object window;
10500 {
10501 while (!NILP (window))
10502 {
10503 struct window *w = XWINDOW (window);
10504
10505 if (!NILP (w->hchild))
10506 redisplay_windows (w->hchild);
10507 else if (!NILP (w->vchild))
10508 redisplay_windows (w->vchild);
10509 else
10510 {
10511 displayed_buffer = XBUFFER (w->buffer);
10512 /* Use list_of_error, not Qerror, so that
10513 we catch only errors and don't run the debugger. */
10514 internal_condition_case_1 (redisplay_window_0, window,
10515 list_of_error,
10516 redisplay_window_error);
10517 }
10518
10519 window = w->next;
10520 }
10521 }
10522
10523 static Lisp_Object
10524 redisplay_window_error ()
10525 {
10526 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10527 return Qnil;
10528 }
10529
10530 static Lisp_Object
10531 redisplay_window_0 (window)
10532 Lisp_Object window;
10533 {
10534 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10535 redisplay_window (window, 0);
10536 return Qnil;
10537 }
10538
10539 static Lisp_Object
10540 redisplay_window_1 (window)
10541 Lisp_Object window;
10542 {
10543 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10544 redisplay_window (window, 1);
10545 return Qnil;
10546 }
10547 \f
10548
10549 /* Increment GLYPH until it reaches END or CONDITION fails while
10550 adding (GLYPH)->pixel_width to X. */
10551
10552 #define SKIP_GLYPHS(glyph, end, x, condition) \
10553 do \
10554 { \
10555 (x) += (glyph)->pixel_width; \
10556 ++(glyph); \
10557 } \
10558 while ((glyph) < (end) && (condition))
10559
10560
10561 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10562 DELTA is the number of bytes by which positions recorded in ROW
10563 differ from current buffer positions. */
10564
10565 void
10566 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10567 struct window *w;
10568 struct glyph_row *row;
10569 struct glyph_matrix *matrix;
10570 int delta, delta_bytes, dy, dvpos;
10571 {
10572 struct glyph *glyph = row->glyphs[TEXT_AREA];
10573 struct glyph *end = glyph + row->used[TEXT_AREA];
10574 /* The first glyph that starts a sequence of glyphs from string. */
10575 struct glyph *string_start;
10576 /* The X coordinate of string_start. */
10577 int string_start_x;
10578 /* The last known character position. */
10579 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10580 /* The last known character position before string_start. */
10581 int string_before_pos;
10582 int x = row->x;
10583 int pt_old = PT - delta;
10584
10585 /* Skip over glyphs not having an object at the start of the row.
10586 These are special glyphs like truncation marks on terminal
10587 frames. */
10588 if (row->displays_text_p)
10589 while (glyph < end
10590 && INTEGERP (glyph->object)
10591 && glyph->charpos < 0)
10592 {
10593 x += glyph->pixel_width;
10594 ++glyph;
10595 }
10596
10597 string_start = NULL;
10598 while (glyph < end
10599 && !INTEGERP (glyph->object)
10600 && (!BUFFERP (glyph->object)
10601 || (last_pos = glyph->charpos) < pt_old))
10602 {
10603 if (! STRINGP (glyph->object))
10604 {
10605 string_start = NULL;
10606 x += glyph->pixel_width;
10607 ++glyph;
10608 }
10609 else
10610 {
10611 string_before_pos = last_pos;
10612 string_start = glyph;
10613 string_start_x = x;
10614 /* Skip all glyphs from string. */
10615 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10616 }
10617 }
10618
10619 if (string_start
10620 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10621 {
10622 /* We may have skipped over point because the previous glyphs
10623 are from string. As there's no easy way to know the
10624 character position of the current glyph, find the correct
10625 glyph on point by scanning from string_start again. */
10626 Lisp_Object limit;
10627 Lisp_Object string;
10628 int pos;
10629
10630 limit = make_number (pt_old + 1);
10631 end = glyph;
10632 glyph = string_start;
10633 x = string_start_x;
10634 string = glyph->object;
10635 pos = string_buffer_position (w, string, string_before_pos);
10636 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10637 because we always put cursor after overlay strings. */
10638 while (pos == 0 && glyph < end)
10639 {
10640 string = glyph->object;
10641 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10642 if (glyph < end)
10643 pos = string_buffer_position (w, glyph->object, string_before_pos);
10644 }
10645
10646 while (glyph < end)
10647 {
10648 pos = XINT (Fnext_single_char_property_change
10649 (make_number (pos), Qdisplay, Qnil, limit));
10650 if (pos > pt_old)
10651 break;
10652 /* Skip glyphs from the same string. */
10653 string = glyph->object;
10654 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10655 /* Skip glyphs from an overlay. */
10656 while (glyph < end
10657 && ! string_buffer_position (w, glyph->object, pos))
10658 {
10659 string = glyph->object;
10660 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10661 }
10662 }
10663 }
10664
10665 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10666 w->cursor.x = x;
10667 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10668 w->cursor.y = row->y + dy;
10669
10670 if (w == XWINDOW (selected_window))
10671 {
10672 if (!row->continued_p
10673 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10674 && row->x == 0)
10675 {
10676 this_line_buffer = XBUFFER (w->buffer);
10677
10678 CHARPOS (this_line_start_pos)
10679 = MATRIX_ROW_START_CHARPOS (row) + delta;
10680 BYTEPOS (this_line_start_pos)
10681 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10682
10683 CHARPOS (this_line_end_pos)
10684 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10685 BYTEPOS (this_line_end_pos)
10686 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10687
10688 this_line_y = w->cursor.y;
10689 this_line_pixel_height = row->height;
10690 this_line_vpos = w->cursor.vpos;
10691 this_line_start_x = row->x;
10692 }
10693 else
10694 CHARPOS (this_line_start_pos) = 0;
10695 }
10696 }
10697
10698
10699 /* Run window scroll functions, if any, for WINDOW with new window
10700 start STARTP. Sets the window start of WINDOW to that position.
10701
10702 We assume that the window's buffer is really current. */
10703
10704 static INLINE struct text_pos
10705 run_window_scroll_functions (window, startp)
10706 Lisp_Object window;
10707 struct text_pos startp;
10708 {
10709 struct window *w = XWINDOW (window);
10710 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10711
10712 if (current_buffer != XBUFFER (w->buffer))
10713 abort ();
10714
10715 if (!NILP (Vwindow_scroll_functions))
10716 {
10717 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10718 make_number (CHARPOS (startp)));
10719 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10720 /* In case the hook functions switch buffers. */
10721 if (current_buffer != XBUFFER (w->buffer))
10722 set_buffer_internal_1 (XBUFFER (w->buffer));
10723 }
10724
10725 return startp;
10726 }
10727
10728
10729 /* Make sure the line containing the cursor is fully visible.
10730 A value of 1 means there is nothing to be done.
10731 (Either the line is fully visible, or it cannot be made so,
10732 or we cannot tell.)
10733
10734 If FORCE_P is non-zero, return 0 even if partial visible cursor row
10735 is higher than window.
10736
10737 A value of 0 means the caller should do scrolling
10738 as if point had gone off the screen. */
10739
10740 static int
10741 make_cursor_line_fully_visible (w, force_p)
10742 struct window *w;
10743 int force_p;
10744 {
10745 struct glyph_matrix *matrix;
10746 struct glyph_row *row;
10747 int window_height;
10748
10749 /* It's not always possible to find the cursor, e.g, when a window
10750 is full of overlay strings. Don't do anything in that case. */
10751 if (w->cursor.vpos < 0)
10752 return 1;
10753
10754 matrix = w->desired_matrix;
10755 row = MATRIX_ROW (matrix, w->cursor.vpos);
10756
10757 /* If the cursor row is not partially visible, there's nothing to do. */
10758 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10759 return 1;
10760
10761 if (force_p)
10762 return 0;
10763
10764 /* If the row the cursor is in is taller than the window's height,
10765 it's not clear what to do, so do nothing. */
10766 window_height = window_box_height (w);
10767 if (row->height >= window_height)
10768 return 1;
10769
10770 return 0;
10771
10772 #if 0
10773 /* This code used to try to scroll the window just enough to make
10774 the line visible. It returned 0 to say that the caller should
10775 allocate larger glyph matrices. */
10776
10777 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10778 {
10779 int dy = row->height - row->visible_height;
10780 w->vscroll = 0;
10781 w->cursor.y += dy;
10782 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10783 }
10784 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10785 {
10786 int dy = - (row->height - row->visible_height);
10787 w->vscroll = dy;
10788 w->cursor.y += dy;
10789 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10790 }
10791
10792 /* When we change the cursor y-position of the selected window,
10793 change this_line_y as well so that the display optimization for
10794 the cursor line of the selected window in redisplay_internal uses
10795 the correct y-position. */
10796 if (w == XWINDOW (selected_window))
10797 this_line_y = w->cursor.y;
10798
10799 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10800 redisplay with larger matrices. */
10801 if (matrix->nrows < required_matrix_height (w))
10802 {
10803 fonts_changed_p = 1;
10804 return 0;
10805 }
10806
10807 return 1;
10808 #endif /* 0 */
10809 }
10810
10811
10812 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10813 non-zero means only WINDOW is redisplayed in redisplay_internal.
10814 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10815 in redisplay_window to bring a partially visible line into view in
10816 the case that only the cursor has moved.
10817
10818 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10819 last screen line's vertical height extends past the end of the screen.
10820
10821 Value is
10822
10823 1 if scrolling succeeded
10824
10825 0 if scrolling didn't find point.
10826
10827 -1 if new fonts have been loaded so that we must interrupt
10828 redisplay, adjust glyph matrices, and try again. */
10829
10830 enum
10831 {
10832 SCROLLING_SUCCESS,
10833 SCROLLING_FAILED,
10834 SCROLLING_NEED_LARGER_MATRICES
10835 };
10836
10837 static int
10838 try_scrolling (window, just_this_one_p, scroll_conservatively,
10839 scroll_step, temp_scroll_step, last_line_misfit)
10840 Lisp_Object window;
10841 int just_this_one_p;
10842 EMACS_INT scroll_conservatively, scroll_step;
10843 int temp_scroll_step;
10844 int last_line_misfit;
10845 {
10846 struct window *w = XWINDOW (window);
10847 struct frame *f = XFRAME (w->frame);
10848 struct text_pos scroll_margin_pos;
10849 struct text_pos pos;
10850 struct text_pos startp;
10851 struct it it;
10852 Lisp_Object window_end;
10853 int this_scroll_margin;
10854 int dy = 0;
10855 int scroll_max;
10856 int rc;
10857 int amount_to_scroll = 0;
10858 Lisp_Object aggressive;
10859 int height;
10860 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
10861
10862 #if GLYPH_DEBUG
10863 debug_method_add (w, "try_scrolling");
10864 #endif
10865
10866 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10867
10868 /* Compute scroll margin height in pixels. We scroll when point is
10869 within this distance from the top or bottom of the window. */
10870 if (scroll_margin > 0)
10871 {
10872 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10873 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10874 }
10875 else
10876 this_scroll_margin = 0;
10877
10878 /* Force scroll_conservatively to have a reasonable value so it doesn't
10879 cause an overflow while computing how much to scroll. */
10880 if (scroll_conservatively)
10881 scroll_conservatively = min (scroll_conservatively,
10882 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
10883
10884 /* Compute how much we should try to scroll maximally to bring point
10885 into view. */
10886 if (scroll_step || scroll_conservatively || temp_scroll_step)
10887 scroll_max = max (scroll_step,
10888 max (scroll_conservatively, temp_scroll_step));
10889 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10890 || NUMBERP (current_buffer->scroll_up_aggressively))
10891 /* We're trying to scroll because of aggressive scrolling
10892 but no scroll_step is set. Choose an arbitrary one. Maybe
10893 there should be a variable for this. */
10894 scroll_max = 10;
10895 else
10896 scroll_max = 0;
10897 scroll_max *= FRAME_LINE_HEIGHT (f);
10898
10899 /* Decide whether we have to scroll down. Start at the window end
10900 and move this_scroll_margin up to find the position of the scroll
10901 margin. */
10902 window_end = Fwindow_end (window, Qt);
10903
10904 too_near_end:
10905
10906 CHARPOS (scroll_margin_pos) = XINT (window_end);
10907 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10908
10909 if (this_scroll_margin || extra_scroll_margin_lines)
10910 {
10911 start_display (&it, w, scroll_margin_pos);
10912 if (this_scroll_margin)
10913 move_it_vertically (&it, - this_scroll_margin);
10914 if (extra_scroll_margin_lines)
10915 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
10916 scroll_margin_pos = it.current.pos;
10917 }
10918
10919 if (PT >= CHARPOS (scroll_margin_pos))
10920 {
10921 int y0;
10922
10923 /* Point is in the scroll margin at the bottom of the window, or
10924 below. Compute a new window start that makes point visible. */
10925
10926 /* Compute the distance from the scroll margin to PT.
10927 Give up if the distance is greater than scroll_max. */
10928 start_display (&it, w, scroll_margin_pos);
10929 y0 = it.current_y;
10930 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10931 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10932
10933 /* To make point visible, we have to move the window start
10934 down so that the line the cursor is in is visible, which
10935 means we have to add in the height of the cursor line. */
10936 dy = line_bottom_y (&it) - y0;
10937
10938 if (dy > scroll_max)
10939 return SCROLLING_FAILED;
10940
10941 /* Move the window start down. If scrolling conservatively,
10942 move it just enough down to make point visible. If
10943 scroll_step is set, move it down by scroll_step. */
10944 start_display (&it, w, startp);
10945
10946 if (scroll_conservatively)
10947 /* Set AMOUNT_TO_SCROLL to at least one line,
10948 and at most scroll_conservatively lines. */
10949 amount_to_scroll
10950 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10951 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10952 else if (scroll_step || temp_scroll_step)
10953 amount_to_scroll = scroll_max;
10954 else
10955 {
10956 aggressive = current_buffer->scroll_up_aggressively;
10957 height = WINDOW_BOX_TEXT_HEIGHT (w);
10958 if (NUMBERP (aggressive))
10959 amount_to_scroll = XFLOATINT (aggressive) * height;
10960 }
10961
10962 if (amount_to_scroll <= 0)
10963 return SCROLLING_FAILED;
10964
10965 /* If moving by amount_to_scroll leaves STARTP unchanged,
10966 move it down one screen line. */
10967
10968 move_it_vertically (&it, amount_to_scroll);
10969 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10970 move_it_by_lines (&it, 1, 1);
10971 startp = it.current.pos;
10972 }
10973 else
10974 {
10975 /* See if point is inside the scroll margin at the top of the
10976 window. */
10977 scroll_margin_pos = startp;
10978 if (this_scroll_margin)
10979 {
10980 start_display (&it, w, startp);
10981 move_it_vertically (&it, this_scroll_margin);
10982 scroll_margin_pos = it.current.pos;
10983 }
10984
10985 if (PT < CHARPOS (scroll_margin_pos))
10986 {
10987 /* Point is in the scroll margin at the top of the window or
10988 above what is displayed in the window. */
10989 int y0;
10990
10991 /* Compute the vertical distance from PT to the scroll
10992 margin position. Give up if distance is greater than
10993 scroll_max. */
10994 SET_TEXT_POS (pos, PT, PT_BYTE);
10995 start_display (&it, w, pos);
10996 y0 = it.current_y;
10997 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
10998 it.last_visible_y, -1,
10999 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11000 dy = it.current_y - y0;
11001 if (dy > scroll_max)
11002 return SCROLLING_FAILED;
11003
11004 /* Compute new window start. */
11005 start_display (&it, w, startp);
11006
11007 if (scroll_conservatively)
11008 amount_to_scroll =
11009 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11010 else if (scroll_step || temp_scroll_step)
11011 amount_to_scroll = scroll_max;
11012 else
11013 {
11014 aggressive = current_buffer->scroll_down_aggressively;
11015 height = WINDOW_BOX_TEXT_HEIGHT (w);
11016 if (NUMBERP (aggressive))
11017 amount_to_scroll = XFLOATINT (aggressive) * height;
11018 }
11019
11020 if (amount_to_scroll <= 0)
11021 return SCROLLING_FAILED;
11022
11023 move_it_vertically (&it, - amount_to_scroll);
11024 startp = it.current.pos;
11025 }
11026 }
11027
11028 /* Run window scroll functions. */
11029 startp = run_window_scroll_functions (window, startp);
11030
11031 /* Display the window. Give up if new fonts are loaded, or if point
11032 doesn't appear. */
11033 if (!try_window (window, startp))
11034 rc = SCROLLING_NEED_LARGER_MATRICES;
11035 else if (w->cursor.vpos < 0)
11036 {
11037 clear_glyph_matrix (w->desired_matrix);
11038 rc = SCROLLING_FAILED;
11039 }
11040 else
11041 {
11042 /* Maybe forget recorded base line for line number display. */
11043 if (!just_this_one_p
11044 || current_buffer->clip_changed
11045 || BEG_UNCHANGED < CHARPOS (startp))
11046 w->base_line_number = Qnil;
11047
11048 /* If cursor ends up on a partially visible line,
11049 treat that as being off the bottom of the screen. */
11050 if (! make_cursor_line_fully_visible (w, extra_scroll_margin_lines <= 1))
11051 {
11052 clear_glyph_matrix (w->desired_matrix);
11053 ++extra_scroll_margin_lines;
11054 goto too_near_end;
11055 }
11056 rc = SCROLLING_SUCCESS;
11057 }
11058
11059 return rc;
11060 }
11061
11062
11063 /* Compute a suitable window start for window W if display of W starts
11064 on a continuation line. Value is non-zero if a new window start
11065 was computed.
11066
11067 The new window start will be computed, based on W's width, starting
11068 from the start of the continued line. It is the start of the
11069 screen line with the minimum distance from the old start W->start. */
11070
11071 static int
11072 compute_window_start_on_continuation_line (w)
11073 struct window *w;
11074 {
11075 struct text_pos pos, start_pos;
11076 int window_start_changed_p = 0;
11077
11078 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11079
11080 /* If window start is on a continuation line... Window start may be
11081 < BEGV in case there's invisible text at the start of the
11082 buffer (M-x rmail, for example). */
11083 if (CHARPOS (start_pos) > BEGV
11084 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11085 {
11086 struct it it;
11087 struct glyph_row *row;
11088
11089 /* Handle the case that the window start is out of range. */
11090 if (CHARPOS (start_pos) < BEGV)
11091 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11092 else if (CHARPOS (start_pos) > ZV)
11093 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11094
11095 /* Find the start of the continued line. This should be fast
11096 because scan_buffer is fast (newline cache). */
11097 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11098 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11099 row, DEFAULT_FACE_ID);
11100 reseat_at_previous_visible_line_start (&it);
11101
11102 /* If the line start is "too far" away from the window start,
11103 say it takes too much time to compute a new window start. */
11104 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11105 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11106 {
11107 int min_distance, distance;
11108
11109 /* Move forward by display lines to find the new window
11110 start. If window width was enlarged, the new start can
11111 be expected to be > the old start. If window width was
11112 decreased, the new window start will be < the old start.
11113 So, we're looking for the display line start with the
11114 minimum distance from the old window start. */
11115 pos = it.current.pos;
11116 min_distance = INFINITY;
11117 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11118 distance < min_distance)
11119 {
11120 min_distance = distance;
11121 pos = it.current.pos;
11122 move_it_by_lines (&it, 1, 0);
11123 }
11124
11125 /* Set the window start there. */
11126 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11127 window_start_changed_p = 1;
11128 }
11129 }
11130
11131 return window_start_changed_p;
11132 }
11133
11134
11135 /* Try cursor movement in case text has not changed in window WINDOW,
11136 with window start STARTP. Value is
11137
11138 CURSOR_MOVEMENT_SUCCESS if successful
11139
11140 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11141
11142 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11143 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11144 we want to scroll as if scroll-step were set to 1. See the code.
11145
11146 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11147 which case we have to abort this redisplay, and adjust matrices
11148 first. */
11149
11150 enum
11151 {
11152 CURSOR_MOVEMENT_SUCCESS,
11153 CURSOR_MOVEMENT_CANNOT_BE_USED,
11154 CURSOR_MOVEMENT_MUST_SCROLL,
11155 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11156 };
11157
11158 static int
11159 try_cursor_movement (window, startp, scroll_step)
11160 Lisp_Object window;
11161 struct text_pos startp;
11162 int *scroll_step;
11163 {
11164 struct window *w = XWINDOW (window);
11165 struct frame *f = XFRAME (w->frame);
11166 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11167
11168 #if GLYPH_DEBUG
11169 if (inhibit_try_cursor_movement)
11170 return rc;
11171 #endif
11172
11173 /* Handle case where text has not changed, only point, and it has
11174 not moved off the frame. */
11175 if (/* Point may be in this window. */
11176 PT >= CHARPOS (startp)
11177 /* Selective display hasn't changed. */
11178 && !current_buffer->clip_changed
11179 /* Function force-mode-line-update is used to force a thorough
11180 redisplay. It sets either windows_or_buffers_changed or
11181 update_mode_lines. So don't take a shortcut here for these
11182 cases. */
11183 && !update_mode_lines
11184 && !windows_or_buffers_changed
11185 && !cursor_type_changed
11186 /* Can't use this case if highlighting a region. When a
11187 region exists, cursor movement has to do more than just
11188 set the cursor. */
11189 && !(!NILP (Vtransient_mark_mode)
11190 && !NILP (current_buffer->mark_active))
11191 && NILP (w->region_showing)
11192 && NILP (Vshow_trailing_whitespace)
11193 /* Right after splitting windows, last_point may be nil. */
11194 && INTEGERP (w->last_point)
11195 /* This code is not used for mini-buffer for the sake of the case
11196 of redisplaying to replace an echo area message; since in
11197 that case the mini-buffer contents per se are usually
11198 unchanged. This code is of no real use in the mini-buffer
11199 since the handling of this_line_start_pos, etc., in redisplay
11200 handles the same cases. */
11201 && !EQ (window, minibuf_window)
11202 /* When splitting windows or for new windows, it happens that
11203 redisplay is called with a nil window_end_vpos or one being
11204 larger than the window. This should really be fixed in
11205 window.c. I don't have this on my list, now, so we do
11206 approximately the same as the old redisplay code. --gerd. */
11207 && INTEGERP (w->window_end_vpos)
11208 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11209 && (FRAME_WINDOW_P (f)
11210 || !overlay_arrow_in_current_buffer_p ()))
11211 {
11212 int this_scroll_margin;
11213 struct glyph_row *row = NULL;
11214
11215 #if GLYPH_DEBUG
11216 debug_method_add (w, "cursor movement");
11217 #endif
11218
11219 /* Scroll if point within this distance from the top or bottom
11220 of the window. This is a pixel value. */
11221 this_scroll_margin = max (0, scroll_margin);
11222 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11223 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11224
11225 /* Start with the row the cursor was displayed during the last
11226 not paused redisplay. Give up if that row is not valid. */
11227 if (w->last_cursor.vpos < 0
11228 || w->last_cursor.vpos >= w->current_matrix->nrows)
11229 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11230 else
11231 {
11232 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11233 if (row->mode_line_p)
11234 ++row;
11235 if (!row->enabled_p)
11236 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11237 }
11238
11239 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11240 {
11241 int scroll_p = 0;
11242 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11243
11244 if (PT > XFASTINT (w->last_point))
11245 {
11246 /* Point has moved forward. */
11247 while (MATRIX_ROW_END_CHARPOS (row) < PT
11248 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11249 {
11250 xassert (row->enabled_p);
11251 ++row;
11252 }
11253
11254 /* The end position of a row equals the start position
11255 of the next row. If PT is there, we would rather
11256 display it in the next line. */
11257 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11258 && MATRIX_ROW_END_CHARPOS (row) == PT
11259 && !cursor_row_p (w, row))
11260 ++row;
11261
11262 /* If within the scroll margin, scroll. Note that
11263 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11264 the next line would be drawn, and that
11265 this_scroll_margin can be zero. */
11266 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11267 || PT > MATRIX_ROW_END_CHARPOS (row)
11268 /* Line is completely visible last line in window
11269 and PT is to be set in the next line. */
11270 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11271 && PT == MATRIX_ROW_END_CHARPOS (row)
11272 && !row->ends_at_zv_p
11273 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11274 scroll_p = 1;
11275 }
11276 else if (PT < XFASTINT (w->last_point))
11277 {
11278 /* Cursor has to be moved backward. Note that PT >=
11279 CHARPOS (startp) because of the outer
11280 if-statement. */
11281 while (!row->mode_line_p
11282 && (MATRIX_ROW_START_CHARPOS (row) > PT
11283 || (MATRIX_ROW_START_CHARPOS (row) == PT
11284 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11285 && (row->y > this_scroll_margin
11286 || CHARPOS (startp) == BEGV))
11287 {
11288 xassert (row->enabled_p);
11289 --row;
11290 }
11291
11292 /* Consider the following case: Window starts at BEGV,
11293 there is invisible, intangible text at BEGV, so that
11294 display starts at some point START > BEGV. It can
11295 happen that we are called with PT somewhere between
11296 BEGV and START. Try to handle that case. */
11297 if (row < w->current_matrix->rows
11298 || row->mode_line_p)
11299 {
11300 row = w->current_matrix->rows;
11301 if (row->mode_line_p)
11302 ++row;
11303 }
11304
11305 /* Due to newlines in overlay strings, we may have to
11306 skip forward over overlay strings. */
11307 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11308 && MATRIX_ROW_END_CHARPOS (row) == PT
11309 && !cursor_row_p (w, row))
11310 ++row;
11311
11312 /* If within the scroll margin, scroll. */
11313 if (row->y < this_scroll_margin
11314 && CHARPOS (startp) != BEGV)
11315 scroll_p = 1;
11316 }
11317
11318 if (PT < MATRIX_ROW_START_CHARPOS (row)
11319 || PT > MATRIX_ROW_END_CHARPOS (row))
11320 {
11321 /* if PT is not in the glyph row, give up. */
11322 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11323 }
11324 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11325 {
11326 if (PT == MATRIX_ROW_END_CHARPOS (row)
11327 && !row->ends_at_zv_p
11328 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11329 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11330 else if (row->height > window_box_height (w))
11331 {
11332 /* If we end up in a partially visible line, let's
11333 make it fully visible, except when it's taller
11334 than the window, in which case we can't do much
11335 about it. */
11336 *scroll_step = 1;
11337 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11338 }
11339 else
11340 {
11341 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11342 if (!make_cursor_line_fully_visible (w, 0))
11343 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11344 else
11345 rc = CURSOR_MOVEMENT_SUCCESS;
11346 }
11347 }
11348 else if (scroll_p)
11349 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11350 else
11351 {
11352 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11353 rc = CURSOR_MOVEMENT_SUCCESS;
11354 }
11355 }
11356 }
11357
11358 return rc;
11359 }
11360
11361 void
11362 set_vertical_scroll_bar (w)
11363 struct window *w;
11364 {
11365 int start, end, whole;
11366
11367 /* Calculate the start and end positions for the current window.
11368 At some point, it would be nice to choose between scrollbars
11369 which reflect the whole buffer size, with special markers
11370 indicating narrowing, and scrollbars which reflect only the
11371 visible region.
11372
11373 Note that mini-buffers sometimes aren't displaying any text. */
11374 if (!MINI_WINDOW_P (w)
11375 || (w == XWINDOW (minibuf_window)
11376 && NILP (echo_area_buffer[0])))
11377 {
11378 struct buffer *buf = XBUFFER (w->buffer);
11379 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11380 start = marker_position (w->start) - BUF_BEGV (buf);
11381 /* I don't think this is guaranteed to be right. For the
11382 moment, we'll pretend it is. */
11383 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11384
11385 if (end < start)
11386 end = start;
11387 if (whole < (end - start))
11388 whole = end - start;
11389 }
11390 else
11391 start = end = whole = 0;
11392
11393 /* Indicate what this scroll bar ought to be displaying now. */
11394 if (FRAME_DISPLAY (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
11395 (*FRAME_DISPLAY (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
11396 (w, end - start, whole, start);
11397 }
11398
11399
11400 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11401 selected_window is redisplayed.
11402
11403 We can return without actually redisplaying the window if
11404 fonts_changed_p is nonzero. In that case, redisplay_internal will
11405 retry. */
11406
11407 static void
11408 redisplay_window (window, just_this_one_p)
11409 Lisp_Object window;
11410 int just_this_one_p;
11411 {
11412 struct window *w = XWINDOW (window);
11413 struct frame *f = XFRAME (w->frame);
11414 struct buffer *buffer = XBUFFER (w->buffer);
11415 struct buffer *old = current_buffer;
11416 struct text_pos lpoint, opoint, startp;
11417 int update_mode_line;
11418 int tem;
11419 struct it it;
11420 /* Record it now because it's overwritten. */
11421 int current_matrix_up_to_date_p = 0;
11422 int used_current_matrix_p = 0;
11423 /* This is less strict than current_matrix_up_to_date_p.
11424 It indictes that the buffer contents and narrowing are unchanged. */
11425 int buffer_unchanged_p = 0;
11426 int temp_scroll_step = 0;
11427 int count = SPECPDL_INDEX ();
11428 int rc;
11429 int centering_position;
11430 int last_line_misfit = 0;
11431
11432 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11433 opoint = lpoint;
11434
11435 /* W must be a leaf window here. */
11436 xassert (!NILP (w->buffer));
11437 #if GLYPH_DEBUG
11438 *w->desired_matrix->method = 0;
11439 #endif
11440
11441 specbind (Qinhibit_point_motion_hooks, Qt);
11442
11443 reconsider_clip_changes (w, buffer);
11444
11445 /* Has the mode line to be updated? */
11446 update_mode_line = (!NILP (w->update_mode_line)
11447 || update_mode_lines
11448 || buffer->clip_changed
11449 || buffer->prevent_redisplay_optimizations_p);
11450
11451 if (MINI_WINDOW_P (w))
11452 {
11453 if (w == XWINDOW (echo_area_window)
11454 && !NILP (echo_area_buffer[0]))
11455 {
11456 if (update_mode_line)
11457 /* We may have to update a tty frame's menu bar or a
11458 tool-bar. Example `M-x C-h C-h C-g'. */
11459 goto finish_menu_bars;
11460 else
11461 /* We've already displayed the echo area glyphs in this window. */
11462 goto finish_scroll_bars;
11463 }
11464 else if ((w != XWINDOW (minibuf_window)
11465 || minibuf_level == 0)
11466 /* When buffer is nonempty, redisplay window normally. */
11467 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11468 /* Quail displays non-mini buffers in minibuffer window.
11469 In that case, redisplay the window normally. */
11470 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11471 {
11472 /* W is a mini-buffer window, but it's not active, so clear
11473 it. */
11474 int yb = window_text_bottom_y (w);
11475 struct glyph_row *row;
11476 int y;
11477
11478 for (y = 0, row = w->desired_matrix->rows;
11479 y < yb;
11480 y += row->height, ++row)
11481 blank_row (w, row, y);
11482 goto finish_scroll_bars;
11483 }
11484
11485 clear_glyph_matrix (w->desired_matrix);
11486 }
11487
11488 /* Otherwise set up data on this window; select its buffer and point
11489 value. */
11490 /* Really select the buffer, for the sake of buffer-local
11491 variables. */
11492 set_buffer_internal_1 (XBUFFER (w->buffer));
11493 SET_TEXT_POS (opoint, PT, PT_BYTE);
11494
11495 current_matrix_up_to_date_p
11496 = (!NILP (w->window_end_valid)
11497 && !current_buffer->clip_changed
11498 && !current_buffer->prevent_redisplay_optimizations_p
11499 && XFASTINT (w->last_modified) >= MODIFF
11500 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11501
11502 buffer_unchanged_p
11503 = (!NILP (w->window_end_valid)
11504 && !current_buffer->clip_changed
11505 && XFASTINT (w->last_modified) >= MODIFF
11506 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11507
11508 /* When windows_or_buffers_changed is non-zero, we can't rely on
11509 the window end being valid, so set it to nil there. */
11510 if (windows_or_buffers_changed)
11511 {
11512 /* If window starts on a continuation line, maybe adjust the
11513 window start in case the window's width changed. */
11514 if (XMARKER (w->start)->buffer == current_buffer)
11515 compute_window_start_on_continuation_line (w);
11516
11517 w->window_end_valid = Qnil;
11518 }
11519
11520 /* Some sanity checks. */
11521 CHECK_WINDOW_END (w);
11522 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11523 abort ();
11524 if (BYTEPOS (opoint) < CHARPOS (opoint))
11525 abort ();
11526
11527 /* If %c is in mode line, update it if needed. */
11528 if (!NILP (w->column_number_displayed)
11529 /* This alternative quickly identifies a common case
11530 where no change is needed. */
11531 && !(PT == XFASTINT (w->last_point)
11532 && XFASTINT (w->last_modified) >= MODIFF
11533 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11534 && (XFASTINT (w->column_number_displayed)
11535 != (int) current_column ())) /* iftc */
11536 update_mode_line = 1;
11537
11538 /* Count number of windows showing the selected buffer. An indirect
11539 buffer counts as its base buffer. */
11540 if (!just_this_one_p)
11541 {
11542 struct buffer *current_base, *window_base;
11543 current_base = current_buffer;
11544 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11545 if (current_base->base_buffer)
11546 current_base = current_base->base_buffer;
11547 if (window_base->base_buffer)
11548 window_base = window_base->base_buffer;
11549 if (current_base == window_base)
11550 buffer_shared++;
11551 }
11552
11553 /* Point refers normally to the selected window. For any other
11554 window, set up appropriate value. */
11555 if (!EQ (window, selected_window))
11556 {
11557 int new_pt = XMARKER (w->pointm)->charpos;
11558 int new_pt_byte = marker_byte_position (w->pointm);
11559 if (new_pt < BEGV)
11560 {
11561 new_pt = BEGV;
11562 new_pt_byte = BEGV_BYTE;
11563 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11564 }
11565 else if (new_pt > (ZV - 1))
11566 {
11567 new_pt = ZV;
11568 new_pt_byte = ZV_BYTE;
11569 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11570 }
11571
11572 /* We don't use SET_PT so that the point-motion hooks don't run. */
11573 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11574 }
11575
11576 /* If any of the character widths specified in the display table
11577 have changed, invalidate the width run cache. It's true that
11578 this may be a bit late to catch such changes, but the rest of
11579 redisplay goes (non-fatally) haywire when the display table is
11580 changed, so why should we worry about doing any better? */
11581 if (current_buffer->width_run_cache)
11582 {
11583 struct Lisp_Char_Table *disptab = buffer_display_table ();
11584
11585 if (! disptab_matches_widthtab (disptab,
11586 XVECTOR (current_buffer->width_table)))
11587 {
11588 invalidate_region_cache (current_buffer,
11589 current_buffer->width_run_cache,
11590 BEG, Z);
11591 recompute_width_table (current_buffer, disptab);
11592 }
11593 }
11594
11595 /* If window-start is screwed up, choose a new one. */
11596 if (XMARKER (w->start)->buffer != current_buffer)
11597 goto recenter;
11598
11599 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11600
11601 /* If someone specified a new starting point but did not insist,
11602 check whether it can be used. */
11603 if (!NILP (w->optional_new_start)
11604 && CHARPOS (startp) >= BEGV
11605 && CHARPOS (startp) <= ZV)
11606 {
11607 w->optional_new_start = Qnil;
11608 start_display (&it, w, startp);
11609 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11610 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11611 if (IT_CHARPOS (it) == PT)
11612 w->force_start = Qt;
11613 /* IT may overshoot PT if text at PT is invisible. */
11614 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11615 w->force_start = Qt;
11616
11617
11618 }
11619
11620 /* Handle case where place to start displaying has been specified,
11621 unless the specified location is outside the accessible range. */
11622 if (!NILP (w->force_start)
11623 || w->frozen_window_start_p)
11624 {
11625 /* We set this later on if we have to adjust point. */
11626 int new_vpos = -1;
11627
11628 w->force_start = Qnil;
11629 w->vscroll = 0;
11630 w->window_end_valid = Qnil;
11631
11632 /* Forget any recorded base line for line number display. */
11633 if (!buffer_unchanged_p)
11634 w->base_line_number = Qnil;
11635
11636 /* Redisplay the mode line. Select the buffer properly for that.
11637 Also, run the hook window-scroll-functions
11638 because we have scrolled. */
11639 /* Note, we do this after clearing force_start because
11640 if there's an error, it is better to forget about force_start
11641 than to get into an infinite loop calling the hook functions
11642 and having them get more errors. */
11643 if (!update_mode_line
11644 || ! NILP (Vwindow_scroll_functions))
11645 {
11646 update_mode_line = 1;
11647 w->update_mode_line = Qt;
11648 startp = run_window_scroll_functions (window, startp);
11649 }
11650
11651 w->last_modified = make_number (0);
11652 w->last_overlay_modified = make_number (0);
11653 if (CHARPOS (startp) < BEGV)
11654 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11655 else if (CHARPOS (startp) > ZV)
11656 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11657
11658 /* Redisplay, then check if cursor has been set during the
11659 redisplay. Give up if new fonts were loaded. */
11660 if (!try_window (window, startp))
11661 {
11662 w->force_start = Qt;
11663 clear_glyph_matrix (w->desired_matrix);
11664 goto need_larger_matrices;
11665 }
11666
11667 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11668 {
11669 /* If point does not appear, try to move point so it does
11670 appear. The desired matrix has been built above, so we
11671 can use it here. */
11672 new_vpos = window_box_height (w) / 2;
11673 }
11674
11675 if (!make_cursor_line_fully_visible (w, 0))
11676 {
11677 /* Point does appear, but on a line partly visible at end of window.
11678 Move it back to a fully-visible line. */
11679 new_vpos = window_box_height (w);
11680 }
11681
11682 /* If we need to move point for either of the above reasons,
11683 now actually do it. */
11684 if (new_vpos >= 0)
11685 {
11686 struct glyph_row *row;
11687
11688 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11689 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11690 ++row;
11691
11692 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11693 MATRIX_ROW_START_BYTEPOS (row));
11694
11695 if (w != XWINDOW (selected_window))
11696 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11697 else if (current_buffer == old)
11698 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11699
11700 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11701
11702 /* If we are highlighting the region, then we just changed
11703 the region, so redisplay to show it. */
11704 if (!NILP (Vtransient_mark_mode)
11705 && !NILP (current_buffer->mark_active))
11706 {
11707 clear_glyph_matrix (w->desired_matrix);
11708 if (!try_window (window, startp))
11709 goto need_larger_matrices;
11710 }
11711 }
11712
11713 #if GLYPH_DEBUG
11714 debug_method_add (w, "forced window start");
11715 #endif
11716 goto done;
11717 }
11718
11719 /* Handle case where text has not changed, only point, and it has
11720 not moved off the frame, and we are not retrying after hscroll.
11721 (current_matrix_up_to_date_p is nonzero when retrying.) */
11722 if (current_matrix_up_to_date_p
11723 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11724 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11725 {
11726 switch (rc)
11727 {
11728 case CURSOR_MOVEMENT_SUCCESS:
11729 used_current_matrix_p = 1;
11730 goto done;
11731
11732 #if 0 /* try_cursor_movement never returns this value. */
11733 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11734 goto need_larger_matrices;
11735 #endif
11736
11737 case CURSOR_MOVEMENT_MUST_SCROLL:
11738 goto try_to_scroll;
11739
11740 default:
11741 abort ();
11742 }
11743 }
11744 /* If current starting point was originally the beginning of a line
11745 but no longer is, find a new starting point. */
11746 else if (!NILP (w->start_at_line_beg)
11747 && !(CHARPOS (startp) <= BEGV
11748 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11749 {
11750 #if GLYPH_DEBUG
11751 debug_method_add (w, "recenter 1");
11752 #endif
11753 goto recenter;
11754 }
11755
11756 /* Try scrolling with try_window_id. Value is > 0 if update has
11757 been done, it is -1 if we know that the same window start will
11758 not work. It is 0 if unsuccessful for some other reason. */
11759 else if ((tem = try_window_id (w)) != 0)
11760 {
11761 #if GLYPH_DEBUG
11762 debug_method_add (w, "try_window_id %d", tem);
11763 #endif
11764
11765 if (fonts_changed_p)
11766 goto need_larger_matrices;
11767 if (tem > 0)
11768 goto done;
11769
11770 /* Otherwise try_window_id has returned -1 which means that we
11771 don't want the alternative below this comment to execute. */
11772 }
11773 else if (CHARPOS (startp) >= BEGV
11774 && CHARPOS (startp) <= ZV
11775 && PT >= CHARPOS (startp)
11776 && (CHARPOS (startp) < ZV
11777 /* Avoid starting at end of buffer. */
11778 || CHARPOS (startp) == BEGV
11779 || (XFASTINT (w->last_modified) >= MODIFF
11780 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11781 {
11782 #if GLYPH_DEBUG
11783 debug_method_add (w, "same window start");
11784 #endif
11785
11786 /* Try to redisplay starting at same place as before.
11787 If point has not moved off frame, accept the results. */
11788 if (!current_matrix_up_to_date_p
11789 /* Don't use try_window_reusing_current_matrix in this case
11790 because a window scroll function can have changed the
11791 buffer. */
11792 || !NILP (Vwindow_scroll_functions)
11793 || MINI_WINDOW_P (w)
11794 || !(used_current_matrix_p =
11795 try_window_reusing_current_matrix (w)))
11796 {
11797 IF_DEBUG (debug_method_add (w, "1"));
11798 try_window (window, startp);
11799 }
11800
11801 if (fonts_changed_p)
11802 goto need_larger_matrices;
11803
11804 if (w->cursor.vpos >= 0)
11805 {
11806 if (!just_this_one_p
11807 || current_buffer->clip_changed
11808 || BEG_UNCHANGED < CHARPOS (startp))
11809 /* Forget any recorded base line for line number display. */
11810 w->base_line_number = Qnil;
11811
11812 if (!make_cursor_line_fully_visible (w, 1))
11813 {
11814 clear_glyph_matrix (w->desired_matrix);
11815 last_line_misfit = 1;
11816 }
11817 /* Drop through and scroll. */
11818 else
11819 goto done;
11820 }
11821 else
11822 clear_glyph_matrix (w->desired_matrix);
11823 }
11824
11825 try_to_scroll:
11826
11827 w->last_modified = make_number (0);
11828 w->last_overlay_modified = make_number (0);
11829
11830 /* Redisplay the mode line. Select the buffer properly for that. */
11831 if (!update_mode_line)
11832 {
11833 update_mode_line = 1;
11834 w->update_mode_line = Qt;
11835 }
11836
11837 /* Try to scroll by specified few lines. */
11838 if ((scroll_conservatively
11839 || scroll_step
11840 || temp_scroll_step
11841 || NUMBERP (current_buffer->scroll_up_aggressively)
11842 || NUMBERP (current_buffer->scroll_down_aggressively))
11843 && !current_buffer->clip_changed
11844 && CHARPOS (startp) >= BEGV
11845 && CHARPOS (startp) <= ZV)
11846 {
11847 /* The function returns -1 if new fonts were loaded, 1 if
11848 successful, 0 if not successful. */
11849 int rc = try_scrolling (window, just_this_one_p,
11850 scroll_conservatively,
11851 scroll_step,
11852 temp_scroll_step, last_line_misfit);
11853 switch (rc)
11854 {
11855 case SCROLLING_SUCCESS:
11856 goto done;
11857
11858 case SCROLLING_NEED_LARGER_MATRICES:
11859 goto need_larger_matrices;
11860
11861 case SCROLLING_FAILED:
11862 break;
11863
11864 default:
11865 abort ();
11866 }
11867 }
11868
11869 /* Finally, just choose place to start which centers point */
11870
11871 recenter:
11872 centering_position = window_box_height (w) / 2;
11873
11874 point_at_top:
11875 /* Jump here with centering_position already set to 0. */
11876
11877 #if GLYPH_DEBUG
11878 debug_method_add (w, "recenter");
11879 #endif
11880
11881 /* w->vscroll = 0; */
11882
11883 /* Forget any previously recorded base line for line number display. */
11884 if (!buffer_unchanged_p)
11885 w->base_line_number = Qnil;
11886
11887 /* Move backward half the height of the window. */
11888 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11889 it.current_y = it.last_visible_y;
11890 move_it_vertically_backward (&it, centering_position);
11891 xassert (IT_CHARPOS (it) >= BEGV);
11892
11893 /* The function move_it_vertically_backward may move over more
11894 than the specified y-distance. If it->w is small, e.g. a
11895 mini-buffer window, we may end up in front of the window's
11896 display area. Start displaying at the start of the line
11897 containing PT in this case. */
11898 if (it.current_y <= 0)
11899 {
11900 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11901 move_it_vertically (&it, 0);
11902 xassert (IT_CHARPOS (it) <= PT);
11903 it.current_y = 0;
11904 }
11905
11906 it.current_x = it.hpos = 0;
11907
11908 /* Set startp here explicitly in case that helps avoid an infinite loop
11909 in case the window-scroll-functions functions get errors. */
11910 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11911
11912 /* Run scroll hooks. */
11913 startp = run_window_scroll_functions (window, it.current.pos);
11914
11915 /* Redisplay the window. */
11916 if (!current_matrix_up_to_date_p
11917 || windows_or_buffers_changed
11918 || cursor_type_changed
11919 /* Don't use try_window_reusing_current_matrix in this case
11920 because it can have changed the buffer. */
11921 || !NILP (Vwindow_scroll_functions)
11922 || !just_this_one_p
11923 || MINI_WINDOW_P (w)
11924 || !(used_current_matrix_p =
11925 try_window_reusing_current_matrix (w)))
11926 try_window (window, startp);
11927
11928 /* If new fonts have been loaded (due to fontsets), give up. We
11929 have to start a new redisplay since we need to re-adjust glyph
11930 matrices. */
11931 if (fonts_changed_p)
11932 goto need_larger_matrices;
11933
11934 /* If cursor did not appear assume that the middle of the window is
11935 in the first line of the window. Do it again with the next line.
11936 (Imagine a window of height 100, displaying two lines of height
11937 60. Moving back 50 from it->last_visible_y will end in the first
11938 line.) */
11939 if (w->cursor.vpos < 0)
11940 {
11941 if (!NILP (w->window_end_valid)
11942 && PT >= Z - XFASTINT (w->window_end_pos))
11943 {
11944 clear_glyph_matrix (w->desired_matrix);
11945 move_it_by_lines (&it, 1, 0);
11946 try_window (window, it.current.pos);
11947 }
11948 else if (PT < IT_CHARPOS (it))
11949 {
11950 clear_glyph_matrix (w->desired_matrix);
11951 move_it_by_lines (&it, -1, 0);
11952 try_window (window, it.current.pos);
11953 }
11954 else
11955 {
11956 /* Not much we can do about it. */
11957 }
11958 }
11959
11960 /* Consider the following case: Window starts at BEGV, there is
11961 invisible, intangible text at BEGV, so that display starts at
11962 some point START > BEGV. It can happen that we are called with
11963 PT somewhere between BEGV and START. Try to handle that case. */
11964 if (w->cursor.vpos < 0)
11965 {
11966 struct glyph_row *row = w->current_matrix->rows;
11967 if (row->mode_line_p)
11968 ++row;
11969 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11970 }
11971
11972 if (!make_cursor_line_fully_visible (w, centering_position > 0))
11973 {
11974 /* If vscroll is enabled, disable it and try again. */
11975 if (w->vscroll)
11976 {
11977 w->vscroll = 0;
11978 clear_glyph_matrix (w->desired_matrix);
11979 goto recenter;
11980 }
11981
11982 /* If centering point failed to make the whole line visible,
11983 put point at the top instead. That has to make the whole line
11984 visible, if it can be done. */
11985 clear_glyph_matrix (w->desired_matrix);
11986 centering_position = 0;
11987 goto point_at_top;
11988 }
11989
11990 done:
11991
11992 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11993 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11994 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11995 ? Qt : Qnil);
11996
11997 /* Display the mode line, if we must. */
11998 if ((update_mode_line
11999 /* If window not full width, must redo its mode line
12000 if (a) the window to its side is being redone and
12001 (b) we do a frame-based redisplay. This is a consequence
12002 of how inverted lines are drawn in frame-based redisplay. */
12003 || (!just_this_one_p
12004 && !FRAME_WINDOW_P (f)
12005 && !WINDOW_FULL_WIDTH_P (w))
12006 /* Line number to display. */
12007 || INTEGERP (w->base_line_pos)
12008 /* Column number is displayed and different from the one displayed. */
12009 || (!NILP (w->column_number_displayed)
12010 && (XFASTINT (w->column_number_displayed)
12011 != (int) current_column ()))) /* iftc */
12012 /* This means that the window has a mode line. */
12013 && (WINDOW_WANTS_MODELINE_P (w)
12014 || WINDOW_WANTS_HEADER_LINE_P (w)))
12015 {
12016 display_mode_lines (w);
12017
12018 /* If mode line height has changed, arrange for a thorough
12019 immediate redisplay using the correct mode line height. */
12020 if (WINDOW_WANTS_MODELINE_P (w)
12021 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12022 {
12023 fonts_changed_p = 1;
12024 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12025 = DESIRED_MODE_LINE_HEIGHT (w);
12026 }
12027
12028 /* If top line height has changed, arrange for a thorough
12029 immediate redisplay using the correct mode line height. */
12030 if (WINDOW_WANTS_HEADER_LINE_P (w)
12031 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12032 {
12033 fonts_changed_p = 1;
12034 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12035 = DESIRED_HEADER_LINE_HEIGHT (w);
12036 }
12037
12038 if (fonts_changed_p)
12039 goto need_larger_matrices;
12040 }
12041
12042 if (!line_number_displayed
12043 && !BUFFERP (w->base_line_pos))
12044 {
12045 w->base_line_pos = Qnil;
12046 w->base_line_number = Qnil;
12047 }
12048
12049 finish_menu_bars:
12050
12051 /* When we reach a frame's selected window, redo the frame's menu bar. */
12052 if (update_mode_line
12053 && EQ (FRAME_SELECTED_WINDOW (f), window))
12054 {
12055 int redisplay_menu_p = 0;
12056 int redisplay_tool_bar_p = 0;
12057
12058 if (FRAME_WINDOW_P (f))
12059 {
12060 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12061 || defined (USE_GTK)
12062 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12063 #else
12064 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12065 #endif
12066 }
12067 else
12068 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12069
12070 if (redisplay_menu_p)
12071 display_menu_bar (w);
12072
12073 #ifdef HAVE_WINDOW_SYSTEM
12074 #ifdef USE_GTK
12075 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12076 #else
12077 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12078 && (FRAME_TOOL_BAR_LINES (f) > 0
12079 || auto_resize_tool_bars_p);
12080
12081 #endif
12082
12083 if (redisplay_tool_bar_p)
12084 redisplay_tool_bar (f);
12085 #endif
12086 }
12087
12088 #ifdef HAVE_WINDOW_SYSTEM
12089 if (update_window_fringes (w, 0)
12090 && !just_this_one_p
12091 && (used_current_matrix_p || overlay_arrow_seen)
12092 && !w->pseudo_window_p)
12093 {
12094 update_begin (f);
12095 BLOCK_INPUT;
12096 draw_window_fringes (w);
12097 UNBLOCK_INPUT;
12098 update_end (f);
12099 }
12100 #endif /* HAVE_WINDOW_SYSTEM */
12101
12102 /* We go to this label, with fonts_changed_p nonzero,
12103 if it is necessary to try again using larger glyph matrices.
12104 We have to redeem the scroll bar even in this case,
12105 because the loop in redisplay_internal expects that. */
12106 need_larger_matrices:
12107 ;
12108 finish_scroll_bars:
12109
12110 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12111 {
12112 /* Set the thumb's position and size. */
12113 set_vertical_scroll_bar (w);
12114
12115 /* Note that we actually used the scroll bar attached to this
12116 window, so it shouldn't be deleted at the end of redisplay. */
12117 if (FRAME_DISPLAY (f)->redeem_scroll_bar_hook)
12118 (*FRAME_DISPLAY (f)->redeem_scroll_bar_hook) (w);
12119 }
12120
12121 /* Restore current_buffer and value of point in it. */
12122 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12123 set_buffer_internal_1 (old);
12124 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12125
12126 unbind_to (count, Qnil);
12127 }
12128
12129
12130 /* Build the complete desired matrix of WINDOW with a window start
12131 buffer position POS. Value is non-zero if successful. It is zero
12132 if fonts were loaded during redisplay which makes re-adjusting
12133 glyph matrices necessary. */
12134
12135 int
12136 try_window (window, pos)
12137 Lisp_Object window;
12138 struct text_pos pos;
12139 {
12140 struct window *w = XWINDOW (window);
12141 struct it it;
12142 struct glyph_row *last_text_row = NULL;
12143
12144 /* Make POS the new window start. */
12145 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12146
12147 /* Mark cursor position as unknown. No overlay arrow seen. */
12148 w->cursor.vpos = -1;
12149 overlay_arrow_seen = 0;
12150
12151 /* Initialize iterator and info to start at POS. */
12152 start_display (&it, w, pos);
12153
12154 /* Display all lines of W. */
12155 while (it.current_y < it.last_visible_y)
12156 {
12157 if (display_line (&it))
12158 last_text_row = it.glyph_row - 1;
12159 if (fonts_changed_p)
12160 return 0;
12161 }
12162
12163 /* If bottom moved off end of frame, change mode line percentage. */
12164 if (XFASTINT (w->window_end_pos) <= 0
12165 && Z != IT_CHARPOS (it))
12166 w->update_mode_line = Qt;
12167
12168 /* Set window_end_pos to the offset of the last character displayed
12169 on the window from the end of current_buffer. Set
12170 window_end_vpos to its row number. */
12171 if (last_text_row)
12172 {
12173 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12174 w->window_end_bytepos
12175 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12176 w->window_end_pos
12177 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12178 w->window_end_vpos
12179 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12180 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12181 ->displays_text_p);
12182 }
12183 else
12184 {
12185 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12186 w->window_end_pos = make_number (Z - ZV);
12187 w->window_end_vpos = make_number (0);
12188 }
12189
12190 /* But that is not valid info until redisplay finishes. */
12191 w->window_end_valid = Qnil;
12192 return 1;
12193 }
12194
12195
12196 \f
12197 /************************************************************************
12198 Window redisplay reusing current matrix when buffer has not changed
12199 ************************************************************************/
12200
12201 /* Try redisplay of window W showing an unchanged buffer with a
12202 different window start than the last time it was displayed by
12203 reusing its current matrix. Value is non-zero if successful.
12204 W->start is the new window start. */
12205
12206 static int
12207 try_window_reusing_current_matrix (w)
12208 struct window *w;
12209 {
12210 struct frame *f = XFRAME (w->frame);
12211 struct glyph_row *row, *bottom_row;
12212 struct it it;
12213 struct run run;
12214 struct text_pos start, new_start;
12215 int nrows_scrolled, i;
12216 struct glyph_row *last_text_row;
12217 struct glyph_row *last_reused_text_row;
12218 struct glyph_row *start_row;
12219 int start_vpos, min_y, max_y;
12220
12221 #if GLYPH_DEBUG
12222 if (inhibit_try_window_reusing)
12223 return 0;
12224 #endif
12225
12226 if (/* This function doesn't handle terminal frames. */
12227 !FRAME_WINDOW_P (f)
12228 /* Don't try to reuse the display if windows have been split
12229 or such. */
12230 || windows_or_buffers_changed
12231 || cursor_type_changed)
12232 return 0;
12233
12234 /* Can't do this if region may have changed. */
12235 if ((!NILP (Vtransient_mark_mode)
12236 && !NILP (current_buffer->mark_active))
12237 || !NILP (w->region_showing)
12238 || !NILP (Vshow_trailing_whitespace))
12239 return 0;
12240
12241 /* If top-line visibility has changed, give up. */
12242 if (WINDOW_WANTS_HEADER_LINE_P (w)
12243 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12244 return 0;
12245
12246 /* Give up if old or new display is scrolled vertically. We could
12247 make this function handle this, but right now it doesn't. */
12248 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12249 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12250 return 0;
12251
12252 /* The variable new_start now holds the new window start. The old
12253 start `start' can be determined from the current matrix. */
12254 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12255 start = start_row->start.pos;
12256 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12257
12258 /* Clear the desired matrix for the display below. */
12259 clear_glyph_matrix (w->desired_matrix);
12260
12261 if (CHARPOS (new_start) <= CHARPOS (start))
12262 {
12263 int first_row_y;
12264
12265 /* Don't use this method if the display starts with an ellipsis
12266 displayed for invisible text. It's not easy to handle that case
12267 below, and it's certainly not worth the effort since this is
12268 not a frequent case. */
12269 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12270 return 0;
12271
12272 IF_DEBUG (debug_method_add (w, "twu1"));
12273
12274 /* Display up to a row that can be reused. The variable
12275 last_text_row is set to the last row displayed that displays
12276 text. Note that it.vpos == 0 if or if not there is a
12277 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12278 start_display (&it, w, new_start);
12279 first_row_y = it.current_y;
12280 w->cursor.vpos = -1;
12281 last_text_row = last_reused_text_row = NULL;
12282
12283 while (it.current_y < it.last_visible_y
12284 && IT_CHARPOS (it) < CHARPOS (start)
12285 && !fonts_changed_p)
12286 if (display_line (&it))
12287 last_text_row = it.glyph_row - 1;
12288
12289 /* A value of current_y < last_visible_y means that we stopped
12290 at the previous window start, which in turn means that we
12291 have at least one reusable row. */
12292 if (it.current_y < it.last_visible_y)
12293 {
12294 /* IT.vpos always starts from 0; it counts text lines. */
12295 nrows_scrolled = it.vpos;
12296
12297 /* Find PT if not already found in the lines displayed. */
12298 if (w->cursor.vpos < 0)
12299 {
12300 int dy = it.current_y - first_row_y;
12301
12302 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12303 row = row_containing_pos (w, PT, row, NULL, dy);
12304 if (row)
12305 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12306 dy, nrows_scrolled);
12307 else
12308 {
12309 clear_glyph_matrix (w->desired_matrix);
12310 return 0;
12311 }
12312 }
12313
12314 /* Scroll the display. Do it before the current matrix is
12315 changed. The problem here is that update has not yet
12316 run, i.e. part of the current matrix is not up to date.
12317 scroll_run_hook will clear the cursor, and use the
12318 current matrix to get the height of the row the cursor is
12319 in. */
12320 run.current_y = first_row_y;
12321 run.desired_y = it.current_y;
12322 run.height = it.last_visible_y - it.current_y;
12323
12324 if (run.height > 0 && run.current_y != run.desired_y)
12325 {
12326 update_begin (f);
12327 FRAME_RIF (f)->update_window_begin_hook (w);
12328 FRAME_RIF (f)->clear_window_mouse_face (w);
12329 FRAME_RIF (f)->scroll_run_hook (w, &run);
12330 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
12331 update_end (f);
12332 }
12333
12334 /* Shift current matrix down by nrows_scrolled lines. */
12335 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12336 rotate_matrix (w->current_matrix,
12337 start_vpos,
12338 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12339 nrows_scrolled);
12340
12341 /* Disable lines that must be updated. */
12342 for (i = 0; i < it.vpos; ++i)
12343 (start_row + i)->enabled_p = 0;
12344
12345 /* Re-compute Y positions. */
12346 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12347 max_y = it.last_visible_y;
12348 for (row = start_row + nrows_scrolled;
12349 row < bottom_row;
12350 ++row)
12351 {
12352 row->y = it.current_y;
12353 row->visible_height = row->height;
12354
12355 if (row->y < min_y)
12356 row->visible_height -= min_y - row->y;
12357 if (row->y + row->height > max_y)
12358 row->visible_height -= row->y + row->height - max_y;
12359 row->redraw_fringe_bitmaps_p = 1;
12360
12361 it.current_y += row->height;
12362
12363 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12364 last_reused_text_row = row;
12365 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12366 break;
12367 }
12368
12369 /* Disable lines in the current matrix which are now
12370 below the window. */
12371 for (++row; row < bottom_row; ++row)
12372 row->enabled_p = 0;
12373 }
12374
12375 /* Update window_end_pos etc.; last_reused_text_row is the last
12376 reused row from the current matrix containing text, if any.
12377 The value of last_text_row is the last displayed line
12378 containing text. */
12379 if (last_reused_text_row)
12380 {
12381 w->window_end_bytepos
12382 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12383 w->window_end_pos
12384 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12385 w->window_end_vpos
12386 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12387 w->current_matrix));
12388 }
12389 else if (last_text_row)
12390 {
12391 w->window_end_bytepos
12392 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12393 w->window_end_pos
12394 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12395 w->window_end_vpos
12396 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12397 }
12398 else
12399 {
12400 /* This window must be completely empty. */
12401 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12402 w->window_end_pos = make_number (Z - ZV);
12403 w->window_end_vpos = make_number (0);
12404 }
12405 w->window_end_valid = Qnil;
12406
12407 /* Update hint: don't try scrolling again in update_window. */
12408 w->desired_matrix->no_scrolling_p = 1;
12409
12410 #if GLYPH_DEBUG
12411 debug_method_add (w, "try_window_reusing_current_matrix 1");
12412 #endif
12413 return 1;
12414 }
12415 else if (CHARPOS (new_start) > CHARPOS (start))
12416 {
12417 struct glyph_row *pt_row, *row;
12418 struct glyph_row *first_reusable_row;
12419 struct glyph_row *first_row_to_display;
12420 int dy;
12421 int yb = window_text_bottom_y (w);
12422
12423 /* Find the row starting at new_start, if there is one. Don't
12424 reuse a partially visible line at the end. */
12425 first_reusable_row = start_row;
12426 while (first_reusable_row->enabled_p
12427 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12428 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12429 < CHARPOS (new_start)))
12430 ++first_reusable_row;
12431
12432 /* Give up if there is no row to reuse. */
12433 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12434 || !first_reusable_row->enabled_p
12435 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12436 != CHARPOS (new_start)))
12437 return 0;
12438
12439 /* We can reuse fully visible rows beginning with
12440 first_reusable_row to the end of the window. Set
12441 first_row_to_display to the first row that cannot be reused.
12442 Set pt_row to the row containing point, if there is any. */
12443 pt_row = NULL;
12444 for (first_row_to_display = first_reusable_row;
12445 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12446 ++first_row_to_display)
12447 {
12448 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12449 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12450 pt_row = first_row_to_display;
12451 }
12452
12453 /* Start displaying at the start of first_row_to_display. */
12454 xassert (first_row_to_display->y < yb);
12455 init_to_row_start (&it, w, first_row_to_display);
12456
12457 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12458 - start_vpos);
12459 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12460 - nrows_scrolled);
12461 it.current_y = (first_row_to_display->y - first_reusable_row->y
12462 + WINDOW_HEADER_LINE_HEIGHT (w));
12463
12464 /* Display lines beginning with first_row_to_display in the
12465 desired matrix. Set last_text_row to the last row displayed
12466 that displays text. */
12467 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12468 if (pt_row == NULL)
12469 w->cursor.vpos = -1;
12470 last_text_row = NULL;
12471 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12472 if (display_line (&it))
12473 last_text_row = it.glyph_row - 1;
12474
12475 /* Give up If point isn't in a row displayed or reused. */
12476 if (w->cursor.vpos < 0)
12477 {
12478 clear_glyph_matrix (w->desired_matrix);
12479 return 0;
12480 }
12481
12482 /* If point is in a reused row, adjust y and vpos of the cursor
12483 position. */
12484 if (pt_row)
12485 {
12486 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12487 w->current_matrix);
12488 w->cursor.y -= first_reusable_row->y;
12489 }
12490
12491 /* Scroll the display. */
12492 run.current_y = first_reusable_row->y;
12493 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12494 run.height = it.last_visible_y - run.current_y;
12495 dy = run.current_y - run.desired_y;
12496
12497 if (run.height)
12498 {
12499 update_begin (f);
12500 FRAME_RIF (f)->update_window_begin_hook (w);
12501 FRAME_RIF (f)->clear_window_mouse_face (w);
12502 FRAME_RIF (f)->scroll_run_hook (w, &run);
12503 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
12504 update_end (f);
12505 }
12506
12507 /* Adjust Y positions of reused rows. */
12508 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12509 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12510 max_y = it.last_visible_y;
12511 for (row = first_reusable_row; row < first_row_to_display; ++row)
12512 {
12513 row->y -= dy;
12514 row->visible_height = row->height;
12515 if (row->y < min_y)
12516 row->visible_height -= min_y - row->y;
12517 if (row->y + row->height > max_y)
12518 row->visible_height -= row->y + row->height - max_y;
12519 row->redraw_fringe_bitmaps_p = 1;
12520 }
12521
12522 /* Scroll the current matrix. */
12523 xassert (nrows_scrolled > 0);
12524 rotate_matrix (w->current_matrix,
12525 start_vpos,
12526 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12527 -nrows_scrolled);
12528
12529 /* Disable rows not reused. */
12530 for (row -= nrows_scrolled; row < bottom_row; ++row)
12531 row->enabled_p = 0;
12532
12533 /* Adjust window end. A null value of last_text_row means that
12534 the window end is in reused rows which in turn means that
12535 only its vpos can have changed. */
12536 if (last_text_row)
12537 {
12538 w->window_end_bytepos
12539 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12540 w->window_end_pos
12541 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12542 w->window_end_vpos
12543 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12544 }
12545 else
12546 {
12547 w->window_end_vpos
12548 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12549 }
12550
12551 w->window_end_valid = Qnil;
12552 w->desired_matrix->no_scrolling_p = 1;
12553
12554 #if GLYPH_DEBUG
12555 debug_method_add (w, "try_window_reusing_current_matrix 2");
12556 #endif
12557 return 1;
12558 }
12559
12560 return 0;
12561 }
12562
12563
12564 \f
12565 /************************************************************************
12566 Window redisplay reusing current matrix when buffer has changed
12567 ************************************************************************/
12568
12569 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12570 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12571 int *, int *));
12572 static struct glyph_row *
12573 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12574 struct glyph_row *));
12575
12576
12577 /* Return the last row in MATRIX displaying text. If row START is
12578 non-null, start searching with that row. IT gives the dimensions
12579 of the display. Value is null if matrix is empty; otherwise it is
12580 a pointer to the row found. */
12581
12582 static struct glyph_row *
12583 find_last_row_displaying_text (matrix, it, start)
12584 struct glyph_matrix *matrix;
12585 struct it *it;
12586 struct glyph_row *start;
12587 {
12588 struct glyph_row *row, *row_found;
12589
12590 /* Set row_found to the last row in IT->w's current matrix
12591 displaying text. The loop looks funny but think of partially
12592 visible lines. */
12593 row_found = NULL;
12594 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12595 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12596 {
12597 xassert (row->enabled_p);
12598 row_found = row;
12599 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12600 break;
12601 ++row;
12602 }
12603
12604 return row_found;
12605 }
12606
12607
12608 /* Return the last row in the current matrix of W that is not affected
12609 by changes at the start of current_buffer that occurred since W's
12610 current matrix was built. Value is null if no such row exists.
12611
12612 BEG_UNCHANGED us the number of characters unchanged at the start of
12613 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12614 first changed character in current_buffer. Characters at positions <
12615 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12616 when the current matrix was built. */
12617
12618 static struct glyph_row *
12619 find_last_unchanged_at_beg_row (w)
12620 struct window *w;
12621 {
12622 int first_changed_pos = BEG + BEG_UNCHANGED;
12623 struct glyph_row *row;
12624 struct glyph_row *row_found = NULL;
12625 int yb = window_text_bottom_y (w);
12626
12627 /* Find the last row displaying unchanged text. */
12628 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12629 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12630 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12631 {
12632 if (/* If row ends before first_changed_pos, it is unchanged,
12633 except in some case. */
12634 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12635 /* When row ends in ZV and we write at ZV it is not
12636 unchanged. */
12637 && !row->ends_at_zv_p
12638 /* When first_changed_pos is the end of a continued line,
12639 row is not unchanged because it may be no longer
12640 continued. */
12641 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12642 && (row->continued_p
12643 || row->exact_window_width_line_p)))
12644 row_found = row;
12645
12646 /* Stop if last visible row. */
12647 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12648 break;
12649
12650 ++row;
12651 }
12652
12653 return row_found;
12654 }
12655
12656
12657 /* Find the first glyph row in the current matrix of W that is not
12658 affected by changes at the end of current_buffer since the
12659 time W's current matrix was built.
12660
12661 Return in *DELTA the number of chars by which buffer positions in
12662 unchanged text at the end of current_buffer must be adjusted.
12663
12664 Return in *DELTA_BYTES the corresponding number of bytes.
12665
12666 Value is null if no such row exists, i.e. all rows are affected by
12667 changes. */
12668
12669 static struct glyph_row *
12670 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12671 struct window *w;
12672 int *delta, *delta_bytes;
12673 {
12674 struct glyph_row *row;
12675 struct glyph_row *row_found = NULL;
12676
12677 *delta = *delta_bytes = 0;
12678
12679 /* Display must not have been paused, otherwise the current matrix
12680 is not up to date. */
12681 if (NILP (w->window_end_valid))
12682 abort ();
12683
12684 /* A value of window_end_pos >= END_UNCHANGED means that the window
12685 end is in the range of changed text. If so, there is no
12686 unchanged row at the end of W's current matrix. */
12687 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12688 return NULL;
12689
12690 /* Set row to the last row in W's current matrix displaying text. */
12691 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12692
12693 /* If matrix is entirely empty, no unchanged row exists. */
12694 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12695 {
12696 /* The value of row is the last glyph row in the matrix having a
12697 meaningful buffer position in it. The end position of row
12698 corresponds to window_end_pos. This allows us to translate
12699 buffer positions in the current matrix to current buffer
12700 positions for characters not in changed text. */
12701 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12702 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12703 int last_unchanged_pos, last_unchanged_pos_old;
12704 struct glyph_row *first_text_row
12705 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12706
12707 *delta = Z - Z_old;
12708 *delta_bytes = Z_BYTE - Z_BYTE_old;
12709
12710 /* Set last_unchanged_pos to the buffer position of the last
12711 character in the buffer that has not been changed. Z is the
12712 index + 1 of the last character in current_buffer, i.e. by
12713 subtracting END_UNCHANGED we get the index of the last
12714 unchanged character, and we have to add BEG to get its buffer
12715 position. */
12716 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12717 last_unchanged_pos_old = last_unchanged_pos - *delta;
12718
12719 /* Search backward from ROW for a row displaying a line that
12720 starts at a minimum position >= last_unchanged_pos_old. */
12721 for (; row > first_text_row; --row)
12722 {
12723 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12724 abort ();
12725
12726 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12727 row_found = row;
12728 }
12729 }
12730
12731 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12732 abort ();
12733
12734 return row_found;
12735 }
12736
12737
12738 /* Make sure that glyph rows in the current matrix of window W
12739 reference the same glyph memory as corresponding rows in the
12740 frame's frame matrix. This function is called after scrolling W's
12741 current matrix on a terminal frame in try_window_id and
12742 try_window_reusing_current_matrix. */
12743
12744 static void
12745 sync_frame_with_window_matrix_rows (w)
12746 struct window *w;
12747 {
12748 struct frame *f = XFRAME (w->frame);
12749 struct glyph_row *window_row, *window_row_end, *frame_row;
12750
12751 /* Preconditions: W must be a leaf window and full-width. Its frame
12752 must have a frame matrix. */
12753 xassert (NILP (w->hchild) && NILP (w->vchild));
12754 xassert (WINDOW_FULL_WIDTH_P (w));
12755 xassert (!FRAME_WINDOW_P (f));
12756
12757 /* If W is a full-width window, glyph pointers in W's current matrix
12758 have, by definition, to be the same as glyph pointers in the
12759 corresponding frame matrix. Note that frame matrices have no
12760 marginal areas (see build_frame_matrix). */
12761 window_row = w->current_matrix->rows;
12762 window_row_end = window_row + w->current_matrix->nrows;
12763 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12764 while (window_row < window_row_end)
12765 {
12766 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12767 struct glyph *end = window_row->glyphs[LAST_AREA];
12768
12769 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12770 frame_row->glyphs[TEXT_AREA] = start;
12771 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12772 frame_row->glyphs[LAST_AREA] = end;
12773
12774 /* Disable frame rows whose corresponding window rows have
12775 been disabled in try_window_id. */
12776 if (!window_row->enabled_p)
12777 frame_row->enabled_p = 0;
12778
12779 ++window_row, ++frame_row;
12780 }
12781 }
12782
12783
12784 /* Find the glyph row in window W containing CHARPOS. Consider all
12785 rows between START and END (not inclusive). END null means search
12786 all rows to the end of the display area of W. Value is the row
12787 containing CHARPOS or null. */
12788
12789 struct glyph_row *
12790 row_containing_pos (w, charpos, start, end, dy)
12791 struct window *w;
12792 int charpos;
12793 struct glyph_row *start, *end;
12794 int dy;
12795 {
12796 struct glyph_row *row = start;
12797 int last_y;
12798
12799 /* If we happen to start on a header-line, skip that. */
12800 if (row->mode_line_p)
12801 ++row;
12802
12803 if ((end && row >= end) || !row->enabled_p)
12804 return NULL;
12805
12806 last_y = window_text_bottom_y (w) - dy;
12807
12808 while (1)
12809 {
12810 /* Give up if we have gone too far. */
12811 if (end && row >= end)
12812 return NULL;
12813 /* This formerly returned if they were equal.
12814 I think that both quantities are of a "last plus one" type;
12815 if so, when they are equal, the row is within the screen. -- rms. */
12816 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12817 return NULL;
12818
12819 /* If it is in this row, return this row. */
12820 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12821 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12822 /* The end position of a row equals the start
12823 position of the next row. If CHARPOS is there, we
12824 would rather display it in the next line, except
12825 when this line ends in ZV. */
12826 && !row->ends_at_zv_p
12827 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12828 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12829 return row;
12830 ++row;
12831 }
12832 }
12833
12834
12835 /* Try to redisplay window W by reusing its existing display. W's
12836 current matrix must be up to date when this function is called,
12837 i.e. window_end_valid must not be nil.
12838
12839 Value is
12840
12841 1 if display has been updated
12842 0 if otherwise unsuccessful
12843 -1 if redisplay with same window start is known not to succeed
12844
12845 The following steps are performed:
12846
12847 1. Find the last row in the current matrix of W that is not
12848 affected by changes at the start of current_buffer. If no such row
12849 is found, give up.
12850
12851 2. Find the first row in W's current matrix that is not affected by
12852 changes at the end of current_buffer. Maybe there is no such row.
12853
12854 3. Display lines beginning with the row + 1 found in step 1 to the
12855 row found in step 2 or, if step 2 didn't find a row, to the end of
12856 the window.
12857
12858 4. If cursor is not known to appear on the window, give up.
12859
12860 5. If display stopped at the row found in step 2, scroll the
12861 display and current matrix as needed.
12862
12863 6. Maybe display some lines at the end of W, if we must. This can
12864 happen under various circumstances, like a partially visible line
12865 becoming fully visible, or because newly displayed lines are displayed
12866 in smaller font sizes.
12867
12868 7. Update W's window end information. */
12869
12870 static int
12871 try_window_id (w)
12872 struct window *w;
12873 {
12874 struct frame *f = XFRAME (w->frame);
12875 struct glyph_matrix *current_matrix = w->current_matrix;
12876 struct glyph_matrix *desired_matrix = w->desired_matrix;
12877 struct glyph_row *last_unchanged_at_beg_row;
12878 struct glyph_row *first_unchanged_at_end_row;
12879 struct glyph_row *row;
12880 struct glyph_row *bottom_row;
12881 int bottom_vpos;
12882 struct it it;
12883 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12884 struct text_pos start_pos;
12885 struct run run;
12886 int first_unchanged_at_end_vpos = 0;
12887 struct glyph_row *last_text_row, *last_text_row_at_end;
12888 struct text_pos start;
12889 int first_changed_charpos, last_changed_charpos;
12890
12891 #if GLYPH_DEBUG
12892 if (inhibit_try_window_id)
12893 return 0;
12894 #endif
12895
12896 /* This is handy for debugging. */
12897 #if 0
12898 #define GIVE_UP(X) \
12899 do { \
12900 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12901 return 0; \
12902 } while (0)
12903 #else
12904 #define GIVE_UP(X) return 0
12905 #endif
12906
12907 SET_TEXT_POS_FROM_MARKER (start, w->start);
12908
12909 /* Don't use this for mini-windows because these can show
12910 messages and mini-buffers, and we don't handle that here. */
12911 if (MINI_WINDOW_P (w))
12912 GIVE_UP (1);
12913
12914 /* This flag is used to prevent redisplay optimizations. */
12915 if (windows_or_buffers_changed || cursor_type_changed)
12916 GIVE_UP (2);
12917
12918 /* Verify that narrowing has not changed.
12919 Also verify that we were not told to prevent redisplay optimizations.
12920 It would be nice to further
12921 reduce the number of cases where this prevents try_window_id. */
12922 if (current_buffer->clip_changed
12923 || current_buffer->prevent_redisplay_optimizations_p)
12924 GIVE_UP (3);
12925
12926 /* Window must either use window-based redisplay or be full width. */
12927 if (!FRAME_WINDOW_P (f)
12928 && (!FRAME_LINE_INS_DEL_OK (f)
12929 || !WINDOW_FULL_WIDTH_P (w)))
12930 GIVE_UP (4);
12931
12932 /* Give up if point is not known NOT to appear in W. */
12933 if (PT < CHARPOS (start))
12934 GIVE_UP (5);
12935
12936 /* Another way to prevent redisplay optimizations. */
12937 if (XFASTINT (w->last_modified) == 0)
12938 GIVE_UP (6);
12939
12940 /* Verify that window is not hscrolled. */
12941 if (XFASTINT (w->hscroll) != 0)
12942 GIVE_UP (7);
12943
12944 /* Verify that display wasn't paused. */
12945 if (NILP (w->window_end_valid))
12946 GIVE_UP (8);
12947
12948 /* Can't use this if highlighting a region because a cursor movement
12949 will do more than just set the cursor. */
12950 if (!NILP (Vtransient_mark_mode)
12951 && !NILP (current_buffer->mark_active))
12952 GIVE_UP (9);
12953
12954 /* Likewise if highlighting trailing whitespace. */
12955 if (!NILP (Vshow_trailing_whitespace))
12956 GIVE_UP (11);
12957
12958 /* Likewise if showing a region. */
12959 if (!NILP (w->region_showing))
12960 GIVE_UP (10);
12961
12962 /* Can use this if overlay arrow position and or string have changed. */
12963 if (overlay_arrows_changed_p ())
12964 GIVE_UP (12);
12965
12966
12967 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12968 only if buffer has really changed. The reason is that the gap is
12969 initially at Z for freshly visited files. The code below would
12970 set end_unchanged to 0 in that case. */
12971 if (MODIFF > SAVE_MODIFF
12972 /* This seems to happen sometimes after saving a buffer. */
12973 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12974 {
12975 if (GPT - BEG < BEG_UNCHANGED)
12976 BEG_UNCHANGED = GPT - BEG;
12977 if (Z - GPT < END_UNCHANGED)
12978 END_UNCHANGED = Z - GPT;
12979 }
12980
12981 /* The position of the first and last character that has been changed. */
12982 first_changed_charpos = BEG + BEG_UNCHANGED;
12983 last_changed_charpos = Z - END_UNCHANGED;
12984
12985 /* If window starts after a line end, and the last change is in
12986 front of that newline, then changes don't affect the display.
12987 This case happens with stealth-fontification. Note that although
12988 the display is unchanged, glyph positions in the matrix have to
12989 be adjusted, of course. */
12990 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12991 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12992 && ((last_changed_charpos < CHARPOS (start)
12993 && CHARPOS (start) == BEGV)
12994 || (last_changed_charpos < CHARPOS (start) - 1
12995 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12996 {
12997 int Z_old, delta, Z_BYTE_old, delta_bytes;
12998 struct glyph_row *r0;
12999
13000 /* Compute how many chars/bytes have been added to or removed
13001 from the buffer. */
13002 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13003 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13004 delta = Z - Z_old;
13005 delta_bytes = Z_BYTE - Z_BYTE_old;
13006
13007 /* Give up if PT is not in the window. Note that it already has
13008 been checked at the start of try_window_id that PT is not in
13009 front of the window start. */
13010 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13011 GIVE_UP (13);
13012
13013 /* If window start is unchanged, we can reuse the whole matrix
13014 as is, after adjusting glyph positions. No need to compute
13015 the window end again, since its offset from Z hasn't changed. */
13016 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13017 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13018 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13019 /* PT must not be in a partially visible line. */
13020 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13021 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13022 {
13023 /* Adjust positions in the glyph matrix. */
13024 if (delta || delta_bytes)
13025 {
13026 struct glyph_row *r1
13027 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13028 increment_matrix_positions (w->current_matrix,
13029 MATRIX_ROW_VPOS (r0, current_matrix),
13030 MATRIX_ROW_VPOS (r1, current_matrix),
13031 delta, delta_bytes);
13032 }
13033
13034 /* Set the cursor. */
13035 row = row_containing_pos (w, PT, r0, NULL, 0);
13036 if (row)
13037 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13038 else
13039 abort ();
13040 return 1;
13041 }
13042 }
13043
13044 /* Handle the case that changes are all below what is displayed in
13045 the window, and that PT is in the window. This shortcut cannot
13046 be taken if ZV is visible in the window, and text has been added
13047 there that is visible in the window. */
13048 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13049 /* ZV is not visible in the window, or there are no
13050 changes at ZV, actually. */
13051 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13052 || first_changed_charpos == last_changed_charpos))
13053 {
13054 struct glyph_row *r0;
13055
13056 /* Give up if PT is not in the window. Note that it already has
13057 been checked at the start of try_window_id that PT is not in
13058 front of the window start. */
13059 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13060 GIVE_UP (14);
13061
13062 /* If window start is unchanged, we can reuse the whole matrix
13063 as is, without changing glyph positions since no text has
13064 been added/removed in front of the window end. */
13065 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13066 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13067 /* PT must not be in a partially visible line. */
13068 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13069 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13070 {
13071 /* We have to compute the window end anew since text
13072 can have been added/removed after it. */
13073 w->window_end_pos
13074 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13075 w->window_end_bytepos
13076 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13077
13078 /* Set the cursor. */
13079 row = row_containing_pos (w, PT, r0, NULL, 0);
13080 if (row)
13081 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13082 else
13083 abort ();
13084 return 2;
13085 }
13086 }
13087
13088 /* Give up if window start is in the changed area.
13089
13090 The condition used to read
13091
13092 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13093
13094 but why that was tested escapes me at the moment. */
13095 if (CHARPOS (start) >= first_changed_charpos
13096 && CHARPOS (start) <= last_changed_charpos)
13097 GIVE_UP (15);
13098
13099 /* Check that window start agrees with the start of the first glyph
13100 row in its current matrix. Check this after we know the window
13101 start is not in changed text, otherwise positions would not be
13102 comparable. */
13103 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13104 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13105 GIVE_UP (16);
13106
13107 /* Give up if the window ends in strings. Overlay strings
13108 at the end are difficult to handle, so don't try. */
13109 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13110 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13111 GIVE_UP (20);
13112
13113 /* Compute the position at which we have to start displaying new
13114 lines. Some of the lines at the top of the window might be
13115 reusable because they are not displaying changed text. Find the
13116 last row in W's current matrix not affected by changes at the
13117 start of current_buffer. Value is null if changes start in the
13118 first line of window. */
13119 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13120 if (last_unchanged_at_beg_row)
13121 {
13122 /* Avoid starting to display in the moddle of a character, a TAB
13123 for instance. This is easier than to set up the iterator
13124 exactly, and it's not a frequent case, so the additional
13125 effort wouldn't really pay off. */
13126 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13127 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13128 && last_unchanged_at_beg_row > w->current_matrix->rows)
13129 --last_unchanged_at_beg_row;
13130
13131 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13132 GIVE_UP (17);
13133
13134 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13135 GIVE_UP (18);
13136 start_pos = it.current.pos;
13137
13138 /* Start displaying new lines in the desired matrix at the same
13139 vpos we would use in the current matrix, i.e. below
13140 last_unchanged_at_beg_row. */
13141 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13142 current_matrix);
13143 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13144 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13145
13146 xassert (it.hpos == 0 && it.current_x == 0);
13147 }
13148 else
13149 {
13150 /* There are no reusable lines at the start of the window.
13151 Start displaying in the first text line. */
13152 start_display (&it, w, start);
13153 it.vpos = it.first_vpos;
13154 start_pos = it.current.pos;
13155 }
13156
13157 /* Find the first row that is not affected by changes at the end of
13158 the buffer. Value will be null if there is no unchanged row, in
13159 which case we must redisplay to the end of the window. delta
13160 will be set to the value by which buffer positions beginning with
13161 first_unchanged_at_end_row have to be adjusted due to text
13162 changes. */
13163 first_unchanged_at_end_row
13164 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13165 IF_DEBUG (debug_delta = delta);
13166 IF_DEBUG (debug_delta_bytes = delta_bytes);
13167
13168 /* Set stop_pos to the buffer position up to which we will have to
13169 display new lines. If first_unchanged_at_end_row != NULL, this
13170 is the buffer position of the start of the line displayed in that
13171 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13172 that we don't stop at a buffer position. */
13173 stop_pos = 0;
13174 if (first_unchanged_at_end_row)
13175 {
13176 xassert (last_unchanged_at_beg_row == NULL
13177 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13178
13179 /* If this is a continuation line, move forward to the next one
13180 that isn't. Changes in lines above affect this line.
13181 Caution: this may move first_unchanged_at_end_row to a row
13182 not displaying text. */
13183 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13184 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13185 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13186 < it.last_visible_y))
13187 ++first_unchanged_at_end_row;
13188
13189 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13190 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13191 >= it.last_visible_y))
13192 first_unchanged_at_end_row = NULL;
13193 else
13194 {
13195 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13196 + delta);
13197 first_unchanged_at_end_vpos
13198 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13199 xassert (stop_pos >= Z - END_UNCHANGED);
13200 }
13201 }
13202 else if (last_unchanged_at_beg_row == NULL)
13203 GIVE_UP (19);
13204
13205
13206 #if GLYPH_DEBUG
13207
13208 /* Either there is no unchanged row at the end, or the one we have
13209 now displays text. This is a necessary condition for the window
13210 end pos calculation at the end of this function. */
13211 xassert (first_unchanged_at_end_row == NULL
13212 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13213
13214 debug_last_unchanged_at_beg_vpos
13215 = (last_unchanged_at_beg_row
13216 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13217 : -1);
13218 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13219
13220 #endif /* GLYPH_DEBUG != 0 */
13221
13222
13223 /* Display new lines. Set last_text_row to the last new line
13224 displayed which has text on it, i.e. might end up as being the
13225 line where the window_end_vpos is. */
13226 w->cursor.vpos = -1;
13227 last_text_row = NULL;
13228 overlay_arrow_seen = 0;
13229 while (it.current_y < it.last_visible_y
13230 && !fonts_changed_p
13231 && (first_unchanged_at_end_row == NULL
13232 || IT_CHARPOS (it) < stop_pos))
13233 {
13234 if (display_line (&it))
13235 last_text_row = it.glyph_row - 1;
13236 }
13237
13238 if (fonts_changed_p)
13239 return -1;
13240
13241
13242 /* Compute differences in buffer positions, y-positions etc. for
13243 lines reused at the bottom of the window. Compute what we can
13244 scroll. */
13245 if (first_unchanged_at_end_row
13246 /* No lines reused because we displayed everything up to the
13247 bottom of the window. */
13248 && it.current_y < it.last_visible_y)
13249 {
13250 dvpos = (it.vpos
13251 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13252 current_matrix));
13253 dy = it.current_y - first_unchanged_at_end_row->y;
13254 run.current_y = first_unchanged_at_end_row->y;
13255 run.desired_y = run.current_y + dy;
13256 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13257 }
13258 else
13259 {
13260 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13261 first_unchanged_at_end_row = NULL;
13262 }
13263 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13264
13265
13266 /* Find the cursor if not already found. We have to decide whether
13267 PT will appear on this window (it sometimes doesn't, but this is
13268 not a very frequent case.) This decision has to be made before
13269 the current matrix is altered. A value of cursor.vpos < 0 means
13270 that PT is either in one of the lines beginning at
13271 first_unchanged_at_end_row or below the window. Don't care for
13272 lines that might be displayed later at the window end; as
13273 mentioned, this is not a frequent case. */
13274 if (w->cursor.vpos < 0)
13275 {
13276 /* Cursor in unchanged rows at the top? */
13277 if (PT < CHARPOS (start_pos)
13278 && last_unchanged_at_beg_row)
13279 {
13280 row = row_containing_pos (w, PT,
13281 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13282 last_unchanged_at_beg_row + 1, 0);
13283 if (row)
13284 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13285 }
13286
13287 /* Start from first_unchanged_at_end_row looking for PT. */
13288 else if (first_unchanged_at_end_row)
13289 {
13290 row = row_containing_pos (w, PT - delta,
13291 first_unchanged_at_end_row, NULL, 0);
13292 if (row)
13293 set_cursor_from_row (w, row, w->current_matrix, delta,
13294 delta_bytes, dy, dvpos);
13295 }
13296
13297 /* Give up if cursor was not found. */
13298 if (w->cursor.vpos < 0)
13299 {
13300 clear_glyph_matrix (w->desired_matrix);
13301 return -1;
13302 }
13303 }
13304
13305 /* Don't let the cursor end in the scroll margins. */
13306 {
13307 int this_scroll_margin, cursor_height;
13308
13309 this_scroll_margin = max (0, scroll_margin);
13310 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13311 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13312 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13313
13314 if ((w->cursor.y < this_scroll_margin
13315 && CHARPOS (start) > BEGV)
13316 /* Don't take scroll margin into account at the bottom because
13317 old redisplay didn't do it either. */
13318 || w->cursor.y + cursor_height > it.last_visible_y)
13319 {
13320 w->cursor.vpos = -1;
13321 clear_glyph_matrix (w->desired_matrix);
13322 return -1;
13323 }
13324 }
13325
13326 /* Scroll the display. Do it before changing the current matrix so
13327 that xterm.c doesn't get confused about where the cursor glyph is
13328 found. */
13329 if (dy && run.height)
13330 {
13331 update_begin (f);
13332
13333 if (FRAME_WINDOW_P (f))
13334 {
13335 FRAME_RIF (f)->update_window_begin_hook (w);
13336 FRAME_RIF (f)->clear_window_mouse_face (w);
13337 FRAME_RIF (f)->scroll_run_hook (w, &run);
13338 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13339 }
13340 else
13341 {
13342 /* Terminal frame. In this case, dvpos gives the number of
13343 lines to scroll by; dvpos < 0 means scroll up. */
13344 int first_unchanged_at_end_vpos
13345 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13346 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13347 int end = (WINDOW_TOP_EDGE_LINE (w)
13348 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13349 + window_internal_height (w));
13350
13351 /* Perform the operation on the screen. */
13352 if (dvpos > 0)
13353 {
13354 /* Scroll last_unchanged_at_beg_row to the end of the
13355 window down dvpos lines. */
13356 set_terminal_window (f, end);
13357
13358 /* On dumb terminals delete dvpos lines at the end
13359 before inserting dvpos empty lines. */
13360 if (!FRAME_SCROLL_REGION_OK (f))
13361 ins_del_lines (f, end - dvpos, -dvpos);
13362
13363 /* Insert dvpos empty lines in front of
13364 last_unchanged_at_beg_row. */
13365 ins_del_lines (f, from, dvpos);
13366 }
13367 else if (dvpos < 0)
13368 {
13369 /* Scroll up last_unchanged_at_beg_vpos to the end of
13370 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13371 set_terminal_window (f, end);
13372
13373 /* Delete dvpos lines in front of
13374 last_unchanged_at_beg_vpos. ins_del_lines will set
13375 the cursor to the given vpos and emit |dvpos| delete
13376 line sequences. */
13377 ins_del_lines (f, from + dvpos, dvpos);
13378
13379 /* On a dumb terminal insert dvpos empty lines at the
13380 end. */
13381 if (!FRAME_SCROLL_REGION_OK (f))
13382 ins_del_lines (f, end + dvpos, -dvpos);
13383 }
13384
13385 set_terminal_window (f, 0);
13386 }
13387
13388 update_end (f);
13389 }
13390
13391 /* Shift reused rows of the current matrix to the right position.
13392 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13393 text. */
13394 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13395 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13396 if (dvpos < 0)
13397 {
13398 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13399 bottom_vpos, dvpos);
13400 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13401 bottom_vpos, 0);
13402 }
13403 else if (dvpos > 0)
13404 {
13405 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13406 bottom_vpos, dvpos);
13407 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13408 first_unchanged_at_end_vpos + dvpos, 0);
13409 }
13410
13411 /* For frame-based redisplay, make sure that current frame and window
13412 matrix are in sync with respect to glyph memory. */
13413 if (!FRAME_WINDOW_P (f))
13414 sync_frame_with_window_matrix_rows (w);
13415
13416 /* Adjust buffer positions in reused rows. */
13417 if (delta)
13418 increment_matrix_positions (current_matrix,
13419 first_unchanged_at_end_vpos + dvpos,
13420 bottom_vpos, delta, delta_bytes);
13421
13422 /* Adjust Y positions. */
13423 if (dy)
13424 shift_glyph_matrix (w, current_matrix,
13425 first_unchanged_at_end_vpos + dvpos,
13426 bottom_vpos, dy);
13427
13428 if (first_unchanged_at_end_row)
13429 first_unchanged_at_end_row += dvpos;
13430
13431 /* If scrolling up, there may be some lines to display at the end of
13432 the window. */
13433 last_text_row_at_end = NULL;
13434 if (dy < 0)
13435 {
13436 /* Scrolling up can leave for example a partially visible line
13437 at the end of the window to be redisplayed. */
13438 /* Set last_row to the glyph row in the current matrix where the
13439 window end line is found. It has been moved up or down in
13440 the matrix by dvpos. */
13441 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13442 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13443
13444 /* If last_row is the window end line, it should display text. */
13445 xassert (last_row->displays_text_p);
13446
13447 /* If window end line was partially visible before, begin
13448 displaying at that line. Otherwise begin displaying with the
13449 line following it. */
13450 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13451 {
13452 init_to_row_start (&it, w, last_row);
13453 it.vpos = last_vpos;
13454 it.current_y = last_row->y;
13455 }
13456 else
13457 {
13458 init_to_row_end (&it, w, last_row);
13459 it.vpos = 1 + last_vpos;
13460 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13461 ++last_row;
13462 }
13463
13464 /* We may start in a continuation line. If so, we have to
13465 get the right continuation_lines_width and current_x. */
13466 it.continuation_lines_width = last_row->continuation_lines_width;
13467 it.hpos = it.current_x = 0;
13468
13469 /* Display the rest of the lines at the window end. */
13470 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13471 while (it.current_y < it.last_visible_y
13472 && !fonts_changed_p)
13473 {
13474 /* Is it always sure that the display agrees with lines in
13475 the current matrix? I don't think so, so we mark rows
13476 displayed invalid in the current matrix by setting their
13477 enabled_p flag to zero. */
13478 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13479 if (display_line (&it))
13480 last_text_row_at_end = it.glyph_row - 1;
13481 }
13482 }
13483
13484 /* Update window_end_pos and window_end_vpos. */
13485 if (first_unchanged_at_end_row
13486 && first_unchanged_at_end_row->y < it.last_visible_y
13487 && !last_text_row_at_end)
13488 {
13489 /* Window end line if one of the preserved rows from the current
13490 matrix. Set row to the last row displaying text in current
13491 matrix starting at first_unchanged_at_end_row, after
13492 scrolling. */
13493 xassert (first_unchanged_at_end_row->displays_text_p);
13494 row = find_last_row_displaying_text (w->current_matrix, &it,
13495 first_unchanged_at_end_row);
13496 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13497
13498 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13499 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13500 w->window_end_vpos
13501 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13502 xassert (w->window_end_bytepos >= 0);
13503 IF_DEBUG (debug_method_add (w, "A"));
13504 }
13505 else if (last_text_row_at_end)
13506 {
13507 w->window_end_pos
13508 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13509 w->window_end_bytepos
13510 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13511 w->window_end_vpos
13512 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13513 xassert (w->window_end_bytepos >= 0);
13514 IF_DEBUG (debug_method_add (w, "B"));
13515 }
13516 else if (last_text_row)
13517 {
13518 /* We have displayed either to the end of the window or at the
13519 end of the window, i.e. the last row with text is to be found
13520 in the desired matrix. */
13521 w->window_end_pos
13522 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13523 w->window_end_bytepos
13524 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13525 w->window_end_vpos
13526 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13527 xassert (w->window_end_bytepos >= 0);
13528 }
13529 else if (first_unchanged_at_end_row == NULL
13530 && last_text_row == NULL
13531 && last_text_row_at_end == NULL)
13532 {
13533 /* Displayed to end of window, but no line containing text was
13534 displayed. Lines were deleted at the end of the window. */
13535 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13536 int vpos = XFASTINT (w->window_end_vpos);
13537 struct glyph_row *current_row = current_matrix->rows + vpos;
13538 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13539
13540 for (row = NULL;
13541 row == NULL && vpos >= first_vpos;
13542 --vpos, --current_row, --desired_row)
13543 {
13544 if (desired_row->enabled_p)
13545 {
13546 if (desired_row->displays_text_p)
13547 row = desired_row;
13548 }
13549 else if (current_row->displays_text_p)
13550 row = current_row;
13551 }
13552
13553 xassert (row != NULL);
13554 w->window_end_vpos = make_number (vpos + 1);
13555 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13556 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13557 xassert (w->window_end_bytepos >= 0);
13558 IF_DEBUG (debug_method_add (w, "C"));
13559 }
13560 else
13561 abort ();
13562
13563 #if 0 /* This leads to problems, for instance when the cursor is
13564 at ZV, and the cursor line displays no text. */
13565 /* Disable rows below what's displayed in the window. This makes
13566 debugging easier. */
13567 enable_glyph_matrix_rows (current_matrix,
13568 XFASTINT (w->window_end_vpos) + 1,
13569 bottom_vpos, 0);
13570 #endif
13571
13572 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13573 debug_end_vpos = XFASTINT (w->window_end_vpos));
13574
13575 /* Record that display has not been completed. */
13576 w->window_end_valid = Qnil;
13577 w->desired_matrix->no_scrolling_p = 1;
13578 return 3;
13579
13580 #undef GIVE_UP
13581 }
13582
13583
13584 \f
13585 /***********************************************************************
13586 More debugging support
13587 ***********************************************************************/
13588
13589 #if GLYPH_DEBUG
13590
13591 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13592 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13593 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13594
13595
13596 /* Dump the contents of glyph matrix MATRIX on stderr.
13597
13598 GLYPHS 0 means don't show glyph contents.
13599 GLYPHS 1 means show glyphs in short form
13600 GLYPHS > 1 means show glyphs in long form. */
13601
13602 void
13603 dump_glyph_matrix (matrix, glyphs)
13604 struct glyph_matrix *matrix;
13605 int glyphs;
13606 {
13607 int i;
13608 for (i = 0; i < matrix->nrows; ++i)
13609 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13610 }
13611
13612
13613 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13614 the glyph row and area where the glyph comes from. */
13615
13616 void
13617 dump_glyph (row, glyph, area)
13618 struct glyph_row *row;
13619 struct glyph *glyph;
13620 int area;
13621 {
13622 if (glyph->type == CHAR_GLYPH)
13623 {
13624 fprintf (stderr,
13625 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13626 glyph - row->glyphs[TEXT_AREA],
13627 'C',
13628 glyph->charpos,
13629 (BUFFERP (glyph->object)
13630 ? 'B'
13631 : (STRINGP (glyph->object)
13632 ? 'S'
13633 : '-')),
13634 glyph->pixel_width,
13635 glyph->u.ch,
13636 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13637 ? glyph->u.ch
13638 : '.'),
13639 glyph->face_id,
13640 glyph->left_box_line_p,
13641 glyph->right_box_line_p);
13642 }
13643 else if (glyph->type == STRETCH_GLYPH)
13644 {
13645 fprintf (stderr,
13646 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13647 glyph - row->glyphs[TEXT_AREA],
13648 'S',
13649 glyph->charpos,
13650 (BUFFERP (glyph->object)
13651 ? 'B'
13652 : (STRINGP (glyph->object)
13653 ? 'S'
13654 : '-')),
13655 glyph->pixel_width,
13656 0,
13657 '.',
13658 glyph->face_id,
13659 glyph->left_box_line_p,
13660 glyph->right_box_line_p);
13661 }
13662 else if (glyph->type == IMAGE_GLYPH)
13663 {
13664 fprintf (stderr,
13665 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13666 glyph - row->glyphs[TEXT_AREA],
13667 'I',
13668 glyph->charpos,
13669 (BUFFERP (glyph->object)
13670 ? 'B'
13671 : (STRINGP (glyph->object)
13672 ? 'S'
13673 : '-')),
13674 glyph->pixel_width,
13675 glyph->u.img_id,
13676 '.',
13677 glyph->face_id,
13678 glyph->left_box_line_p,
13679 glyph->right_box_line_p);
13680 }
13681 }
13682
13683
13684 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13685 GLYPHS 0 means don't show glyph contents.
13686 GLYPHS 1 means show glyphs in short form
13687 GLYPHS > 1 means show glyphs in long form. */
13688
13689 void
13690 dump_glyph_row (row, vpos, glyphs)
13691 struct glyph_row *row;
13692 int vpos, glyphs;
13693 {
13694 if (glyphs != 1)
13695 {
13696 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13697 fprintf (stderr, "=======================================================================\n");
13698
13699 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13700 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13701 vpos,
13702 MATRIX_ROW_START_CHARPOS (row),
13703 MATRIX_ROW_END_CHARPOS (row),
13704 row->used[TEXT_AREA],
13705 row->contains_overlapping_glyphs_p,
13706 row->enabled_p,
13707 row->truncated_on_left_p,
13708 row->truncated_on_right_p,
13709 row->overlay_arrow_p,
13710 row->continued_p,
13711 MATRIX_ROW_CONTINUATION_LINE_P (row),
13712 row->displays_text_p,
13713 row->ends_at_zv_p,
13714 row->fill_line_p,
13715 row->ends_in_middle_of_char_p,
13716 row->starts_in_middle_of_char_p,
13717 row->mouse_face_p,
13718 row->x,
13719 row->y,
13720 row->pixel_width,
13721 row->height,
13722 row->visible_height,
13723 row->ascent,
13724 row->phys_ascent);
13725 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13726 row->end.overlay_string_index,
13727 row->continuation_lines_width);
13728 fprintf (stderr, "%9d %5d\n",
13729 CHARPOS (row->start.string_pos),
13730 CHARPOS (row->end.string_pos));
13731 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13732 row->end.dpvec_index);
13733 }
13734
13735 if (glyphs > 1)
13736 {
13737 int area;
13738
13739 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13740 {
13741 struct glyph *glyph = row->glyphs[area];
13742 struct glyph *glyph_end = glyph + row->used[area];
13743
13744 /* Glyph for a line end in text. */
13745 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13746 ++glyph_end;
13747
13748 if (glyph < glyph_end)
13749 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13750
13751 for (; glyph < glyph_end; ++glyph)
13752 dump_glyph (row, glyph, area);
13753 }
13754 }
13755 else if (glyphs == 1)
13756 {
13757 int area;
13758
13759 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13760 {
13761 char *s = (char *) alloca (row->used[area] + 1);
13762 int i;
13763
13764 for (i = 0; i < row->used[area]; ++i)
13765 {
13766 struct glyph *glyph = row->glyphs[area] + i;
13767 if (glyph->type == CHAR_GLYPH
13768 && glyph->u.ch < 0x80
13769 && glyph->u.ch >= ' ')
13770 s[i] = glyph->u.ch;
13771 else
13772 s[i] = '.';
13773 }
13774
13775 s[i] = '\0';
13776 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13777 }
13778 }
13779 }
13780
13781
13782 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13783 Sdump_glyph_matrix, 0, 1, "p",
13784 doc: /* Dump the current matrix of the selected window to stderr.
13785 Shows contents of glyph row structures. With non-nil
13786 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13787 glyphs in short form, otherwise show glyphs in long form. */)
13788 (glyphs)
13789 Lisp_Object glyphs;
13790 {
13791 struct window *w = XWINDOW (selected_window);
13792 struct buffer *buffer = XBUFFER (w->buffer);
13793
13794 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13795 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13796 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13797 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13798 fprintf (stderr, "=============================================\n");
13799 dump_glyph_matrix (w->current_matrix,
13800 NILP (glyphs) ? 0 : XINT (glyphs));
13801 return Qnil;
13802 }
13803
13804
13805 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13806 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13807 ()
13808 {
13809 struct frame *f = XFRAME (selected_frame);
13810 dump_glyph_matrix (f->current_matrix, 1);
13811 return Qnil;
13812 }
13813
13814
13815 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13816 doc: /* Dump glyph row ROW to stderr.
13817 GLYPH 0 means don't dump glyphs.
13818 GLYPH 1 means dump glyphs in short form.
13819 GLYPH > 1 or omitted means dump glyphs in long form. */)
13820 (row, glyphs)
13821 Lisp_Object row, glyphs;
13822 {
13823 struct glyph_matrix *matrix;
13824 int vpos;
13825
13826 CHECK_NUMBER (row);
13827 matrix = XWINDOW (selected_window)->current_matrix;
13828 vpos = XINT (row);
13829 if (vpos >= 0 && vpos < matrix->nrows)
13830 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13831 vpos,
13832 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13833 return Qnil;
13834 }
13835
13836
13837 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13838 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13839 GLYPH 0 means don't dump glyphs.
13840 GLYPH 1 means dump glyphs in short form.
13841 GLYPH > 1 or omitted means dump glyphs in long form. */)
13842 (row, glyphs)
13843 Lisp_Object row, glyphs;
13844 {
13845 struct frame *sf = SELECTED_FRAME ();
13846 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13847 int vpos;
13848
13849 CHECK_NUMBER (row);
13850 vpos = XINT (row);
13851 if (vpos >= 0 && vpos < m->nrows)
13852 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13853 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13854 return Qnil;
13855 }
13856
13857
13858 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13859 doc: /* Toggle tracing of redisplay.
13860 With ARG, turn tracing on if and only if ARG is positive. */)
13861 (arg)
13862 Lisp_Object arg;
13863 {
13864 if (NILP (arg))
13865 trace_redisplay_p = !trace_redisplay_p;
13866 else
13867 {
13868 arg = Fprefix_numeric_value (arg);
13869 trace_redisplay_p = XINT (arg) > 0;
13870 }
13871
13872 return Qnil;
13873 }
13874
13875
13876 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13877 doc: /* Like `format', but print result to stderr.
13878 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13879 (nargs, args)
13880 int nargs;
13881 Lisp_Object *args;
13882 {
13883 Lisp_Object s = Fformat (nargs, args);
13884 fprintf (stderr, "%s", SDATA (s));
13885 return Qnil;
13886 }
13887
13888 #endif /* GLYPH_DEBUG */
13889
13890
13891 \f
13892 /***********************************************************************
13893 Building Desired Matrix Rows
13894 ***********************************************************************/
13895
13896 /* Return a temporary glyph row holding the glyphs of an overlay
13897 arrow. Only used for non-window-redisplay windows. */
13898
13899 static struct glyph_row *
13900 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
13901 struct window *w;
13902 Lisp_Object overlay_arrow_string;
13903 {
13904 struct frame *f = XFRAME (WINDOW_FRAME (w));
13905 struct buffer *buffer = XBUFFER (w->buffer);
13906 struct buffer *old = current_buffer;
13907 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
13908 int arrow_len = SCHARS (overlay_arrow_string);
13909 const unsigned char *arrow_end = arrow_string + arrow_len;
13910 const unsigned char *p;
13911 struct it it;
13912 int multibyte_p;
13913 int n_glyphs_before;
13914
13915 set_buffer_temp (buffer);
13916 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13917 it.glyph_row->used[TEXT_AREA] = 0;
13918 SET_TEXT_POS (it.position, 0, 0);
13919
13920 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13921 p = arrow_string;
13922 while (p < arrow_end)
13923 {
13924 Lisp_Object face, ilisp;
13925
13926 /* Get the next character. */
13927 if (multibyte_p)
13928 it.c = string_char_and_length (p, arrow_len, &it.len);
13929 else
13930 it.c = *p, it.len = 1;
13931 p += it.len;
13932
13933 /* Get its face. */
13934 ilisp = make_number (p - arrow_string);
13935 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
13936 it.face_id = compute_char_face (f, it.c, face);
13937
13938 /* Compute its width, get its glyphs. */
13939 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13940 SET_TEXT_POS (it.position, -1, -1);
13941 PRODUCE_GLYPHS (&it);
13942
13943 /* If this character doesn't fit any more in the line, we have
13944 to remove some glyphs. */
13945 if (it.current_x > it.last_visible_x)
13946 {
13947 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13948 break;
13949 }
13950 }
13951
13952 set_buffer_temp (old);
13953 return it.glyph_row;
13954 }
13955
13956
13957 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13958 glyphs are only inserted for terminal frames since we can't really
13959 win with truncation glyphs when partially visible glyphs are
13960 involved. Which glyphs to insert is determined by
13961 produce_special_glyphs. */
13962
13963 static void
13964 insert_left_trunc_glyphs (it)
13965 struct it *it;
13966 {
13967 struct it truncate_it;
13968 struct glyph *from, *end, *to, *toend;
13969
13970 xassert (!FRAME_WINDOW_P (it->f));
13971
13972 /* Get the truncation glyphs. */
13973 truncate_it = *it;
13974 truncate_it.current_x = 0;
13975 truncate_it.face_id = DEFAULT_FACE_ID;
13976 truncate_it.glyph_row = &scratch_glyph_row;
13977 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13978 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13979 truncate_it.object = make_number (0);
13980 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13981
13982 /* Overwrite glyphs from IT with truncation glyphs. */
13983 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13984 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13985 to = it->glyph_row->glyphs[TEXT_AREA];
13986 toend = to + it->glyph_row->used[TEXT_AREA];
13987
13988 while (from < end)
13989 *to++ = *from++;
13990
13991 /* There may be padding glyphs left over. Overwrite them too. */
13992 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13993 {
13994 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13995 while (from < end)
13996 *to++ = *from++;
13997 }
13998
13999 if (to > toend)
14000 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14001 }
14002
14003
14004 /* Compute the pixel height and width of IT->glyph_row.
14005
14006 Most of the time, ascent and height of a display line will be equal
14007 to the max_ascent and max_height values of the display iterator
14008 structure. This is not the case if
14009
14010 1. We hit ZV without displaying anything. In this case, max_ascent
14011 and max_height will be zero.
14012
14013 2. We have some glyphs that don't contribute to the line height.
14014 (The glyph row flag contributes_to_line_height_p is for future
14015 pixmap extensions).
14016
14017 The first case is easily covered by using default values because in
14018 these cases, the line height does not really matter, except that it
14019 must not be zero. */
14020
14021 static void
14022 compute_line_metrics (it)
14023 struct it *it;
14024 {
14025 struct glyph_row *row = it->glyph_row;
14026 int area, i;
14027
14028 if (FRAME_WINDOW_P (it->f))
14029 {
14030 int i, min_y, max_y;
14031
14032 /* The line may consist of one space only, that was added to
14033 place the cursor on it. If so, the row's height hasn't been
14034 computed yet. */
14035 if (row->height == 0)
14036 {
14037 if (it->max_ascent + it->max_descent == 0)
14038 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14039 row->ascent = it->max_ascent;
14040 row->height = it->max_ascent + it->max_descent;
14041 row->phys_ascent = it->max_phys_ascent;
14042 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14043 }
14044
14045 /* Compute the width of this line. */
14046 row->pixel_width = row->x;
14047 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14048 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14049
14050 xassert (row->pixel_width >= 0);
14051 xassert (row->ascent >= 0 && row->height > 0);
14052
14053 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14054 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14055
14056 /* If first line's physical ascent is larger than its logical
14057 ascent, use the physical ascent, and make the row taller.
14058 This makes accented characters fully visible. */
14059 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14060 && row->phys_ascent > row->ascent)
14061 {
14062 row->height += row->phys_ascent - row->ascent;
14063 row->ascent = row->phys_ascent;
14064 }
14065
14066 /* Compute how much of the line is visible. */
14067 row->visible_height = row->height;
14068
14069 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14070 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14071
14072 if (row->y < min_y)
14073 row->visible_height -= min_y - row->y;
14074 if (row->y + row->height > max_y)
14075 row->visible_height -= row->y + row->height - max_y;
14076 }
14077 else
14078 {
14079 row->pixel_width = row->used[TEXT_AREA];
14080 if (row->continued_p)
14081 row->pixel_width -= it->continuation_pixel_width;
14082 else if (row->truncated_on_right_p)
14083 row->pixel_width -= it->truncation_pixel_width;
14084 row->ascent = row->phys_ascent = 0;
14085 row->height = row->phys_height = row->visible_height = 1;
14086 }
14087
14088 /* Compute a hash code for this row. */
14089 row->hash = 0;
14090 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14091 for (i = 0; i < row->used[area]; ++i)
14092 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14093 + row->glyphs[area][i].u.val
14094 + row->glyphs[area][i].face_id
14095 + row->glyphs[area][i].padding_p
14096 + (row->glyphs[area][i].type << 2));
14097
14098 it->max_ascent = it->max_descent = 0;
14099 it->max_phys_ascent = it->max_phys_descent = 0;
14100 }
14101
14102
14103 /* Append one space to the glyph row of iterator IT if doing a
14104 window-based redisplay. DEFAULT_FACE_P non-zero means let the
14105 space have the default face, otherwise let it have the same face as
14106 IT->face_id. Value is non-zero if a space was added.
14107
14108 This function is called to make sure that there is always one glyph
14109 at the end of a glyph row that the cursor can be set on under
14110 window-systems. (If there weren't such a glyph we would not know
14111 how wide and tall a box cursor should be displayed).
14112
14113 At the same time this space let's a nicely handle clearing to the
14114 end of the line if the row ends in italic text. */
14115
14116 static int
14117 append_space (it, default_face_p)
14118 struct it *it;
14119 int default_face_p;
14120 {
14121 if (FRAME_WINDOW_P (it->f))
14122 {
14123 int n = it->glyph_row->used[TEXT_AREA];
14124
14125 if (it->glyph_row->glyphs[TEXT_AREA] + n
14126 < it->glyph_row->glyphs[1 + TEXT_AREA])
14127 {
14128 /* Save some values that must not be changed.
14129 Must save IT->c and IT->len because otherwise
14130 ITERATOR_AT_END_P wouldn't work anymore after
14131 append_space has been called. */
14132 enum display_element_type saved_what = it->what;
14133 int saved_c = it->c, saved_len = it->len;
14134 int saved_x = it->current_x;
14135 int saved_face_id = it->face_id;
14136 struct text_pos saved_pos;
14137 Lisp_Object saved_object;
14138 struct face *face;
14139
14140 saved_object = it->object;
14141 saved_pos = it->position;
14142
14143 it->what = IT_CHARACTER;
14144 bzero (&it->position, sizeof it->position);
14145 it->object = make_number (0);
14146 it->c = ' ';
14147 it->len = 1;
14148
14149 if (default_face_p)
14150 it->face_id = DEFAULT_FACE_ID;
14151 else if (it->face_before_selective_p)
14152 it->face_id = it->saved_face_id;
14153 face = FACE_FROM_ID (it->f, it->face_id);
14154 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14155
14156 PRODUCE_GLYPHS (it);
14157
14158 it->current_x = saved_x;
14159 it->object = saved_object;
14160 it->position = saved_pos;
14161 it->what = saved_what;
14162 it->face_id = saved_face_id;
14163 it->len = saved_len;
14164 it->c = saved_c;
14165 return 1;
14166 }
14167 }
14168
14169 return 0;
14170 }
14171
14172
14173 /* Extend the face of the last glyph in the text area of IT->glyph_row
14174 to the end of the display line. Called from display_line.
14175 If the glyph row is empty, add a space glyph to it so that we
14176 know the face to draw. Set the glyph row flag fill_line_p. */
14177
14178 static void
14179 extend_face_to_end_of_line (it)
14180 struct it *it;
14181 {
14182 struct face *face;
14183 struct frame *f = it->f;
14184
14185 /* If line is already filled, do nothing. */
14186 if (it->current_x >= it->last_visible_x)
14187 return;
14188
14189 /* Face extension extends the background and box of IT->face_id
14190 to the end of the line. If the background equals the background
14191 of the frame, we don't have to do anything. */
14192 if (it->face_before_selective_p)
14193 face = FACE_FROM_ID (it->f, it->saved_face_id);
14194 else
14195 face = FACE_FROM_ID (f, it->face_id);
14196
14197 if (FRAME_WINDOW_P (f)
14198 && face->box == FACE_NO_BOX
14199 && face->background == FRAME_BACKGROUND_PIXEL (f)
14200 && !face->stipple)
14201 return;
14202
14203 /* Set the glyph row flag indicating that the face of the last glyph
14204 in the text area has to be drawn to the end of the text area. */
14205 it->glyph_row->fill_line_p = 1;
14206
14207 /* If current character of IT is not ASCII, make sure we have the
14208 ASCII face. This will be automatically undone the next time
14209 get_next_display_element returns a multibyte character. Note
14210 that the character will always be single byte in unibyte text. */
14211 if (!SINGLE_BYTE_CHAR_P (it->c))
14212 {
14213 it->face_id = FACE_FOR_CHAR (f, face, 0);
14214 }
14215
14216 if (FRAME_WINDOW_P (f))
14217 {
14218 /* If the row is empty, add a space with the current face of IT,
14219 so that we know which face to draw. */
14220 if (it->glyph_row->used[TEXT_AREA] == 0)
14221 {
14222 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14223 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14224 it->glyph_row->used[TEXT_AREA] = 1;
14225 }
14226 }
14227 else
14228 {
14229 /* Save some values that must not be changed. */
14230 int saved_x = it->current_x;
14231 struct text_pos saved_pos;
14232 Lisp_Object saved_object;
14233 enum display_element_type saved_what = it->what;
14234 int saved_face_id = it->face_id;
14235
14236 saved_object = it->object;
14237 saved_pos = it->position;
14238
14239 it->what = IT_CHARACTER;
14240 bzero (&it->position, sizeof it->position);
14241 it->object = make_number (0);
14242 it->c = ' ';
14243 it->len = 1;
14244 it->face_id = face->id;
14245
14246 PRODUCE_GLYPHS (it);
14247
14248 while (it->current_x <= it->last_visible_x)
14249 PRODUCE_GLYPHS (it);
14250
14251 /* Don't count these blanks really. It would let us insert a left
14252 truncation glyph below and make us set the cursor on them, maybe. */
14253 it->current_x = saved_x;
14254 it->object = saved_object;
14255 it->position = saved_pos;
14256 it->what = saved_what;
14257 it->face_id = saved_face_id;
14258 }
14259 }
14260
14261
14262 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14263 trailing whitespace. */
14264
14265 static int
14266 trailing_whitespace_p (charpos)
14267 int charpos;
14268 {
14269 int bytepos = CHAR_TO_BYTE (charpos);
14270 int c = 0;
14271
14272 while (bytepos < ZV_BYTE
14273 && (c = FETCH_CHAR (bytepos),
14274 c == ' ' || c == '\t'))
14275 ++bytepos;
14276
14277 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14278 {
14279 if (bytepos != PT_BYTE)
14280 return 1;
14281 }
14282 return 0;
14283 }
14284
14285
14286 /* Highlight trailing whitespace, if any, in ROW. */
14287
14288 void
14289 highlight_trailing_whitespace (f, row)
14290 struct frame *f;
14291 struct glyph_row *row;
14292 {
14293 int used = row->used[TEXT_AREA];
14294
14295 if (used)
14296 {
14297 struct glyph *start = row->glyphs[TEXT_AREA];
14298 struct glyph *glyph = start + used - 1;
14299
14300 /* Skip over glyphs inserted to display the cursor at the
14301 end of a line, for extending the face of the last glyph
14302 to the end of the line on terminals, and for truncation
14303 and continuation glyphs. */
14304 while (glyph >= start
14305 && glyph->type == CHAR_GLYPH
14306 && INTEGERP (glyph->object))
14307 --glyph;
14308
14309 /* If last glyph is a space or stretch, and it's trailing
14310 whitespace, set the face of all trailing whitespace glyphs in
14311 IT->glyph_row to `trailing-whitespace'. */
14312 if (glyph >= start
14313 && BUFFERP (glyph->object)
14314 && (glyph->type == STRETCH_GLYPH
14315 || (glyph->type == CHAR_GLYPH
14316 && glyph->u.ch == ' '))
14317 && trailing_whitespace_p (glyph->charpos))
14318 {
14319 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14320
14321 while (glyph >= start
14322 && BUFFERP (glyph->object)
14323 && (glyph->type == STRETCH_GLYPH
14324 || (glyph->type == CHAR_GLYPH
14325 && glyph->u.ch == ' ')))
14326 (glyph--)->face_id = face_id;
14327 }
14328 }
14329 }
14330
14331
14332 /* Value is non-zero if glyph row ROW in window W should be
14333 used to hold the cursor. */
14334
14335 static int
14336 cursor_row_p (w, row)
14337 struct window *w;
14338 struct glyph_row *row;
14339 {
14340 int cursor_row_p = 1;
14341
14342 if (PT == MATRIX_ROW_END_CHARPOS (row))
14343 {
14344 /* If the row ends with a newline from a string, we don't want
14345 the cursor there (if the row is continued it doesn't end in a
14346 newline). */
14347 if (CHARPOS (row->end.string_pos) >= 0
14348 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14349 cursor_row_p = row->continued_p;
14350
14351 /* If the row ends at ZV, display the cursor at the end of that
14352 row instead of at the start of the row below. */
14353 else if (row->ends_at_zv_p)
14354 cursor_row_p = 1;
14355 else
14356 cursor_row_p = 0;
14357 }
14358
14359 return cursor_row_p;
14360 }
14361
14362
14363 /* Construct the glyph row IT->glyph_row in the desired matrix of
14364 IT->w from text at the current position of IT. See dispextern.h
14365 for an overview of struct it. Value is non-zero if
14366 IT->glyph_row displays text, as opposed to a line displaying ZV
14367 only. */
14368
14369 static int
14370 display_line (it)
14371 struct it *it;
14372 {
14373 struct glyph_row *row = it->glyph_row;
14374 int overlay_arrow_bitmap;
14375 Lisp_Object overlay_arrow_string;
14376
14377 /* We always start displaying at hpos zero even if hscrolled. */
14378 xassert (it->hpos == 0 && it->current_x == 0);
14379
14380 /* We must not display in a row that's not a text row. */
14381 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14382 < it->w->desired_matrix->nrows);
14383
14384 /* Is IT->w showing the region? */
14385 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14386
14387 /* Clear the result glyph row and enable it. */
14388 prepare_desired_row (row);
14389
14390 row->y = it->current_y;
14391 row->start = it->start;
14392 row->continuation_lines_width = it->continuation_lines_width;
14393 row->displays_text_p = 1;
14394 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14395 it->starts_in_middle_of_char_p = 0;
14396
14397 /* Arrange the overlays nicely for our purposes. Usually, we call
14398 display_line on only one line at a time, in which case this
14399 can't really hurt too much, or we call it on lines which appear
14400 one after another in the buffer, in which case all calls to
14401 recenter_overlay_lists but the first will be pretty cheap. */
14402 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14403
14404 /* Move over display elements that are not visible because we are
14405 hscrolled. This may stop at an x-position < IT->first_visible_x
14406 if the first glyph is partially visible or if we hit a line end. */
14407 if (it->current_x < it->first_visible_x)
14408 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14409 MOVE_TO_POS | MOVE_TO_X);
14410
14411 /* Get the initial row height. This is either the height of the
14412 text hscrolled, if there is any, or zero. */
14413 row->ascent = it->max_ascent;
14414 row->height = it->max_ascent + it->max_descent;
14415 row->phys_ascent = it->max_phys_ascent;
14416 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14417
14418 /* Loop generating characters. The loop is left with IT on the next
14419 character to display. */
14420 while (1)
14421 {
14422 int n_glyphs_before, hpos_before, x_before;
14423 int x, i, nglyphs;
14424 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14425
14426 /* Retrieve the next thing to display. Value is zero if end of
14427 buffer reached. */
14428 if (!get_next_display_element (it))
14429 {
14430 /* Maybe add a space at the end of this line that is used to
14431 display the cursor there under X. Set the charpos of the
14432 first glyph of blank lines not corresponding to any text
14433 to -1. */
14434 #ifdef HAVE_WINDOW_SYSTEM
14435 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14436 row->exact_window_width_line_p = 1;
14437 else
14438 #endif /* HAVE_WINDOW_SYSTEM */
14439 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14440 || row->used[TEXT_AREA] == 0)
14441 {
14442 row->glyphs[TEXT_AREA]->charpos = -1;
14443 row->displays_text_p = 0;
14444
14445 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14446 && (!MINI_WINDOW_P (it->w)
14447 || (minibuf_level && EQ (it->window, minibuf_window))))
14448 row->indicate_empty_line_p = 1;
14449 }
14450
14451 it->continuation_lines_width = 0;
14452 row->ends_at_zv_p = 1;
14453 break;
14454 }
14455
14456 /* Now, get the metrics of what we want to display. This also
14457 generates glyphs in `row' (which is IT->glyph_row). */
14458 n_glyphs_before = row->used[TEXT_AREA];
14459 x = it->current_x;
14460
14461 /* Remember the line height so far in case the next element doesn't
14462 fit on the line. */
14463 if (!it->truncate_lines_p)
14464 {
14465 ascent = it->max_ascent;
14466 descent = it->max_descent;
14467 phys_ascent = it->max_phys_ascent;
14468 phys_descent = it->max_phys_descent;
14469 }
14470
14471 PRODUCE_GLYPHS (it);
14472
14473 /* If this display element was in marginal areas, continue with
14474 the next one. */
14475 if (it->area != TEXT_AREA)
14476 {
14477 row->ascent = max (row->ascent, it->max_ascent);
14478 row->height = max (row->height, it->max_ascent + it->max_descent);
14479 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14480 row->phys_height = max (row->phys_height,
14481 it->max_phys_ascent + it->max_phys_descent);
14482 set_iterator_to_next (it, 1);
14483 continue;
14484 }
14485
14486 /* Does the display element fit on the line? If we truncate
14487 lines, we should draw past the right edge of the window. If
14488 we don't truncate, we want to stop so that we can display the
14489 continuation glyph before the right margin. If lines are
14490 continued, there are two possible strategies for characters
14491 resulting in more than 1 glyph (e.g. tabs): Display as many
14492 glyphs as possible in this line and leave the rest for the
14493 continuation line, or display the whole element in the next
14494 line. Original redisplay did the former, so we do it also. */
14495 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14496 hpos_before = it->hpos;
14497 x_before = x;
14498
14499 if (/* Not a newline. */
14500 nglyphs > 0
14501 /* Glyphs produced fit entirely in the line. */
14502 && it->current_x < it->last_visible_x)
14503 {
14504 it->hpos += nglyphs;
14505 row->ascent = max (row->ascent, it->max_ascent);
14506 row->height = max (row->height, it->max_ascent + it->max_descent);
14507 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14508 row->phys_height = max (row->phys_height,
14509 it->max_phys_ascent + it->max_phys_descent);
14510 if (it->current_x - it->pixel_width < it->first_visible_x)
14511 row->x = x - it->first_visible_x;
14512 }
14513 else
14514 {
14515 int new_x;
14516 struct glyph *glyph;
14517
14518 for (i = 0; i < nglyphs; ++i, x = new_x)
14519 {
14520 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14521 new_x = x + glyph->pixel_width;
14522
14523 if (/* Lines are continued. */
14524 !it->truncate_lines_p
14525 && (/* Glyph doesn't fit on the line. */
14526 new_x > it->last_visible_x
14527 /* Or it fits exactly on a window system frame. */
14528 || (new_x == it->last_visible_x
14529 && FRAME_WINDOW_P (it->f))))
14530 {
14531 /* End of a continued line. */
14532
14533 if (it->hpos == 0
14534 || (new_x == it->last_visible_x
14535 && FRAME_WINDOW_P (it->f)))
14536 {
14537 /* Current glyph is the only one on the line or
14538 fits exactly on the line. We must continue
14539 the line because we can't draw the cursor
14540 after the glyph. */
14541 row->continued_p = 1;
14542 it->current_x = new_x;
14543 it->continuation_lines_width += new_x;
14544 ++it->hpos;
14545 if (i == nglyphs - 1)
14546 {
14547 set_iterator_to_next (it, 1);
14548 #ifdef HAVE_WINDOW_SYSTEM
14549 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14550 {
14551 if (!get_next_display_element (it))
14552 {
14553 row->exact_window_width_line_p = 1;
14554 it->continuation_lines_width = 0;
14555 row->continued_p = 0;
14556 row->ends_at_zv_p = 1;
14557 }
14558 else if (ITERATOR_AT_END_OF_LINE_P (it))
14559 {
14560 row->continued_p = 0;
14561 row->exact_window_width_line_p = 1;
14562 }
14563 }
14564 #endif /* HAVE_WINDOW_SYSTEM */
14565 }
14566 }
14567 else if (CHAR_GLYPH_PADDING_P (*glyph)
14568 && !FRAME_WINDOW_P (it->f))
14569 {
14570 /* A padding glyph that doesn't fit on this line.
14571 This means the whole character doesn't fit
14572 on the line. */
14573 row->used[TEXT_AREA] = n_glyphs_before;
14574
14575 /* Fill the rest of the row with continuation
14576 glyphs like in 20.x. */
14577 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14578 < row->glyphs[1 + TEXT_AREA])
14579 produce_special_glyphs (it, IT_CONTINUATION);
14580
14581 row->continued_p = 1;
14582 it->current_x = x_before;
14583 it->continuation_lines_width += x_before;
14584
14585 /* Restore the height to what it was before the
14586 element not fitting on the line. */
14587 it->max_ascent = ascent;
14588 it->max_descent = descent;
14589 it->max_phys_ascent = phys_ascent;
14590 it->max_phys_descent = phys_descent;
14591 }
14592 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14593 {
14594 /* A TAB that extends past the right edge of the
14595 window. This produces a single glyph on
14596 window system frames. We leave the glyph in
14597 this row and let it fill the row, but don't
14598 consume the TAB. */
14599 it->continuation_lines_width += it->last_visible_x;
14600 row->ends_in_middle_of_char_p = 1;
14601 row->continued_p = 1;
14602 glyph->pixel_width = it->last_visible_x - x;
14603 it->starts_in_middle_of_char_p = 1;
14604 }
14605 else
14606 {
14607 /* Something other than a TAB that draws past
14608 the right edge of the window. Restore
14609 positions to values before the element. */
14610 row->used[TEXT_AREA] = n_glyphs_before + i;
14611
14612 /* Display continuation glyphs. */
14613 if (!FRAME_WINDOW_P (it->f))
14614 produce_special_glyphs (it, IT_CONTINUATION);
14615 row->continued_p = 1;
14616
14617 it->continuation_lines_width += x;
14618
14619 if (nglyphs > 1 && i > 0)
14620 {
14621 row->ends_in_middle_of_char_p = 1;
14622 it->starts_in_middle_of_char_p = 1;
14623 }
14624
14625 /* Restore the height to what it was before the
14626 element not fitting on the line. */
14627 it->max_ascent = ascent;
14628 it->max_descent = descent;
14629 it->max_phys_ascent = phys_ascent;
14630 it->max_phys_descent = phys_descent;
14631 }
14632
14633 break;
14634 }
14635 else if (new_x > it->first_visible_x)
14636 {
14637 /* Increment number of glyphs actually displayed. */
14638 ++it->hpos;
14639
14640 if (x < it->first_visible_x)
14641 /* Glyph is partially visible, i.e. row starts at
14642 negative X position. */
14643 row->x = x - it->first_visible_x;
14644 }
14645 else
14646 {
14647 /* Glyph is completely off the left margin of the
14648 window. This should not happen because of the
14649 move_it_in_display_line at the start of this
14650 function, unless the text display area of the
14651 window is empty. */
14652 xassert (it->first_visible_x <= it->last_visible_x);
14653 }
14654 }
14655
14656 row->ascent = max (row->ascent, it->max_ascent);
14657 row->height = max (row->height, it->max_ascent + it->max_descent);
14658 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14659 row->phys_height = max (row->phys_height,
14660 it->max_phys_ascent + it->max_phys_descent);
14661
14662 /* End of this display line if row is continued. */
14663 if (row->continued_p || row->ends_at_zv_p)
14664 break;
14665 }
14666
14667 at_end_of_line:
14668 /* Is this a line end? If yes, we're also done, after making
14669 sure that a non-default face is extended up to the right
14670 margin of the window. */
14671 if (ITERATOR_AT_END_OF_LINE_P (it))
14672 {
14673 int used_before = row->used[TEXT_AREA];
14674
14675 row->ends_in_newline_from_string_p = STRINGP (it->object);
14676
14677 #ifdef HAVE_WINDOW_SYSTEM
14678 /* Add a space at the end of the line that is used to
14679 display the cursor there. */
14680 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14681 append_space (it, 0);
14682 #endif /* HAVE_WINDOW_SYSTEM */
14683
14684 /* Extend the face to the end of the line. */
14685 extend_face_to_end_of_line (it);
14686
14687 /* Make sure we have the position. */
14688 if (used_before == 0)
14689 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14690
14691 /* Consume the line end. This skips over invisible lines. */
14692 set_iterator_to_next (it, 1);
14693 it->continuation_lines_width = 0;
14694 break;
14695 }
14696
14697 /* Proceed with next display element. Note that this skips
14698 over lines invisible because of selective display. */
14699 set_iterator_to_next (it, 1);
14700
14701 /* If we truncate lines, we are done when the last displayed
14702 glyphs reach past the right margin of the window. */
14703 if (it->truncate_lines_p
14704 && (FRAME_WINDOW_P (it->f)
14705 ? (it->current_x >= it->last_visible_x)
14706 : (it->current_x > it->last_visible_x)))
14707 {
14708 /* Maybe add truncation glyphs. */
14709 if (!FRAME_WINDOW_P (it->f))
14710 {
14711 int i, n;
14712
14713 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14714 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14715 break;
14716
14717 for (n = row->used[TEXT_AREA]; i < n; ++i)
14718 {
14719 row->used[TEXT_AREA] = i;
14720 produce_special_glyphs (it, IT_TRUNCATION);
14721 }
14722 }
14723 #ifdef HAVE_WINDOW_SYSTEM
14724 else
14725 {
14726 /* Don't truncate if we can overflow newline into fringe. */
14727 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14728 {
14729 if (!get_next_display_element (it))
14730 {
14731 #ifdef HAVE_WINDOW_SYSTEM
14732 it->continuation_lines_width = 0;
14733 row->ends_at_zv_p = 1;
14734 row->exact_window_width_line_p = 1;
14735 break;
14736 #endif /* HAVE_WINDOW_SYSTEM */
14737 }
14738 if (ITERATOR_AT_END_OF_LINE_P (it))
14739 {
14740 row->exact_window_width_line_p = 1;
14741 goto at_end_of_line;
14742 }
14743 }
14744 }
14745 #endif /* HAVE_WINDOW_SYSTEM */
14746
14747 row->truncated_on_right_p = 1;
14748 it->continuation_lines_width = 0;
14749 reseat_at_next_visible_line_start (it, 0);
14750 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14751 it->hpos = hpos_before;
14752 it->current_x = x_before;
14753 break;
14754 }
14755 }
14756
14757 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14758 at the left window margin. */
14759 if (it->first_visible_x
14760 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14761 {
14762 if (!FRAME_WINDOW_P (it->f))
14763 insert_left_trunc_glyphs (it);
14764 row->truncated_on_left_p = 1;
14765 }
14766
14767 /* If the start of this line is the overlay arrow-position, then
14768 mark this glyph row as the one containing the overlay arrow.
14769 This is clearly a mess with variable size fonts. It would be
14770 better to let it be displayed like cursors under X. */
14771 if (! overlay_arrow_seen
14772 && (overlay_arrow_string
14773 = overlay_arrow_at_row (it->f, row, &overlay_arrow_bitmap),
14774 !NILP (overlay_arrow_string)))
14775 {
14776 /* Overlay arrow in window redisplay is a fringe bitmap. */
14777 if (!FRAME_WINDOW_P (it->f))
14778 {
14779 struct glyph_row *arrow_row
14780 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
14781 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14782 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14783 struct glyph *p = row->glyphs[TEXT_AREA];
14784 struct glyph *p2, *end;
14785
14786 /* Copy the arrow glyphs. */
14787 while (glyph < arrow_end)
14788 *p++ = *glyph++;
14789
14790 /* Throw away padding glyphs. */
14791 p2 = p;
14792 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14793 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14794 ++p2;
14795 if (p2 > p)
14796 {
14797 while (p2 < end)
14798 *p++ = *p2++;
14799 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14800 }
14801 }
14802
14803 overlay_arrow_seen = 1;
14804 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
14805 row->overlay_arrow_p = 1;
14806 }
14807
14808 /* Compute pixel dimensions of this line. */
14809 compute_line_metrics (it);
14810
14811 /* Remember the position at which this line ends. */
14812 row->end = it->current;
14813
14814 /* Save fringe bitmaps in this row. */
14815 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14816 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14817 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14818 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14819
14820 it->left_user_fringe_bitmap = 0;
14821 it->left_user_fringe_face_id = 0;
14822 it->right_user_fringe_bitmap = 0;
14823 it->right_user_fringe_face_id = 0;
14824
14825 /* Maybe set the cursor. */
14826 if (it->w->cursor.vpos < 0
14827 && PT >= MATRIX_ROW_START_CHARPOS (row)
14828 && PT <= MATRIX_ROW_END_CHARPOS (row)
14829 && cursor_row_p (it->w, row))
14830 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14831
14832 /* Highlight trailing whitespace. */
14833 if (!NILP (Vshow_trailing_whitespace))
14834 highlight_trailing_whitespace (it->f, it->glyph_row);
14835
14836 /* Prepare for the next line. This line starts horizontally at (X
14837 HPOS) = (0 0). Vertical positions are incremented. As a
14838 convenience for the caller, IT->glyph_row is set to the next
14839 row to be used. */
14840 it->current_x = it->hpos = 0;
14841 it->current_y += row->height;
14842 ++it->vpos;
14843 ++it->glyph_row;
14844 it->start = it->current;
14845 return row->displays_text_p;
14846 }
14847
14848
14849 \f
14850 /***********************************************************************
14851 Menu Bar
14852 ***********************************************************************/
14853
14854 /* Redisplay the menu bar in the frame for window W.
14855
14856 The menu bar of X frames that don't have X toolkit support is
14857 displayed in a special window W->frame->menu_bar_window.
14858
14859 The menu bar of terminal frames is treated specially as far as
14860 glyph matrices are concerned. Menu bar lines are not part of
14861 windows, so the update is done directly on the frame matrix rows
14862 for the menu bar. */
14863
14864 static void
14865 display_menu_bar (w)
14866 struct window *w;
14867 {
14868 struct frame *f = XFRAME (WINDOW_FRAME (w));
14869 struct it it;
14870 Lisp_Object items;
14871 int i;
14872
14873 /* Don't do all this for graphical frames. */
14874 #ifdef HAVE_NTGUI
14875 if (!NILP (Vwindow_system))
14876 return;
14877 #endif
14878 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14879 if (FRAME_X_P (f))
14880 return;
14881 #endif
14882 #ifdef MAC_OS
14883 if (FRAME_MAC_P (f))
14884 return;
14885 #endif
14886
14887 #ifdef USE_X_TOOLKIT
14888 xassert (!FRAME_WINDOW_P (f));
14889 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14890 it.first_visible_x = 0;
14891 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14892 #else /* not USE_X_TOOLKIT */
14893 if (FRAME_WINDOW_P (f))
14894 {
14895 /* Menu bar lines are displayed in the desired matrix of the
14896 dummy window menu_bar_window. */
14897 struct window *menu_w;
14898 xassert (WINDOWP (f->menu_bar_window));
14899 menu_w = XWINDOW (f->menu_bar_window);
14900 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14901 MENU_FACE_ID);
14902 it.first_visible_x = 0;
14903 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14904 }
14905 else
14906 {
14907 /* This is a TTY frame, i.e. character hpos/vpos are used as
14908 pixel x/y. */
14909 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14910 MENU_FACE_ID);
14911 it.first_visible_x = 0;
14912 it.last_visible_x = FRAME_COLS (f);
14913 }
14914 #endif /* not USE_X_TOOLKIT */
14915
14916 if (! mode_line_inverse_video)
14917 /* Force the menu-bar to be displayed in the default face. */
14918 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14919
14920 /* Clear all rows of the menu bar. */
14921 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14922 {
14923 struct glyph_row *row = it.glyph_row + i;
14924 clear_glyph_row (row);
14925 row->enabled_p = 1;
14926 row->full_width_p = 1;
14927 }
14928
14929 /* Display all items of the menu bar. */
14930 items = FRAME_MENU_BAR_ITEMS (it.f);
14931 for (i = 0; i < XVECTOR (items)->size; i += 4)
14932 {
14933 Lisp_Object string;
14934
14935 /* Stop at nil string. */
14936 string = AREF (items, i + 1);
14937 if (NILP (string))
14938 break;
14939
14940 /* Remember where item was displayed. */
14941 AREF (items, i + 3) = make_number (it.hpos);
14942
14943 /* Display the item, pad with one space. */
14944 if (it.current_x < it.last_visible_x)
14945 display_string (NULL, string, Qnil, 0, 0, &it,
14946 SCHARS (string) + 1, 0, 0, -1);
14947 }
14948
14949 /* Fill out the line with spaces. */
14950 if (it.current_x < it.last_visible_x)
14951 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14952
14953 /* Compute the total height of the lines. */
14954 compute_line_metrics (&it);
14955 }
14956
14957
14958 \f
14959 /***********************************************************************
14960 Mode Line
14961 ***********************************************************************/
14962
14963 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14964 FORCE is non-zero, redisplay mode lines unconditionally.
14965 Otherwise, redisplay only mode lines that are garbaged. Value is
14966 the number of windows whose mode lines were redisplayed. */
14967
14968 static int
14969 redisplay_mode_lines (window, force)
14970 Lisp_Object window;
14971 int force;
14972 {
14973 int nwindows = 0;
14974
14975 while (!NILP (window))
14976 {
14977 struct window *w = XWINDOW (window);
14978
14979 if (WINDOWP (w->hchild))
14980 nwindows += redisplay_mode_lines (w->hchild, force);
14981 else if (WINDOWP (w->vchild))
14982 nwindows += redisplay_mode_lines (w->vchild, force);
14983 else if (force
14984 || FRAME_GARBAGED_P (XFRAME (w->frame))
14985 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14986 {
14987 struct text_pos lpoint;
14988 struct buffer *old = current_buffer;
14989
14990 /* Set the window's buffer for the mode line display. */
14991 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14992 set_buffer_internal_1 (XBUFFER (w->buffer));
14993
14994 /* Point refers normally to the selected window. For any
14995 other window, set up appropriate value. */
14996 if (!EQ (window, selected_window))
14997 {
14998 struct text_pos pt;
14999
15000 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15001 if (CHARPOS (pt) < BEGV)
15002 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15003 else if (CHARPOS (pt) > (ZV - 1))
15004 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15005 else
15006 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15007 }
15008
15009 /* Display mode lines. */
15010 clear_glyph_matrix (w->desired_matrix);
15011 if (display_mode_lines (w))
15012 {
15013 ++nwindows;
15014 w->must_be_updated_p = 1;
15015 }
15016
15017 /* Restore old settings. */
15018 set_buffer_internal_1 (old);
15019 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15020 }
15021
15022 window = w->next;
15023 }
15024
15025 return nwindows;
15026 }
15027
15028
15029 /* Display the mode and/or top line of window W. Value is the number
15030 of mode lines displayed. */
15031
15032 static int
15033 display_mode_lines (w)
15034 struct window *w;
15035 {
15036 Lisp_Object old_selected_window, old_selected_frame;
15037 int n = 0;
15038
15039 old_selected_frame = selected_frame;
15040 selected_frame = w->frame;
15041 old_selected_window = selected_window;
15042 XSETWINDOW (selected_window, w);
15043
15044 /* These will be set while the mode line specs are processed. */
15045 line_number_displayed = 0;
15046 w->column_number_displayed = Qnil;
15047
15048 if (WINDOW_WANTS_MODELINE_P (w))
15049 {
15050 struct window *sel_w = XWINDOW (old_selected_window);
15051
15052 /* Select mode line face based on the real selected window. */
15053 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15054 current_buffer->mode_line_format);
15055 ++n;
15056 }
15057
15058 if (WINDOW_WANTS_HEADER_LINE_P (w))
15059 {
15060 display_mode_line (w, HEADER_LINE_FACE_ID,
15061 current_buffer->header_line_format);
15062 ++n;
15063 }
15064
15065 selected_frame = old_selected_frame;
15066 selected_window = old_selected_window;
15067 return n;
15068 }
15069
15070
15071 /* Display mode or top line of window W. FACE_ID specifies which line
15072 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15073 FORMAT is the mode line format to display. Value is the pixel
15074 height of the mode line displayed. */
15075
15076 static int
15077 display_mode_line (w, face_id, format)
15078 struct window *w;
15079 enum face_id face_id;
15080 Lisp_Object format;
15081 {
15082 struct it it;
15083 struct face *face;
15084
15085 init_iterator (&it, w, -1, -1, NULL, face_id);
15086 prepare_desired_row (it.glyph_row);
15087
15088 it.glyph_row->mode_line_p = 1;
15089
15090 if (! mode_line_inverse_video)
15091 /* Force the mode-line to be displayed in the default face. */
15092 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15093
15094 /* Temporarily make frame's keyboard the current kboard so that
15095 kboard-local variables in the mode_line_format will get the right
15096 values. */
15097 push_frame_kboard (it.f);
15098 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15099 pop_frame_kboard ();
15100
15101 /* Fill up with spaces. */
15102 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15103
15104 compute_line_metrics (&it);
15105 it.glyph_row->full_width_p = 1;
15106 it.glyph_row->continued_p = 0;
15107 it.glyph_row->truncated_on_left_p = 0;
15108 it.glyph_row->truncated_on_right_p = 0;
15109
15110 /* Make a 3D mode-line have a shadow at its right end. */
15111 face = FACE_FROM_ID (it.f, face_id);
15112 extend_face_to_end_of_line (&it);
15113 if (face->box != FACE_NO_BOX)
15114 {
15115 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15116 + it.glyph_row->used[TEXT_AREA] - 1);
15117 last->right_box_line_p = 1;
15118 }
15119
15120 return it.glyph_row->height;
15121 }
15122
15123 /* Alist that caches the results of :propertize.
15124 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15125 Lisp_Object mode_line_proptrans_alist;
15126
15127 /* List of strings making up the mode-line. */
15128 Lisp_Object mode_line_string_list;
15129
15130 /* Base face property when building propertized mode line string. */
15131 static Lisp_Object mode_line_string_face;
15132 static Lisp_Object mode_line_string_face_prop;
15133
15134
15135 /* Contribute ELT to the mode line for window IT->w. How it
15136 translates into text depends on its data type.
15137
15138 IT describes the display environment in which we display, as usual.
15139
15140 DEPTH is the depth in recursion. It is used to prevent
15141 infinite recursion here.
15142
15143 FIELD_WIDTH is the number of characters the display of ELT should
15144 occupy in the mode line, and PRECISION is the maximum number of
15145 characters to display from ELT's representation. See
15146 display_string for details.
15147
15148 Returns the hpos of the end of the text generated by ELT.
15149
15150 PROPS is a property list to add to any string we encounter.
15151
15152 If RISKY is nonzero, remove (disregard) any properties in any string
15153 we encounter, and ignore :eval and :propertize.
15154
15155 If the global variable `frame_title_ptr' is non-NULL, then the output
15156 is passed to `store_frame_title' instead of `display_string'. */
15157
15158 static int
15159 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15160 struct it *it;
15161 int depth;
15162 int field_width, precision;
15163 Lisp_Object elt, props;
15164 int risky;
15165 {
15166 int n = 0, field, prec;
15167 int literal = 0;
15168
15169 tail_recurse:
15170 if (depth > 100)
15171 elt = build_string ("*too-deep*");
15172
15173 depth++;
15174
15175 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15176 {
15177 case Lisp_String:
15178 {
15179 /* A string: output it and check for %-constructs within it. */
15180 unsigned char c;
15181 const unsigned char *this, *lisp_string;
15182
15183 if (!NILP (props) || risky)
15184 {
15185 Lisp_Object oprops, aelt;
15186 oprops = Ftext_properties_at (make_number (0), elt);
15187
15188 if (NILP (Fequal (props, oprops)) || risky)
15189 {
15190 /* If the starting string has properties,
15191 merge the specified ones onto the existing ones. */
15192 if (! NILP (oprops) && !risky)
15193 {
15194 Lisp_Object tem;
15195
15196 oprops = Fcopy_sequence (oprops);
15197 tem = props;
15198 while (CONSP (tem))
15199 {
15200 oprops = Fplist_put (oprops, XCAR (tem),
15201 XCAR (XCDR (tem)));
15202 tem = XCDR (XCDR (tem));
15203 }
15204 props = oprops;
15205 }
15206
15207 aelt = Fassoc (elt, mode_line_proptrans_alist);
15208 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15209 {
15210 mode_line_proptrans_alist
15211 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15212 elt = XCAR (aelt);
15213 }
15214 else
15215 {
15216 Lisp_Object tem;
15217
15218 elt = Fcopy_sequence (elt);
15219 Fset_text_properties (make_number (0), Flength (elt),
15220 props, elt);
15221 /* Add this item to mode_line_proptrans_alist. */
15222 mode_line_proptrans_alist
15223 = Fcons (Fcons (elt, props),
15224 mode_line_proptrans_alist);
15225 /* Truncate mode_line_proptrans_alist
15226 to at most 50 elements. */
15227 tem = Fnthcdr (make_number (50),
15228 mode_line_proptrans_alist);
15229 if (! NILP (tem))
15230 XSETCDR (tem, Qnil);
15231 }
15232 }
15233 }
15234
15235 this = SDATA (elt);
15236 lisp_string = this;
15237
15238 if (literal)
15239 {
15240 prec = precision - n;
15241 if (frame_title_ptr)
15242 n += store_frame_title (SDATA (elt), -1, prec);
15243 else if (!NILP (mode_line_string_list))
15244 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15245 else
15246 n += display_string (NULL, elt, Qnil, 0, 0, it,
15247 0, prec, 0, STRING_MULTIBYTE (elt));
15248
15249 break;
15250 }
15251
15252 while ((precision <= 0 || n < precision)
15253 && *this
15254 && (frame_title_ptr
15255 || !NILP (mode_line_string_list)
15256 || it->current_x < it->last_visible_x))
15257 {
15258 const unsigned char *last = this;
15259
15260 /* Advance to end of string or next format specifier. */
15261 while ((c = *this++) != '\0' && c != '%')
15262 ;
15263
15264 if (this - 1 != last)
15265 {
15266 /* Output to end of string or up to '%'. Field width
15267 is length of string. Don't output more than
15268 PRECISION allows us. */
15269 --this;
15270
15271 prec = chars_in_text (last, this - last);
15272 if (precision > 0 && prec > precision - n)
15273 prec = precision - n;
15274
15275 if (frame_title_ptr)
15276 n += store_frame_title (last, 0, prec);
15277 else if (!NILP (mode_line_string_list))
15278 {
15279 int bytepos = last - lisp_string;
15280 int charpos = string_byte_to_char (elt, bytepos);
15281 n += store_mode_line_string (NULL,
15282 Fsubstring (elt, make_number (charpos),
15283 make_number (charpos + prec)),
15284 0, 0, 0, Qnil);
15285 }
15286 else
15287 {
15288 int bytepos = last - lisp_string;
15289 int charpos = string_byte_to_char (elt, bytepos);
15290 n += display_string (NULL, elt, Qnil, 0, charpos,
15291 it, 0, prec, 0,
15292 STRING_MULTIBYTE (elt));
15293 }
15294 }
15295 else /* c == '%' */
15296 {
15297 const unsigned char *percent_position = this;
15298
15299 /* Get the specified minimum width. Zero means
15300 don't pad. */
15301 field = 0;
15302 while ((c = *this++) >= '0' && c <= '9')
15303 field = field * 10 + c - '0';
15304
15305 /* Don't pad beyond the total padding allowed. */
15306 if (field_width - n > 0 && field > field_width - n)
15307 field = field_width - n;
15308
15309 /* Note that either PRECISION <= 0 or N < PRECISION. */
15310 prec = precision - n;
15311
15312 if (c == 'M')
15313 n += display_mode_element (it, depth, field, prec,
15314 Vglobal_mode_string, props,
15315 risky);
15316 else if (c != 0)
15317 {
15318 int multibyte;
15319 int bytepos, charpos;
15320 unsigned char *spec;
15321
15322 bytepos = percent_position - lisp_string;
15323 charpos = (STRING_MULTIBYTE (elt)
15324 ? string_byte_to_char (elt, bytepos)
15325 : bytepos);
15326
15327 spec
15328 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15329
15330 if (frame_title_ptr)
15331 n += store_frame_title (spec, field, prec);
15332 else if (!NILP (mode_line_string_list))
15333 {
15334 int len = strlen (spec);
15335 Lisp_Object tem = make_string (spec, len);
15336 props = Ftext_properties_at (make_number (charpos), elt);
15337 /* Should only keep face property in props */
15338 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15339 }
15340 else
15341 {
15342 int nglyphs_before, nwritten;
15343
15344 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15345 nwritten = display_string (spec, Qnil, elt,
15346 charpos, 0, it,
15347 field, prec, 0,
15348 multibyte);
15349
15350 /* Assign to the glyphs written above the
15351 string where the `%x' came from, position
15352 of the `%'. */
15353 if (nwritten > 0)
15354 {
15355 struct glyph *glyph
15356 = (it->glyph_row->glyphs[TEXT_AREA]
15357 + nglyphs_before);
15358 int i;
15359
15360 for (i = 0; i < nwritten; ++i)
15361 {
15362 glyph[i].object = elt;
15363 glyph[i].charpos = charpos;
15364 }
15365
15366 n += nwritten;
15367 }
15368 }
15369 }
15370 else /* c == 0 */
15371 break;
15372 }
15373 }
15374 }
15375 break;
15376
15377 case Lisp_Symbol:
15378 /* A symbol: process the value of the symbol recursively
15379 as if it appeared here directly. Avoid error if symbol void.
15380 Special case: if value of symbol is a string, output the string
15381 literally. */
15382 {
15383 register Lisp_Object tem;
15384
15385 /* If the variable is not marked as risky to set
15386 then its contents are risky to use. */
15387 if (NILP (Fget (elt, Qrisky_local_variable)))
15388 risky = 1;
15389
15390 tem = Fboundp (elt);
15391 if (!NILP (tem))
15392 {
15393 tem = Fsymbol_value (elt);
15394 /* If value is a string, output that string literally:
15395 don't check for % within it. */
15396 if (STRINGP (tem))
15397 literal = 1;
15398
15399 if (!EQ (tem, elt))
15400 {
15401 /* Give up right away for nil or t. */
15402 elt = tem;
15403 goto tail_recurse;
15404 }
15405 }
15406 }
15407 break;
15408
15409 case Lisp_Cons:
15410 {
15411 register Lisp_Object car, tem;
15412
15413 /* A cons cell: five distinct cases.
15414 If first element is :eval or :propertize, do something special.
15415 If first element is a string or a cons, process all the elements
15416 and effectively concatenate them.
15417 If first element is a negative number, truncate displaying cdr to
15418 at most that many characters. If positive, pad (with spaces)
15419 to at least that many characters.
15420 If first element is a symbol, process the cadr or caddr recursively
15421 according to whether the symbol's value is non-nil or nil. */
15422 car = XCAR (elt);
15423 if (EQ (car, QCeval))
15424 {
15425 /* An element of the form (:eval FORM) means evaluate FORM
15426 and use the result as mode line elements. */
15427
15428 if (risky)
15429 break;
15430
15431 if (CONSP (XCDR (elt)))
15432 {
15433 Lisp_Object spec;
15434 spec = safe_eval (XCAR (XCDR (elt)));
15435 n += display_mode_element (it, depth, field_width - n,
15436 precision - n, spec, props,
15437 risky);
15438 }
15439 }
15440 else if (EQ (car, QCpropertize))
15441 {
15442 /* An element of the form (:propertize ELT PROPS...)
15443 means display ELT but applying properties PROPS. */
15444
15445 if (risky)
15446 break;
15447
15448 if (CONSP (XCDR (elt)))
15449 n += display_mode_element (it, depth, field_width - n,
15450 precision - n, XCAR (XCDR (elt)),
15451 XCDR (XCDR (elt)), risky);
15452 }
15453 else if (SYMBOLP (car))
15454 {
15455 tem = Fboundp (car);
15456 elt = XCDR (elt);
15457 if (!CONSP (elt))
15458 goto invalid;
15459 /* elt is now the cdr, and we know it is a cons cell.
15460 Use its car if CAR has a non-nil value. */
15461 if (!NILP (tem))
15462 {
15463 tem = Fsymbol_value (car);
15464 if (!NILP (tem))
15465 {
15466 elt = XCAR (elt);
15467 goto tail_recurse;
15468 }
15469 }
15470 /* Symbol's value is nil (or symbol is unbound)
15471 Get the cddr of the original list
15472 and if possible find the caddr and use that. */
15473 elt = XCDR (elt);
15474 if (NILP (elt))
15475 break;
15476 else if (!CONSP (elt))
15477 goto invalid;
15478 elt = XCAR (elt);
15479 goto tail_recurse;
15480 }
15481 else if (INTEGERP (car))
15482 {
15483 register int lim = XINT (car);
15484 elt = XCDR (elt);
15485 if (lim < 0)
15486 {
15487 /* Negative int means reduce maximum width. */
15488 if (precision <= 0)
15489 precision = -lim;
15490 else
15491 precision = min (precision, -lim);
15492 }
15493 else if (lim > 0)
15494 {
15495 /* Padding specified. Don't let it be more than
15496 current maximum. */
15497 if (precision > 0)
15498 lim = min (precision, lim);
15499
15500 /* If that's more padding than already wanted, queue it.
15501 But don't reduce padding already specified even if
15502 that is beyond the current truncation point. */
15503 field_width = max (lim, field_width);
15504 }
15505 goto tail_recurse;
15506 }
15507 else if (STRINGP (car) || CONSP (car))
15508 {
15509 register int limit = 50;
15510 /* Limit is to protect against circular lists. */
15511 while (CONSP (elt)
15512 && --limit > 0
15513 && (precision <= 0 || n < precision))
15514 {
15515 n += display_mode_element (it, depth, field_width - n,
15516 precision - n, XCAR (elt),
15517 props, risky);
15518 elt = XCDR (elt);
15519 }
15520 }
15521 }
15522 break;
15523
15524 default:
15525 invalid:
15526 elt = build_string ("*invalid*");
15527 goto tail_recurse;
15528 }
15529
15530 /* Pad to FIELD_WIDTH. */
15531 if (field_width > 0 && n < field_width)
15532 {
15533 if (frame_title_ptr)
15534 n += store_frame_title ("", field_width - n, 0);
15535 else if (!NILP (mode_line_string_list))
15536 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15537 else
15538 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15539 0, 0, 0);
15540 }
15541
15542 return n;
15543 }
15544
15545 /* Store a mode-line string element in mode_line_string_list.
15546
15547 If STRING is non-null, display that C string. Otherwise, the Lisp
15548 string LISP_STRING is displayed.
15549
15550 FIELD_WIDTH is the minimum number of output glyphs to produce.
15551 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15552 with spaces. FIELD_WIDTH <= 0 means don't pad.
15553
15554 PRECISION is the maximum number of characters to output from
15555 STRING. PRECISION <= 0 means don't truncate the string.
15556
15557 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15558 properties to the string.
15559
15560 PROPS are the properties to add to the string.
15561 The mode_line_string_face face property is always added to the string.
15562 */
15563
15564 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15565 char *string;
15566 Lisp_Object lisp_string;
15567 int copy_string;
15568 int field_width;
15569 int precision;
15570 Lisp_Object props;
15571 {
15572 int len;
15573 int n = 0;
15574
15575 if (string != NULL)
15576 {
15577 len = strlen (string);
15578 if (precision > 0 && len > precision)
15579 len = precision;
15580 lisp_string = make_string (string, len);
15581 if (NILP (props))
15582 props = mode_line_string_face_prop;
15583 else if (!NILP (mode_line_string_face))
15584 {
15585 Lisp_Object face = Fplist_get (props, Qface);
15586 props = Fcopy_sequence (props);
15587 if (NILP (face))
15588 face = mode_line_string_face;
15589 else
15590 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15591 props = Fplist_put (props, Qface, face);
15592 }
15593 Fadd_text_properties (make_number (0), make_number (len),
15594 props, lisp_string);
15595 }
15596 else
15597 {
15598 len = XFASTINT (Flength (lisp_string));
15599 if (precision > 0 && len > precision)
15600 {
15601 len = precision;
15602 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15603 precision = -1;
15604 }
15605 if (!NILP (mode_line_string_face))
15606 {
15607 Lisp_Object face;
15608 if (NILP (props))
15609 props = Ftext_properties_at (make_number (0), lisp_string);
15610 face = Fplist_get (props, Qface);
15611 if (NILP (face))
15612 face = mode_line_string_face;
15613 else
15614 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15615 props = Fcons (Qface, Fcons (face, Qnil));
15616 if (copy_string)
15617 lisp_string = Fcopy_sequence (lisp_string);
15618 }
15619 if (!NILP (props))
15620 Fadd_text_properties (make_number (0), make_number (len),
15621 props, lisp_string);
15622 }
15623
15624 if (len > 0)
15625 {
15626 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15627 n += len;
15628 }
15629
15630 if (field_width > len)
15631 {
15632 field_width -= len;
15633 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15634 if (!NILP (props))
15635 Fadd_text_properties (make_number (0), make_number (field_width),
15636 props, lisp_string);
15637 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15638 n += field_width;
15639 }
15640
15641 return n;
15642 }
15643
15644
15645 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15646 0, 3, 0,
15647 doc: /* Return the mode-line of selected window as a string.
15648 First optional arg FORMAT specifies a different format string (see
15649 `mode-line-format' for details) to use. If FORMAT is t, return
15650 the buffer's header-line. Second optional arg WINDOW specifies a
15651 different window to use as the context for the formatting.
15652 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15653 (format, window, no_props)
15654 Lisp_Object format, window, no_props;
15655 {
15656 struct it it;
15657 int len;
15658 struct window *w;
15659 struct buffer *old_buffer = NULL;
15660 enum face_id face_id = DEFAULT_FACE_ID;
15661
15662 if (NILP (window))
15663 window = selected_window;
15664 CHECK_WINDOW (window);
15665 w = XWINDOW (window);
15666 CHECK_BUFFER (w->buffer);
15667
15668 if (XBUFFER (w->buffer) != current_buffer)
15669 {
15670 old_buffer = current_buffer;
15671 set_buffer_internal_1 (XBUFFER (w->buffer));
15672 }
15673
15674 if (NILP (format) || EQ (format, Qt))
15675 {
15676 face_id = NILP (format)
15677 ? CURRENT_MODE_LINE_FACE_ID (w) :
15678 HEADER_LINE_FACE_ID;
15679 format = NILP (format)
15680 ? current_buffer->mode_line_format
15681 : current_buffer->header_line_format;
15682 }
15683
15684 init_iterator (&it, w, -1, -1, NULL, face_id);
15685
15686 if (NILP (no_props))
15687 {
15688 mode_line_string_face =
15689 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15690 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15691 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15692
15693 mode_line_string_face_prop =
15694 NILP (mode_line_string_face) ? Qnil :
15695 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15696
15697 /* We need a dummy last element in mode_line_string_list to
15698 indicate we are building the propertized mode-line string.
15699 Using mode_line_string_face_prop here GC protects it. */
15700 mode_line_string_list =
15701 Fcons (mode_line_string_face_prop, Qnil);
15702 frame_title_ptr = NULL;
15703 }
15704 else
15705 {
15706 mode_line_string_face_prop = Qnil;
15707 mode_line_string_list = Qnil;
15708 frame_title_ptr = frame_title_buf;
15709 }
15710
15711 push_frame_kboard (it.f);
15712 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15713 pop_frame_kboard ();
15714
15715 if (old_buffer)
15716 set_buffer_internal_1 (old_buffer);
15717
15718 if (NILP (no_props))
15719 {
15720 Lisp_Object str;
15721 mode_line_string_list = Fnreverse (mode_line_string_list);
15722 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15723 make_string ("", 0));
15724 mode_line_string_face_prop = Qnil;
15725 mode_line_string_list = Qnil;
15726 return str;
15727 }
15728
15729 len = frame_title_ptr - frame_title_buf;
15730 if (len > 0 && frame_title_ptr[-1] == '-')
15731 {
15732 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15733 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15734 ;
15735 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15736 if (len > frame_title_ptr - frame_title_buf)
15737 len = frame_title_ptr - frame_title_buf;
15738 }
15739
15740 frame_title_ptr = NULL;
15741 return make_string (frame_title_buf, len);
15742 }
15743
15744 /* Write a null-terminated, right justified decimal representation of
15745 the positive integer D to BUF using a minimal field width WIDTH. */
15746
15747 static void
15748 pint2str (buf, width, d)
15749 register char *buf;
15750 register int width;
15751 register int d;
15752 {
15753 register char *p = buf;
15754
15755 if (d <= 0)
15756 *p++ = '0';
15757 else
15758 {
15759 while (d > 0)
15760 {
15761 *p++ = d % 10 + '0';
15762 d /= 10;
15763 }
15764 }
15765
15766 for (width -= (int) (p - buf); width > 0; --width)
15767 *p++ = ' ';
15768 *p-- = '\0';
15769 while (p > buf)
15770 {
15771 d = *buf;
15772 *buf++ = *p;
15773 *p-- = d;
15774 }
15775 }
15776
15777 /* Write a null-terminated, right justified decimal and "human
15778 readable" representation of the nonnegative integer D to BUF using
15779 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15780
15781 static const char power_letter[] =
15782 {
15783 0, /* not used */
15784 'k', /* kilo */
15785 'M', /* mega */
15786 'G', /* giga */
15787 'T', /* tera */
15788 'P', /* peta */
15789 'E', /* exa */
15790 'Z', /* zetta */
15791 'Y' /* yotta */
15792 };
15793
15794 static void
15795 pint2hrstr (buf, width, d)
15796 char *buf;
15797 int width;
15798 int d;
15799 {
15800 /* We aim to represent the nonnegative integer D as
15801 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15802 int quotient = d;
15803 int remainder = 0;
15804 /* -1 means: do not use TENTHS. */
15805 int tenths = -1;
15806 int exponent = 0;
15807
15808 /* Length of QUOTIENT.TENTHS as a string. */
15809 int length;
15810
15811 char * psuffix;
15812 char * p;
15813
15814 if (1000 <= quotient)
15815 {
15816 /* Scale to the appropriate EXPONENT. */
15817 do
15818 {
15819 remainder = quotient % 1000;
15820 quotient /= 1000;
15821 exponent++;
15822 }
15823 while (1000 <= quotient);
15824
15825 /* Round to nearest and decide whether to use TENTHS or not. */
15826 if (quotient <= 9)
15827 {
15828 tenths = remainder / 100;
15829 if (50 <= remainder % 100)
15830 if (tenths < 9)
15831 tenths++;
15832 else
15833 {
15834 quotient++;
15835 if (quotient == 10)
15836 tenths = -1;
15837 else
15838 tenths = 0;
15839 }
15840 }
15841 else
15842 if (500 <= remainder)
15843 if (quotient < 999)
15844 quotient++;
15845 else
15846 {
15847 quotient = 1;
15848 exponent++;
15849 tenths = 0;
15850 }
15851 }
15852
15853 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15854 if (tenths == -1 && quotient <= 99)
15855 if (quotient <= 9)
15856 length = 1;
15857 else
15858 length = 2;
15859 else
15860 length = 3;
15861 p = psuffix = buf + max (width, length);
15862
15863 /* Print EXPONENT. */
15864 if (exponent)
15865 *psuffix++ = power_letter[exponent];
15866 *psuffix = '\0';
15867
15868 /* Print TENTHS. */
15869 if (tenths >= 0)
15870 {
15871 *--p = '0' + tenths;
15872 *--p = '.';
15873 }
15874
15875 /* Print QUOTIENT. */
15876 do
15877 {
15878 int digit = quotient % 10;
15879 *--p = '0' + digit;
15880 }
15881 while ((quotient /= 10) != 0);
15882
15883 /* Print leading spaces. */
15884 while (buf < p)
15885 *--p = ' ';
15886 }
15887
15888 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15889 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15890 type of CODING_SYSTEM. Return updated pointer into BUF. */
15891
15892 static unsigned char invalid_eol_type[] = "(*invalid*)";
15893
15894 static char *
15895 decode_mode_spec_coding (coding_system, buf, eol_flag)
15896 Lisp_Object coding_system;
15897 register char *buf;
15898 int eol_flag;
15899 {
15900 Lisp_Object val;
15901 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15902 const unsigned char *eol_str;
15903 int eol_str_len;
15904 /* The EOL conversion we are using. */
15905 Lisp_Object eoltype;
15906
15907 val = Fget (coding_system, Qcoding_system);
15908 eoltype = Qnil;
15909
15910 if (!VECTORP (val)) /* Not yet decided. */
15911 {
15912 if (multibyte)
15913 *buf++ = '-';
15914 if (eol_flag)
15915 eoltype = eol_mnemonic_undecided;
15916 /* Don't mention EOL conversion if it isn't decided. */
15917 }
15918 else
15919 {
15920 Lisp_Object eolvalue;
15921
15922 eolvalue = Fget (coding_system, Qeol_type);
15923
15924 if (multibyte)
15925 *buf++ = XFASTINT (AREF (val, 1));
15926
15927 if (eol_flag)
15928 {
15929 /* The EOL conversion that is normal on this system. */
15930
15931 if (NILP (eolvalue)) /* Not yet decided. */
15932 eoltype = eol_mnemonic_undecided;
15933 else if (VECTORP (eolvalue)) /* Not yet decided. */
15934 eoltype = eol_mnemonic_undecided;
15935 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15936 eoltype = (XFASTINT (eolvalue) == 0
15937 ? eol_mnemonic_unix
15938 : (XFASTINT (eolvalue) == 1
15939 ? eol_mnemonic_dos : eol_mnemonic_mac));
15940 }
15941 }
15942
15943 if (eol_flag)
15944 {
15945 /* Mention the EOL conversion if it is not the usual one. */
15946 if (STRINGP (eoltype))
15947 {
15948 eol_str = SDATA (eoltype);
15949 eol_str_len = SBYTES (eoltype);
15950 }
15951 else if (INTEGERP (eoltype)
15952 && CHAR_VALID_P (XINT (eoltype), 0))
15953 {
15954 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15955 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15956 eol_str = tmp;
15957 }
15958 else
15959 {
15960 eol_str = invalid_eol_type;
15961 eol_str_len = sizeof (invalid_eol_type) - 1;
15962 }
15963 bcopy (eol_str, buf, eol_str_len);
15964 buf += eol_str_len;
15965 }
15966
15967 return buf;
15968 }
15969
15970 /* Return a string for the output of a mode line %-spec for window W,
15971 generated by character C. PRECISION >= 0 means don't return a
15972 string longer than that value. FIELD_WIDTH > 0 means pad the
15973 string returned with spaces to that value. Return 1 in *MULTIBYTE
15974 if the result is multibyte text. */
15975
15976 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15977
15978 static char *
15979 decode_mode_spec (w, c, field_width, precision, multibyte)
15980 struct window *w;
15981 register int c;
15982 int field_width, precision;
15983 int *multibyte;
15984 {
15985 Lisp_Object obj;
15986 struct frame *f = XFRAME (WINDOW_FRAME (w));
15987 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15988 struct buffer *b = XBUFFER (w->buffer);
15989
15990 obj = Qnil;
15991 *multibyte = 0;
15992
15993 switch (c)
15994 {
15995 case '*':
15996 if (!NILP (b->read_only))
15997 return "%";
15998 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15999 return "*";
16000 return "-";
16001
16002 case '+':
16003 /* This differs from %* only for a modified read-only buffer. */
16004 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16005 return "*";
16006 if (!NILP (b->read_only))
16007 return "%";
16008 return "-";
16009
16010 case '&':
16011 /* This differs from %* in ignoring read-only-ness. */
16012 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16013 return "*";
16014 return "-";
16015
16016 case '%':
16017 return "%";
16018
16019 case '[':
16020 {
16021 int i;
16022 char *p;
16023
16024 if (command_loop_level > 5)
16025 return "[[[... ";
16026 p = decode_mode_spec_buf;
16027 for (i = 0; i < command_loop_level; i++)
16028 *p++ = '[';
16029 *p = 0;
16030 return decode_mode_spec_buf;
16031 }
16032
16033 case ']':
16034 {
16035 int i;
16036 char *p;
16037
16038 if (command_loop_level > 5)
16039 return " ...]]]";
16040 p = decode_mode_spec_buf;
16041 for (i = 0; i < command_loop_level; i++)
16042 *p++ = ']';
16043 *p = 0;
16044 return decode_mode_spec_buf;
16045 }
16046
16047 case '-':
16048 {
16049 register int i;
16050
16051 /* Let lots_of_dashes be a string of infinite length. */
16052 if (!NILP (mode_line_string_list))
16053 return "--";
16054 if (field_width <= 0
16055 || field_width > sizeof (lots_of_dashes))
16056 {
16057 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16058 decode_mode_spec_buf[i] = '-';
16059 decode_mode_spec_buf[i] = '\0';
16060 return decode_mode_spec_buf;
16061 }
16062 else
16063 return lots_of_dashes;
16064 }
16065
16066 case 'b':
16067 obj = b->name;
16068 break;
16069
16070 case 'c':
16071 {
16072 int col = (int) current_column (); /* iftc */
16073 w->column_number_displayed = make_number (col);
16074 pint2str (decode_mode_spec_buf, field_width, col);
16075 return decode_mode_spec_buf;
16076 }
16077
16078 case 'F':
16079 /* %F displays the frame name. */
16080 if (!NILP (f->title))
16081 return (char *) SDATA (f->title);
16082 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16083 return (char *) SDATA (f->name);
16084 return "Emacs";
16085
16086 case 'f':
16087 obj = b->filename;
16088 break;
16089
16090 case 'i':
16091 {
16092 int size = ZV - BEGV;
16093 pint2str (decode_mode_spec_buf, field_width, size);
16094 return decode_mode_spec_buf;
16095 }
16096
16097 case 'I':
16098 {
16099 int size = ZV - BEGV;
16100 pint2hrstr (decode_mode_spec_buf, field_width, size);
16101 return decode_mode_spec_buf;
16102 }
16103
16104 case 'l':
16105 {
16106 int startpos = XMARKER (w->start)->charpos;
16107 int startpos_byte = marker_byte_position (w->start);
16108 int line, linepos, linepos_byte, topline;
16109 int nlines, junk;
16110 int height = WINDOW_TOTAL_LINES (w);
16111
16112 /* If we decided that this buffer isn't suitable for line numbers,
16113 don't forget that too fast. */
16114 if (EQ (w->base_line_pos, w->buffer))
16115 goto no_value;
16116 /* But do forget it, if the window shows a different buffer now. */
16117 else if (BUFFERP (w->base_line_pos))
16118 w->base_line_pos = Qnil;
16119
16120 /* If the buffer is very big, don't waste time. */
16121 if (INTEGERP (Vline_number_display_limit)
16122 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16123 {
16124 w->base_line_pos = Qnil;
16125 w->base_line_number = Qnil;
16126 goto no_value;
16127 }
16128
16129 if (!NILP (w->base_line_number)
16130 && !NILP (w->base_line_pos)
16131 && XFASTINT (w->base_line_pos) <= startpos)
16132 {
16133 line = XFASTINT (w->base_line_number);
16134 linepos = XFASTINT (w->base_line_pos);
16135 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16136 }
16137 else
16138 {
16139 line = 1;
16140 linepos = BUF_BEGV (b);
16141 linepos_byte = BUF_BEGV_BYTE (b);
16142 }
16143
16144 /* Count lines from base line to window start position. */
16145 nlines = display_count_lines (linepos, linepos_byte,
16146 startpos_byte,
16147 startpos, &junk);
16148
16149 topline = nlines + line;
16150
16151 /* Determine a new base line, if the old one is too close
16152 or too far away, or if we did not have one.
16153 "Too close" means it's plausible a scroll-down would
16154 go back past it. */
16155 if (startpos == BUF_BEGV (b))
16156 {
16157 w->base_line_number = make_number (topline);
16158 w->base_line_pos = make_number (BUF_BEGV (b));
16159 }
16160 else if (nlines < height + 25 || nlines > height * 3 + 50
16161 || linepos == BUF_BEGV (b))
16162 {
16163 int limit = BUF_BEGV (b);
16164 int limit_byte = BUF_BEGV_BYTE (b);
16165 int position;
16166 int distance = (height * 2 + 30) * line_number_display_limit_width;
16167
16168 if (startpos - distance > limit)
16169 {
16170 limit = startpos - distance;
16171 limit_byte = CHAR_TO_BYTE (limit);
16172 }
16173
16174 nlines = display_count_lines (startpos, startpos_byte,
16175 limit_byte,
16176 - (height * 2 + 30),
16177 &position);
16178 /* If we couldn't find the lines we wanted within
16179 line_number_display_limit_width chars per line,
16180 give up on line numbers for this window. */
16181 if (position == limit_byte && limit == startpos - distance)
16182 {
16183 w->base_line_pos = w->buffer;
16184 w->base_line_number = Qnil;
16185 goto no_value;
16186 }
16187
16188 w->base_line_number = make_number (topline - nlines);
16189 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16190 }
16191
16192 /* Now count lines from the start pos to point. */
16193 nlines = display_count_lines (startpos, startpos_byte,
16194 PT_BYTE, PT, &junk);
16195
16196 /* Record that we did display the line number. */
16197 line_number_displayed = 1;
16198
16199 /* Make the string to show. */
16200 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16201 return decode_mode_spec_buf;
16202 no_value:
16203 {
16204 char* p = decode_mode_spec_buf;
16205 int pad = field_width - 2;
16206 while (pad-- > 0)
16207 *p++ = ' ';
16208 *p++ = '?';
16209 *p++ = '?';
16210 *p = '\0';
16211 return decode_mode_spec_buf;
16212 }
16213 }
16214 break;
16215
16216 case 'm':
16217 obj = b->mode_name;
16218 break;
16219
16220 case 'n':
16221 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16222 return " Narrow";
16223 break;
16224
16225 case 'p':
16226 {
16227 int pos = marker_position (w->start);
16228 int total = BUF_ZV (b) - BUF_BEGV (b);
16229
16230 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16231 {
16232 if (pos <= BUF_BEGV (b))
16233 return "All";
16234 else
16235 return "Bottom";
16236 }
16237 else if (pos <= BUF_BEGV (b))
16238 return "Top";
16239 else
16240 {
16241 if (total > 1000000)
16242 /* Do it differently for a large value, to avoid overflow. */
16243 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16244 else
16245 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16246 /* We can't normally display a 3-digit number,
16247 so get us a 2-digit number that is close. */
16248 if (total == 100)
16249 total = 99;
16250 sprintf (decode_mode_spec_buf, "%2d%%", total);
16251 return decode_mode_spec_buf;
16252 }
16253 }
16254
16255 /* Display percentage of size above the bottom of the screen. */
16256 case 'P':
16257 {
16258 int toppos = marker_position (w->start);
16259 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16260 int total = BUF_ZV (b) - BUF_BEGV (b);
16261
16262 if (botpos >= BUF_ZV (b))
16263 {
16264 if (toppos <= BUF_BEGV (b))
16265 return "All";
16266 else
16267 return "Bottom";
16268 }
16269 else
16270 {
16271 if (total > 1000000)
16272 /* Do it differently for a large value, to avoid overflow. */
16273 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16274 else
16275 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16276 /* We can't normally display a 3-digit number,
16277 so get us a 2-digit number that is close. */
16278 if (total == 100)
16279 total = 99;
16280 if (toppos <= BUF_BEGV (b))
16281 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16282 else
16283 sprintf (decode_mode_spec_buf, "%2d%%", total);
16284 return decode_mode_spec_buf;
16285 }
16286 }
16287
16288 case 's':
16289 /* status of process */
16290 obj = Fget_buffer_process (w->buffer);
16291 if (NILP (obj))
16292 return "no process";
16293 #ifdef subprocesses
16294 obj = Fsymbol_name (Fprocess_status (obj));
16295 #endif
16296 break;
16297
16298 case 't': /* indicate TEXT or BINARY */
16299 #ifdef MODE_LINE_BINARY_TEXT
16300 return MODE_LINE_BINARY_TEXT (b);
16301 #else
16302 return "T";
16303 #endif
16304
16305 case 'z':
16306 /* coding-system (not including end-of-line format) */
16307 case 'Z':
16308 /* coding-system (including end-of-line type) */
16309 {
16310 int eol_flag = (c == 'Z');
16311 char *p = decode_mode_spec_buf;
16312
16313 if (! FRAME_WINDOW_P (f))
16314 {
16315 /* No need to mention EOL here--the terminal never needs
16316 to do EOL conversion. */
16317 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16318 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16319 }
16320 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16321 p, eol_flag);
16322
16323 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16324 #ifdef subprocesses
16325 obj = Fget_buffer_process (Fcurrent_buffer ());
16326 if (PROCESSP (obj))
16327 {
16328 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16329 p, eol_flag);
16330 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16331 p, eol_flag);
16332 }
16333 #endif /* subprocesses */
16334 #endif /* 0 */
16335 *p = 0;
16336 return decode_mode_spec_buf;
16337 }
16338 }
16339
16340 if (STRINGP (obj))
16341 {
16342 *multibyte = STRING_MULTIBYTE (obj);
16343 return (char *) SDATA (obj);
16344 }
16345 else
16346 return "";
16347 }
16348
16349
16350 /* Count up to COUNT lines starting from START / START_BYTE.
16351 But don't go beyond LIMIT_BYTE.
16352 Return the number of lines thus found (always nonnegative).
16353
16354 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16355
16356 static int
16357 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16358 int start, start_byte, limit_byte, count;
16359 int *byte_pos_ptr;
16360 {
16361 register unsigned char *cursor;
16362 unsigned char *base;
16363
16364 register int ceiling;
16365 register unsigned char *ceiling_addr;
16366 int orig_count = count;
16367
16368 /* If we are not in selective display mode,
16369 check only for newlines. */
16370 int selective_display = (!NILP (current_buffer->selective_display)
16371 && !INTEGERP (current_buffer->selective_display));
16372
16373 if (count > 0)
16374 {
16375 while (start_byte < limit_byte)
16376 {
16377 ceiling = BUFFER_CEILING_OF (start_byte);
16378 ceiling = min (limit_byte - 1, ceiling);
16379 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16380 base = (cursor = BYTE_POS_ADDR (start_byte));
16381 while (1)
16382 {
16383 if (selective_display)
16384 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16385 ;
16386 else
16387 while (*cursor != '\n' && ++cursor != ceiling_addr)
16388 ;
16389
16390 if (cursor != ceiling_addr)
16391 {
16392 if (--count == 0)
16393 {
16394 start_byte += cursor - base + 1;
16395 *byte_pos_ptr = start_byte;
16396 return orig_count;
16397 }
16398 else
16399 if (++cursor == ceiling_addr)
16400 break;
16401 }
16402 else
16403 break;
16404 }
16405 start_byte += cursor - base;
16406 }
16407 }
16408 else
16409 {
16410 while (start_byte > limit_byte)
16411 {
16412 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16413 ceiling = max (limit_byte, ceiling);
16414 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16415 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16416 while (1)
16417 {
16418 if (selective_display)
16419 while (--cursor != ceiling_addr
16420 && *cursor != '\n' && *cursor != 015)
16421 ;
16422 else
16423 while (--cursor != ceiling_addr && *cursor != '\n')
16424 ;
16425
16426 if (cursor != ceiling_addr)
16427 {
16428 if (++count == 0)
16429 {
16430 start_byte += cursor - base + 1;
16431 *byte_pos_ptr = start_byte;
16432 /* When scanning backwards, we should
16433 not count the newline posterior to which we stop. */
16434 return - orig_count - 1;
16435 }
16436 }
16437 else
16438 break;
16439 }
16440 /* Here we add 1 to compensate for the last decrement
16441 of CURSOR, which took it past the valid range. */
16442 start_byte += cursor - base + 1;
16443 }
16444 }
16445
16446 *byte_pos_ptr = limit_byte;
16447
16448 if (count < 0)
16449 return - orig_count + count;
16450 return orig_count - count;
16451
16452 }
16453
16454
16455 \f
16456 /***********************************************************************
16457 Displaying strings
16458 ***********************************************************************/
16459
16460 /* Display a NUL-terminated string, starting with index START.
16461
16462 If STRING is non-null, display that C string. Otherwise, the Lisp
16463 string LISP_STRING is displayed.
16464
16465 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16466 FACE_STRING. Display STRING or LISP_STRING with the face at
16467 FACE_STRING_POS in FACE_STRING:
16468
16469 Display the string in the environment given by IT, but use the
16470 standard display table, temporarily.
16471
16472 FIELD_WIDTH is the minimum number of output glyphs to produce.
16473 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16474 with spaces. If STRING has more characters, more than FIELD_WIDTH
16475 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16476
16477 PRECISION is the maximum number of characters to output from
16478 STRING. PRECISION < 0 means don't truncate the string.
16479
16480 This is roughly equivalent to printf format specifiers:
16481
16482 FIELD_WIDTH PRECISION PRINTF
16483 ----------------------------------------
16484 -1 -1 %s
16485 -1 10 %.10s
16486 10 -1 %10s
16487 20 10 %20.10s
16488
16489 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16490 display them, and < 0 means obey the current buffer's value of
16491 enable_multibyte_characters.
16492
16493 Value is the number of glyphs produced. */
16494
16495 static int
16496 display_string (string, lisp_string, face_string, face_string_pos,
16497 start, it, field_width, precision, max_x, multibyte)
16498 unsigned char *string;
16499 Lisp_Object lisp_string;
16500 Lisp_Object face_string;
16501 int face_string_pos;
16502 int start;
16503 struct it *it;
16504 int field_width, precision, max_x;
16505 int multibyte;
16506 {
16507 int hpos_at_start = it->hpos;
16508 int saved_face_id = it->face_id;
16509 struct glyph_row *row = it->glyph_row;
16510
16511 /* Initialize the iterator IT for iteration over STRING beginning
16512 with index START. */
16513 reseat_to_string (it, string, lisp_string, start,
16514 precision, field_width, multibyte);
16515
16516 /* If displaying STRING, set up the face of the iterator
16517 from LISP_STRING, if that's given. */
16518 if (STRINGP (face_string))
16519 {
16520 int endptr;
16521 struct face *face;
16522
16523 it->face_id
16524 = face_at_string_position (it->w, face_string, face_string_pos,
16525 0, it->region_beg_charpos,
16526 it->region_end_charpos,
16527 &endptr, it->base_face_id, 0);
16528 face = FACE_FROM_ID (it->f, it->face_id);
16529 it->face_box_p = face->box != FACE_NO_BOX;
16530 }
16531
16532 /* Set max_x to the maximum allowed X position. Don't let it go
16533 beyond the right edge of the window. */
16534 if (max_x <= 0)
16535 max_x = it->last_visible_x;
16536 else
16537 max_x = min (max_x, it->last_visible_x);
16538
16539 /* Skip over display elements that are not visible. because IT->w is
16540 hscrolled. */
16541 if (it->current_x < it->first_visible_x)
16542 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16543 MOVE_TO_POS | MOVE_TO_X);
16544
16545 row->ascent = it->max_ascent;
16546 row->height = it->max_ascent + it->max_descent;
16547 row->phys_ascent = it->max_phys_ascent;
16548 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16549
16550 /* This condition is for the case that we are called with current_x
16551 past last_visible_x. */
16552 while (it->current_x < max_x)
16553 {
16554 int x_before, x, n_glyphs_before, i, nglyphs;
16555
16556 /* Get the next display element. */
16557 if (!get_next_display_element (it))
16558 break;
16559
16560 /* Produce glyphs. */
16561 x_before = it->current_x;
16562 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16563 PRODUCE_GLYPHS (it);
16564
16565 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16566 i = 0;
16567 x = x_before;
16568 while (i < nglyphs)
16569 {
16570 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16571
16572 if (!it->truncate_lines_p
16573 && x + glyph->pixel_width > max_x)
16574 {
16575 /* End of continued line or max_x reached. */
16576 if (CHAR_GLYPH_PADDING_P (*glyph))
16577 {
16578 /* A wide character is unbreakable. */
16579 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16580 it->current_x = x_before;
16581 }
16582 else
16583 {
16584 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16585 it->current_x = x;
16586 }
16587 break;
16588 }
16589 else if (x + glyph->pixel_width > it->first_visible_x)
16590 {
16591 /* Glyph is at least partially visible. */
16592 ++it->hpos;
16593 if (x < it->first_visible_x)
16594 it->glyph_row->x = x - it->first_visible_x;
16595 }
16596 else
16597 {
16598 /* Glyph is off the left margin of the display area.
16599 Should not happen. */
16600 abort ();
16601 }
16602
16603 row->ascent = max (row->ascent, it->max_ascent);
16604 row->height = max (row->height, it->max_ascent + it->max_descent);
16605 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16606 row->phys_height = max (row->phys_height,
16607 it->max_phys_ascent + it->max_phys_descent);
16608 x += glyph->pixel_width;
16609 ++i;
16610 }
16611
16612 /* Stop if max_x reached. */
16613 if (i < nglyphs)
16614 break;
16615
16616 /* Stop at line ends. */
16617 if (ITERATOR_AT_END_OF_LINE_P (it))
16618 {
16619 it->continuation_lines_width = 0;
16620 break;
16621 }
16622
16623 set_iterator_to_next (it, 1);
16624
16625 /* Stop if truncating at the right edge. */
16626 if (it->truncate_lines_p
16627 && it->current_x >= it->last_visible_x)
16628 {
16629 /* Add truncation mark, but don't do it if the line is
16630 truncated at a padding space. */
16631 if (IT_CHARPOS (*it) < it->string_nchars)
16632 {
16633 if (!FRAME_WINDOW_P (it->f))
16634 {
16635 int i, n;
16636
16637 if (it->current_x > it->last_visible_x)
16638 {
16639 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16640 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16641 break;
16642 for (n = row->used[TEXT_AREA]; i < n; ++i)
16643 {
16644 row->used[TEXT_AREA] = i;
16645 produce_special_glyphs (it, IT_TRUNCATION);
16646 }
16647 }
16648 produce_special_glyphs (it, IT_TRUNCATION);
16649 }
16650 it->glyph_row->truncated_on_right_p = 1;
16651 }
16652 break;
16653 }
16654 }
16655
16656 /* Maybe insert a truncation at the left. */
16657 if (it->first_visible_x
16658 && IT_CHARPOS (*it) > 0)
16659 {
16660 if (!FRAME_WINDOW_P (it->f))
16661 insert_left_trunc_glyphs (it);
16662 it->glyph_row->truncated_on_left_p = 1;
16663 }
16664
16665 it->face_id = saved_face_id;
16666
16667 /* Value is number of columns displayed. */
16668 return it->hpos - hpos_at_start;
16669 }
16670
16671
16672 \f
16673 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16674 appears as an element of LIST or as the car of an element of LIST.
16675 If PROPVAL is a list, compare each element against LIST in that
16676 way, and return 1/2 if any element of PROPVAL is found in LIST.
16677 Otherwise return 0. This function cannot quit.
16678 The return value is 2 if the text is invisible but with an ellipsis
16679 and 1 if it's invisible and without an ellipsis. */
16680
16681 int
16682 invisible_p (propval, list)
16683 register Lisp_Object propval;
16684 Lisp_Object list;
16685 {
16686 register Lisp_Object tail, proptail;
16687
16688 for (tail = list; CONSP (tail); tail = XCDR (tail))
16689 {
16690 register Lisp_Object tem;
16691 tem = XCAR (tail);
16692 if (EQ (propval, tem))
16693 return 1;
16694 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16695 return NILP (XCDR (tem)) ? 1 : 2;
16696 }
16697
16698 if (CONSP (propval))
16699 {
16700 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16701 {
16702 Lisp_Object propelt;
16703 propelt = XCAR (proptail);
16704 for (tail = list; CONSP (tail); tail = XCDR (tail))
16705 {
16706 register Lisp_Object tem;
16707 tem = XCAR (tail);
16708 if (EQ (propelt, tem))
16709 return 1;
16710 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16711 return NILP (XCDR (tem)) ? 1 : 2;
16712 }
16713 }
16714 }
16715
16716 return 0;
16717 }
16718
16719 /* Calculate a width or height in pixels from a specification using
16720 the following elements:
16721
16722 SPEC ::=
16723 NUM - a (fractional) multiple of the default font width/height
16724 (NUM) - specifies exactly NUM pixels
16725 UNIT - a fixed number of pixels, see below.
16726 ELEMENT - size of a display element in pixels, see below.
16727 (NUM . SPEC) - equals NUM * SPEC
16728 (+ SPEC SPEC ...) - add pixel values
16729 (- SPEC SPEC ...) - subtract pixel values
16730 (- SPEC) - negate pixel value
16731
16732 NUM ::=
16733 INT or FLOAT - a number constant
16734 SYMBOL - use symbol's (buffer local) variable binding.
16735
16736 UNIT ::=
16737 in - pixels per inch *)
16738 mm - pixels per 1/1000 meter *)
16739 cm - pixels per 1/100 meter *)
16740 width - width of current font in pixels.
16741 height - height of current font in pixels.
16742
16743 *) using the ratio(s) defined in display-pixels-per-inch.
16744
16745 ELEMENT ::=
16746
16747 left-fringe - left fringe width in pixels
16748 right-fringe - right fringe width in pixels
16749
16750 left-margin - left margin width in pixels
16751 right-margin - right margin width in pixels
16752
16753 scroll-bar - scroll-bar area width in pixels
16754
16755 Examples:
16756
16757 Pixels corresponding to 5 inches:
16758 (5 . in)
16759
16760 Total width of non-text areas on left side of window (if scroll-bar is on left):
16761 '(space :width (+ left-fringe left-margin scroll-bar))
16762
16763 Align to first text column (in header line):
16764 '(space :align-to 0)
16765
16766 Align to middle of text area minus half the width of variable `my-image'
16767 containing a loaded image:
16768 '(space :align-to (0.5 . (- text my-image)))
16769
16770 Width of left margin minus width of 1 character in the default font:
16771 '(space :width (- left-margin 1))
16772
16773 Width of left margin minus width of 2 characters in the current font:
16774 '(space :width (- left-margin (2 . width)))
16775
16776 Center 1 character over left-margin (in header line):
16777 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
16778
16779 Different ways to express width of left fringe plus left margin minus one pixel:
16780 '(space :width (- (+ left-fringe left-margin) (1)))
16781 '(space :width (+ left-fringe left-margin (- (1))))
16782 '(space :width (+ left-fringe left-margin (-1)))
16783
16784 */
16785
16786 #define NUMVAL(X) \
16787 ((INTEGERP (X) || FLOATP (X)) \
16788 ? XFLOATINT (X) \
16789 : - 1)
16790
16791 int
16792 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
16793 double *res;
16794 struct it *it;
16795 Lisp_Object prop;
16796 void *font;
16797 int width_p, *align_to;
16798 {
16799 double pixels;
16800
16801 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
16802 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
16803
16804 if (NILP (prop))
16805 return OK_PIXELS (0);
16806
16807 if (SYMBOLP (prop))
16808 {
16809 if (SCHARS (SYMBOL_NAME (prop)) == 2)
16810 {
16811 char *unit = SDATA (SYMBOL_NAME (prop));
16812
16813 if (unit[0] == 'i' && unit[1] == 'n')
16814 pixels = 1.0;
16815 else if (unit[0] == 'm' && unit[1] == 'm')
16816 pixels = 25.4;
16817 else if (unit[0] == 'c' && unit[1] == 'm')
16818 pixels = 2.54;
16819 else
16820 pixels = 0;
16821 if (pixels > 0)
16822 {
16823 double ppi;
16824 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
16825 || (CONSP (Vdisplay_pixels_per_inch)
16826 && (ppi = (width_p
16827 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
16828 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
16829 ppi > 0)))
16830 return OK_PIXELS (ppi / pixels);
16831
16832 return 0;
16833 }
16834 }
16835
16836 #ifdef HAVE_WINDOW_SYSTEM
16837 if (EQ (prop, Qheight))
16838 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
16839 if (EQ (prop, Qwidth))
16840 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
16841 #else
16842 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
16843 return OK_PIXELS (1);
16844 #endif
16845
16846 if (EQ (prop, Qtext))
16847 return OK_PIXELS (width_p
16848 ? window_box_width (it->w, TEXT_AREA)
16849 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
16850
16851 if (align_to && *align_to < 0)
16852 {
16853 *res = 0;
16854 if (EQ (prop, Qleft))
16855 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
16856 if (EQ (prop, Qright))
16857 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
16858 if (EQ (prop, Qcenter))
16859 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
16860 + window_box_width (it->w, TEXT_AREA) / 2);
16861 if (EQ (prop, Qleft_fringe))
16862 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
16863 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
16864 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
16865 if (EQ (prop, Qright_fringe))
16866 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
16867 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
16868 : window_box_right_offset (it->w, TEXT_AREA));
16869 if (EQ (prop, Qleft_margin))
16870 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
16871 if (EQ (prop, Qright_margin))
16872 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
16873 if (EQ (prop, Qscroll_bar))
16874 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
16875 ? 0
16876 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
16877 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
16878 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
16879 : 0)));
16880 }
16881 else
16882 {
16883 if (EQ (prop, Qleft_fringe))
16884 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
16885 if (EQ (prop, Qright_fringe))
16886 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
16887 if (EQ (prop, Qleft_margin))
16888 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
16889 if (EQ (prop, Qright_margin))
16890 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
16891 if (EQ (prop, Qscroll_bar))
16892 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
16893 }
16894
16895 prop = Fbuffer_local_value (prop, it->w->buffer);
16896 }
16897
16898 if (INTEGERP (prop) || FLOATP (prop))
16899 {
16900 int base_unit = (width_p
16901 ? FRAME_COLUMN_WIDTH (it->f)
16902 : FRAME_LINE_HEIGHT (it->f));
16903 return OK_PIXELS (XFLOATINT (prop) * base_unit);
16904 }
16905
16906 if (CONSP (prop))
16907 {
16908 Lisp_Object car = XCAR (prop);
16909 Lisp_Object cdr = XCDR (prop);
16910
16911 if (SYMBOLP (car))
16912 {
16913 #ifdef HAVE_WINDOW_SYSTEM
16914 if (valid_image_p (prop))
16915 {
16916 int id = lookup_image (it->f, prop);
16917 struct image *img = IMAGE_FROM_ID (it->f, id);
16918
16919 return OK_PIXELS (width_p ? img->width : img->height);
16920 }
16921 #endif
16922 if (EQ (car, Qplus) || EQ (car, Qminus))
16923 {
16924 int first = 1;
16925 double px;
16926
16927 pixels = 0;
16928 while (CONSP (cdr))
16929 {
16930 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
16931 font, width_p, align_to))
16932 return 0;
16933 if (first)
16934 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
16935 else
16936 pixels += px;
16937 cdr = XCDR (cdr);
16938 }
16939 if (EQ (car, Qminus))
16940 pixels = -pixels;
16941 return OK_PIXELS (pixels);
16942 }
16943
16944 car = Fbuffer_local_value (car, it->w->buffer);
16945 }
16946
16947 if (INTEGERP (car) || FLOATP (car))
16948 {
16949 double fact;
16950 pixels = XFLOATINT (car);
16951 if (NILP (cdr))
16952 return OK_PIXELS (pixels);
16953 if (calc_pixel_width_or_height (&fact, it, cdr,
16954 font, width_p, align_to))
16955 return OK_PIXELS (pixels * fact);
16956 return 0;
16957 }
16958
16959 return 0;
16960 }
16961
16962 return 0;
16963 }
16964
16965 \f
16966 /***********************************************************************
16967 Glyph Display
16968 ***********************************************************************/
16969
16970 #ifdef HAVE_WINDOW_SYSTEM
16971
16972 #if GLYPH_DEBUG
16973
16974 void
16975 dump_glyph_string (s)
16976 struct glyph_string *s;
16977 {
16978 fprintf (stderr, "glyph string\n");
16979 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16980 s->x, s->y, s->width, s->height);
16981 fprintf (stderr, " ybase = %d\n", s->ybase);
16982 fprintf (stderr, " hl = %d\n", s->hl);
16983 fprintf (stderr, " left overhang = %d, right = %d\n",
16984 s->left_overhang, s->right_overhang);
16985 fprintf (stderr, " nchars = %d\n", s->nchars);
16986 fprintf (stderr, " extends to end of line = %d\n",
16987 s->extends_to_end_of_line_p);
16988 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16989 fprintf (stderr, " bg width = %d\n", s->background_width);
16990 }
16991
16992 #endif /* GLYPH_DEBUG */
16993
16994 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16995 of XChar2b structures for S; it can't be allocated in
16996 init_glyph_string because it must be allocated via `alloca'. W
16997 is the window on which S is drawn. ROW and AREA are the glyph row
16998 and area within the row from which S is constructed. START is the
16999 index of the first glyph structure covered by S. HL is a
17000 face-override for drawing S. */
17001
17002 #ifdef HAVE_NTGUI
17003 #define OPTIONAL_HDC(hdc) hdc,
17004 #define DECLARE_HDC(hdc) HDC hdc;
17005 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17006 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17007 #endif
17008
17009 #ifndef OPTIONAL_HDC
17010 #define OPTIONAL_HDC(hdc)
17011 #define DECLARE_HDC(hdc)
17012 #define ALLOCATE_HDC(hdc, f)
17013 #define RELEASE_HDC(hdc, f)
17014 #endif
17015
17016 static void
17017 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17018 struct glyph_string *s;
17019 DECLARE_HDC (hdc)
17020 XChar2b *char2b;
17021 struct window *w;
17022 struct glyph_row *row;
17023 enum glyph_row_area area;
17024 int start;
17025 enum draw_glyphs_face hl;
17026 {
17027 bzero (s, sizeof *s);
17028 s->w = w;
17029 s->f = XFRAME (w->frame);
17030 #ifdef HAVE_NTGUI
17031 s->hdc = hdc;
17032 #endif
17033 s->display = FRAME_X_DISPLAY (s->f);
17034 s->window = FRAME_X_WINDOW (s->f);
17035 s->char2b = char2b;
17036 s->hl = hl;
17037 s->row = row;
17038 s->area = area;
17039 s->first_glyph = row->glyphs[area] + start;
17040 s->height = row->height;
17041 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17042
17043 /* Display the internal border below the tool-bar window. */
17044 if (s->w == XWINDOW (s->f->tool_bar_window))
17045 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17046
17047 s->ybase = s->y + row->ascent;
17048 }
17049
17050
17051 /* Append the list of glyph strings with head H and tail T to the list
17052 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17053
17054 static INLINE void
17055 append_glyph_string_lists (head, tail, h, t)
17056 struct glyph_string **head, **tail;
17057 struct glyph_string *h, *t;
17058 {
17059 if (h)
17060 {
17061 if (*head)
17062 (*tail)->next = h;
17063 else
17064 *head = h;
17065 h->prev = *tail;
17066 *tail = t;
17067 }
17068 }
17069
17070
17071 /* Prepend the list of glyph strings with head H and tail T to the
17072 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17073 result. */
17074
17075 static INLINE void
17076 prepend_glyph_string_lists (head, tail, h, t)
17077 struct glyph_string **head, **tail;
17078 struct glyph_string *h, *t;
17079 {
17080 if (h)
17081 {
17082 if (*head)
17083 (*head)->prev = t;
17084 else
17085 *tail = t;
17086 t->next = *head;
17087 *head = h;
17088 }
17089 }
17090
17091
17092 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17093 Set *HEAD and *TAIL to the resulting list. */
17094
17095 static INLINE void
17096 append_glyph_string (head, tail, s)
17097 struct glyph_string **head, **tail;
17098 struct glyph_string *s;
17099 {
17100 s->next = s->prev = NULL;
17101 append_glyph_string_lists (head, tail, s, s);
17102 }
17103
17104
17105 /* Get face and two-byte form of character glyph GLYPH on frame F.
17106 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17107 a pointer to a realized face that is ready for display. */
17108
17109 static INLINE struct face *
17110 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17111 struct frame *f;
17112 struct glyph *glyph;
17113 XChar2b *char2b;
17114 int *two_byte_p;
17115 {
17116 struct face *face;
17117
17118 xassert (glyph->type == CHAR_GLYPH);
17119 face = FACE_FROM_ID (f, glyph->face_id);
17120
17121 if (two_byte_p)
17122 *two_byte_p = 0;
17123
17124 if (!glyph->multibyte_p)
17125 {
17126 /* Unibyte case. We don't have to encode, but we have to make
17127 sure to use a face suitable for unibyte. */
17128 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17129 }
17130 else if (glyph->u.ch < 128
17131 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17132 {
17133 /* Case of ASCII in a face known to fit ASCII. */
17134 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17135 }
17136 else
17137 {
17138 int c1, c2, charset;
17139
17140 /* Split characters into bytes. If c2 is -1 afterwards, C is
17141 really a one-byte character so that byte1 is zero. */
17142 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17143 if (c2 > 0)
17144 STORE_XCHAR2B (char2b, c1, c2);
17145 else
17146 STORE_XCHAR2B (char2b, 0, c1);
17147
17148 /* Maybe encode the character in *CHAR2B. */
17149 if (charset != CHARSET_ASCII)
17150 {
17151 struct font_info *font_info
17152 = FONT_INFO_FROM_ID (f, face->font_info_id);
17153 if (font_info)
17154 glyph->font_type
17155 = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17156 }
17157 }
17158
17159 /* Make sure X resources of the face are allocated. */
17160 xassert (face != NULL);
17161 PREPARE_FACE_FOR_DISPLAY (f, face);
17162 return face;
17163 }
17164
17165
17166 /* Fill glyph string S with composition components specified by S->cmp.
17167
17168 FACES is an array of faces for all components of this composition.
17169 S->gidx is the index of the first component for S.
17170 OVERLAPS_P non-zero means S should draw the foreground only, and
17171 use its physical height for clipping.
17172
17173 Value is the index of a component not in S. */
17174
17175 static int
17176 fill_composite_glyph_string (s, faces, overlaps_p)
17177 struct glyph_string *s;
17178 struct face **faces;
17179 int overlaps_p;
17180 {
17181 int i;
17182
17183 xassert (s);
17184
17185 s->for_overlaps_p = overlaps_p;
17186
17187 s->face = faces[s->gidx];
17188 s->font = s->face->font;
17189 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17190
17191 /* For all glyphs of this composition, starting at the offset
17192 S->gidx, until we reach the end of the definition or encounter a
17193 glyph that requires the different face, add it to S. */
17194 ++s->nchars;
17195 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17196 ++s->nchars;
17197
17198 /* All glyph strings for the same composition has the same width,
17199 i.e. the width set for the first component of the composition. */
17200
17201 s->width = s->first_glyph->pixel_width;
17202
17203 /* If the specified font could not be loaded, use the frame's
17204 default font, but record the fact that we couldn't load it in
17205 the glyph string so that we can draw rectangles for the
17206 characters of the glyph string. */
17207 if (s->font == NULL)
17208 {
17209 s->font_not_found_p = 1;
17210 s->font = FRAME_FONT (s->f);
17211 }
17212
17213 /* Adjust base line for subscript/superscript text. */
17214 s->ybase += s->first_glyph->voffset;
17215
17216 xassert (s->face && s->face->gc);
17217
17218 /* This glyph string must always be drawn with 16-bit functions. */
17219 s->two_byte_p = 1;
17220
17221 return s->gidx + s->nchars;
17222 }
17223
17224
17225 /* Fill glyph string S from a sequence of character glyphs.
17226
17227 FACE_ID is the face id of the string. START is the index of the
17228 first glyph to consider, END is the index of the last + 1.
17229 OVERLAPS_P non-zero means S should draw the foreground only, and
17230 use its physical height for clipping.
17231
17232 Value is the index of the first glyph not in S. */
17233
17234 static int
17235 fill_glyph_string (s, face_id, start, end, overlaps_p)
17236 struct glyph_string *s;
17237 int face_id;
17238 int start, end, overlaps_p;
17239 {
17240 struct glyph *glyph, *last;
17241 int voffset;
17242 int glyph_not_available_p;
17243
17244 xassert (s->f == XFRAME (s->w->frame));
17245 xassert (s->nchars == 0);
17246 xassert (start >= 0 && end > start);
17247
17248 s->for_overlaps_p = overlaps_p,
17249 glyph = s->row->glyphs[s->area] + start;
17250 last = s->row->glyphs[s->area] + end;
17251 voffset = glyph->voffset;
17252
17253 glyph_not_available_p = glyph->glyph_not_available_p;
17254
17255 while (glyph < last
17256 && glyph->type == CHAR_GLYPH
17257 && glyph->voffset == voffset
17258 /* Same face id implies same font, nowadays. */
17259 && glyph->face_id == face_id
17260 && glyph->glyph_not_available_p == glyph_not_available_p)
17261 {
17262 int two_byte_p;
17263
17264 s->face = get_glyph_face_and_encoding (s->f, glyph,
17265 s->char2b + s->nchars,
17266 &two_byte_p);
17267 s->two_byte_p = two_byte_p;
17268 ++s->nchars;
17269 xassert (s->nchars <= end - start);
17270 s->width += glyph->pixel_width;
17271 ++glyph;
17272 }
17273
17274 s->font = s->face->font;
17275 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17276
17277 /* If the specified font could not be loaded, use the frame's font,
17278 but record the fact that we couldn't load it in
17279 S->font_not_found_p so that we can draw rectangles for the
17280 characters of the glyph string. */
17281 if (s->font == NULL || glyph_not_available_p)
17282 {
17283 s->font_not_found_p = 1;
17284 s->font = FRAME_FONT (s->f);
17285 }
17286
17287 /* Adjust base line for subscript/superscript text. */
17288 s->ybase += voffset;
17289
17290 xassert (s->face && s->face->gc);
17291 return glyph - s->row->glyphs[s->area];
17292 }
17293
17294
17295 /* Fill glyph string S from image glyph S->first_glyph. */
17296
17297 static void
17298 fill_image_glyph_string (s)
17299 struct glyph_string *s;
17300 {
17301 xassert (s->first_glyph->type == IMAGE_GLYPH);
17302 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17303 xassert (s->img);
17304 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17305 s->font = s->face->font;
17306 s->width = s->first_glyph->pixel_width;
17307
17308 /* Adjust base line for subscript/superscript text. */
17309 s->ybase += s->first_glyph->voffset;
17310 }
17311
17312
17313 /* Fill glyph string S from a sequence of stretch glyphs.
17314
17315 ROW is the glyph row in which the glyphs are found, AREA is the
17316 area within the row. START is the index of the first glyph to
17317 consider, END is the index of the last + 1.
17318
17319 Value is the index of the first glyph not in S. */
17320
17321 static int
17322 fill_stretch_glyph_string (s, row, area, start, end)
17323 struct glyph_string *s;
17324 struct glyph_row *row;
17325 enum glyph_row_area area;
17326 int start, end;
17327 {
17328 struct glyph *glyph, *last;
17329 int voffset, face_id;
17330
17331 xassert (s->first_glyph->type == STRETCH_GLYPH);
17332
17333 glyph = s->row->glyphs[s->area] + start;
17334 last = s->row->glyphs[s->area] + end;
17335 face_id = glyph->face_id;
17336 s->face = FACE_FROM_ID (s->f, face_id);
17337 s->font = s->face->font;
17338 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17339 s->width = glyph->pixel_width;
17340 voffset = glyph->voffset;
17341
17342 for (++glyph;
17343 (glyph < last
17344 && glyph->type == STRETCH_GLYPH
17345 && glyph->voffset == voffset
17346 && glyph->face_id == face_id);
17347 ++glyph)
17348 s->width += glyph->pixel_width;
17349
17350 /* Adjust base line for subscript/superscript text. */
17351 s->ybase += voffset;
17352
17353 /* The case that face->gc == 0 is handled when drawing the glyph
17354 string by calling PREPARE_FACE_FOR_DISPLAY. */
17355 xassert (s->face);
17356 return glyph - s->row->glyphs[s->area];
17357 }
17358
17359
17360 /* EXPORT for RIF:
17361 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17362 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17363 assumed to be zero. */
17364
17365 void
17366 x_get_glyph_overhangs (glyph, f, left, right)
17367 struct glyph *glyph;
17368 struct frame *f;
17369 int *left, *right;
17370 {
17371 *left = *right = 0;
17372
17373 if (glyph->type == CHAR_GLYPH)
17374 {
17375 XFontStruct *font;
17376 struct face *face;
17377 struct font_info *font_info;
17378 XChar2b char2b;
17379 XCharStruct *pcm;
17380
17381 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17382 font = face->font;
17383 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17384 if (font /* ++KFS: Should this be font_info ? */
17385 && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
17386 {
17387 if (pcm->rbearing > pcm->width)
17388 *right = pcm->rbearing - pcm->width;
17389 if (pcm->lbearing < 0)
17390 *left = -pcm->lbearing;
17391 }
17392 }
17393 }
17394
17395
17396 /* Return the index of the first glyph preceding glyph string S that
17397 is overwritten by S because of S's left overhang. Value is -1
17398 if no glyphs are overwritten. */
17399
17400 static int
17401 left_overwritten (s)
17402 struct glyph_string *s;
17403 {
17404 int k;
17405
17406 if (s->left_overhang)
17407 {
17408 int x = 0, i;
17409 struct glyph *glyphs = s->row->glyphs[s->area];
17410 int first = s->first_glyph - glyphs;
17411
17412 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17413 x -= glyphs[i].pixel_width;
17414
17415 k = i + 1;
17416 }
17417 else
17418 k = -1;
17419
17420 return k;
17421 }
17422
17423
17424 /* Return the index of the first glyph preceding glyph string S that
17425 is overwriting S because of its right overhang. Value is -1 if no
17426 glyph in front of S overwrites S. */
17427
17428 static int
17429 left_overwriting (s)
17430 struct glyph_string *s;
17431 {
17432 int i, k, x;
17433 struct glyph *glyphs = s->row->glyphs[s->area];
17434 int first = s->first_glyph - glyphs;
17435
17436 k = -1;
17437 x = 0;
17438 for (i = first - 1; i >= 0; --i)
17439 {
17440 int left, right;
17441 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17442 if (x + right > 0)
17443 k = i;
17444 x -= glyphs[i].pixel_width;
17445 }
17446
17447 return k;
17448 }
17449
17450
17451 /* Return the index of the last glyph following glyph string S that is
17452 not overwritten by S because of S's right overhang. Value is -1 if
17453 no such glyph is found. */
17454
17455 static int
17456 right_overwritten (s)
17457 struct glyph_string *s;
17458 {
17459 int k = -1;
17460
17461 if (s->right_overhang)
17462 {
17463 int x = 0, i;
17464 struct glyph *glyphs = s->row->glyphs[s->area];
17465 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17466 int end = s->row->used[s->area];
17467
17468 for (i = first; i < end && s->right_overhang > x; ++i)
17469 x += glyphs[i].pixel_width;
17470
17471 k = i;
17472 }
17473
17474 return k;
17475 }
17476
17477
17478 /* Return the index of the last glyph following glyph string S that
17479 overwrites S because of its left overhang. Value is negative
17480 if no such glyph is found. */
17481
17482 static int
17483 right_overwriting (s)
17484 struct glyph_string *s;
17485 {
17486 int i, k, x;
17487 int end = s->row->used[s->area];
17488 struct glyph *glyphs = s->row->glyphs[s->area];
17489 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17490
17491 k = -1;
17492 x = 0;
17493 for (i = first; i < end; ++i)
17494 {
17495 int left, right;
17496 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17497 if (x - left < 0)
17498 k = i;
17499 x += glyphs[i].pixel_width;
17500 }
17501
17502 return k;
17503 }
17504
17505
17506 /* Get face and two-byte form of character C in face FACE_ID on frame
17507 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17508 means we want to display multibyte text. DISPLAY_P non-zero means
17509 make sure that X resources for the face returned are allocated.
17510 Value is a pointer to a realized face that is ready for display if
17511 DISPLAY_P is non-zero. */
17512
17513 static INLINE struct face *
17514 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17515 struct frame *f;
17516 int c, face_id;
17517 XChar2b *char2b;
17518 int multibyte_p, display_p;
17519 {
17520 struct face *face = FACE_FROM_ID (f, face_id);
17521
17522 if (!multibyte_p)
17523 {
17524 /* Unibyte case. We don't have to encode, but we have to make
17525 sure to use a face suitable for unibyte. */
17526 STORE_XCHAR2B (char2b, 0, c);
17527 face_id = FACE_FOR_CHAR (f, face, c);
17528 face = FACE_FROM_ID (f, face_id);
17529 }
17530 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17531 {
17532 /* Case of ASCII in a face known to fit ASCII. */
17533 STORE_XCHAR2B (char2b, 0, c);
17534 }
17535 else
17536 {
17537 int c1, c2, charset;
17538
17539 /* Split characters into bytes. If c2 is -1 afterwards, C is
17540 really a one-byte character so that byte1 is zero. */
17541 SPLIT_CHAR (c, charset, c1, c2);
17542 if (c2 > 0)
17543 STORE_XCHAR2B (char2b, c1, c2);
17544 else
17545 STORE_XCHAR2B (char2b, 0, c1);
17546
17547 /* Maybe encode the character in *CHAR2B. */
17548 if (face->font != NULL)
17549 {
17550 struct font_info *font_info
17551 = FONT_INFO_FROM_ID (f, face->font_info_id);
17552 if (font_info)
17553 FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
17554 }
17555 }
17556
17557 /* Make sure X resources of the face are allocated. */
17558 #ifdef HAVE_X_WINDOWS
17559 if (display_p)
17560 #endif
17561 {
17562 xassert (face != NULL);
17563 PREPARE_FACE_FOR_DISPLAY (f, face);
17564 }
17565
17566 return face;
17567 }
17568
17569
17570 /* Set background width of glyph string S. START is the index of the
17571 first glyph following S. LAST_X is the right-most x-position + 1
17572 in the drawing area. */
17573
17574 static INLINE void
17575 set_glyph_string_background_width (s, start, last_x)
17576 struct glyph_string *s;
17577 int start;
17578 int last_x;
17579 {
17580 /* If the face of this glyph string has to be drawn to the end of
17581 the drawing area, set S->extends_to_end_of_line_p. */
17582 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17583
17584 if (start == s->row->used[s->area]
17585 && s->area == TEXT_AREA
17586 && ((s->hl == DRAW_NORMAL_TEXT
17587 && (s->row->fill_line_p
17588 || s->face->background != default_face->background
17589 || s->face->stipple != default_face->stipple
17590 || s->row->mouse_face_p))
17591 || s->hl == DRAW_MOUSE_FACE
17592 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17593 && s->row->fill_line_p)))
17594 s->extends_to_end_of_line_p = 1;
17595
17596 /* If S extends its face to the end of the line, set its
17597 background_width to the distance to the right edge of the drawing
17598 area. */
17599 if (s->extends_to_end_of_line_p)
17600 s->background_width = last_x - s->x + 1;
17601 else
17602 s->background_width = s->width;
17603 }
17604
17605
17606 /* Compute overhangs and x-positions for glyph string S and its
17607 predecessors, or successors. X is the starting x-position for S.
17608 BACKWARD_P non-zero means process predecessors. */
17609
17610 static void
17611 compute_overhangs_and_x (s, x, backward_p)
17612 struct glyph_string *s;
17613 int x;
17614 int backward_p;
17615 {
17616 if (backward_p)
17617 {
17618 while (s)
17619 {
17620 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
17621 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
17622 x -= s->width;
17623 s->x = x;
17624 s = s->prev;
17625 }
17626 }
17627 else
17628 {
17629 while (s)
17630 {
17631 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
17632 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
17633 s->x = x;
17634 x += s->width;
17635 s = s->next;
17636 }
17637 }
17638 }
17639
17640
17641
17642 /* The following macros are only called from draw_glyphs below.
17643 They reference the following parameters of that function directly:
17644 `w', `row', `area', and `overlap_p'
17645 as well as the following local variables:
17646 `s', `f', and `hdc' (in W32) */
17647
17648 #ifdef HAVE_NTGUI
17649 /* On W32, silently add local `hdc' variable to argument list of
17650 init_glyph_string. */
17651 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17652 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17653 #else
17654 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17655 init_glyph_string (s, char2b, w, row, area, start, hl)
17656 #endif
17657
17658 /* Add a glyph string for a stretch glyph to the list of strings
17659 between HEAD and TAIL. START is the index of the stretch glyph in
17660 row area AREA of glyph row ROW. END is the index of the last glyph
17661 in that glyph row area. X is the current output position assigned
17662 to the new glyph string constructed. HL overrides that face of the
17663 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17664 is the right-most x-position of the drawing area. */
17665
17666 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17667 and below -- keep them on one line. */
17668 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17669 do \
17670 { \
17671 s = (struct glyph_string *) alloca (sizeof *s); \
17672 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17673 START = fill_stretch_glyph_string (s, row, area, START, END); \
17674 append_glyph_string (&HEAD, &TAIL, s); \
17675 s->x = (X); \
17676 } \
17677 while (0)
17678
17679
17680 /* Add a glyph string for an image glyph to the list of strings
17681 between HEAD and TAIL. START is the index of the image glyph in
17682 row area AREA of glyph row ROW. END is the index of the last glyph
17683 in that glyph row area. X is the current output position assigned
17684 to the new glyph string constructed. HL overrides that face of the
17685 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17686 is the right-most x-position of the drawing area. */
17687
17688 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17689 do \
17690 { \
17691 s = (struct glyph_string *) alloca (sizeof *s); \
17692 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17693 fill_image_glyph_string (s); \
17694 append_glyph_string (&HEAD, &TAIL, s); \
17695 ++START; \
17696 s->x = (X); \
17697 } \
17698 while (0)
17699
17700
17701 /* Add a glyph string for a sequence of character glyphs to the list
17702 of strings between HEAD and TAIL. START is the index of the first
17703 glyph in row area AREA of glyph row ROW that is part of the new
17704 glyph string. END is the index of the last glyph in that glyph row
17705 area. X is the current output position assigned to the new glyph
17706 string constructed. HL overrides that face of the glyph; e.g. it
17707 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17708 right-most x-position of the drawing area. */
17709
17710 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17711 do \
17712 { \
17713 int c, face_id; \
17714 XChar2b *char2b; \
17715 \
17716 c = (row)->glyphs[area][START].u.ch; \
17717 face_id = (row)->glyphs[area][START].face_id; \
17718 \
17719 s = (struct glyph_string *) alloca (sizeof *s); \
17720 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17721 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17722 append_glyph_string (&HEAD, &TAIL, s); \
17723 s->x = (X); \
17724 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17725 } \
17726 while (0)
17727
17728
17729 /* Add a glyph string for a composite sequence to the list of strings
17730 between HEAD and TAIL. START is the index of the first glyph in
17731 row area AREA of glyph row ROW that is part of the new glyph
17732 string. END is the index of the last glyph in that glyph row area.
17733 X is the current output position assigned to the new glyph string
17734 constructed. HL overrides that face of the glyph; e.g. it is
17735 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17736 x-position of the drawing area. */
17737
17738 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17739 do { \
17740 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17741 int face_id = (row)->glyphs[area][START].face_id; \
17742 struct face *base_face = FACE_FROM_ID (f, face_id); \
17743 struct composition *cmp = composition_table[cmp_id]; \
17744 int glyph_len = cmp->glyph_len; \
17745 XChar2b *char2b; \
17746 struct face **faces; \
17747 struct glyph_string *first_s = NULL; \
17748 int n; \
17749 \
17750 base_face = base_face->ascii_face; \
17751 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17752 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17753 /* At first, fill in `char2b' and `faces'. */ \
17754 for (n = 0; n < glyph_len; n++) \
17755 { \
17756 int c = COMPOSITION_GLYPH (cmp, n); \
17757 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17758 faces[n] = FACE_FROM_ID (f, this_face_id); \
17759 get_char_face_and_encoding (f, c, this_face_id, \
17760 char2b + n, 1, 1); \
17761 } \
17762 \
17763 /* Make glyph_strings for each glyph sequence that is drawable by \
17764 the same face, and append them to HEAD/TAIL. */ \
17765 for (n = 0; n < cmp->glyph_len;) \
17766 { \
17767 s = (struct glyph_string *) alloca (sizeof *s); \
17768 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17769 append_glyph_string (&(HEAD), &(TAIL), s); \
17770 s->cmp = cmp; \
17771 s->gidx = n; \
17772 s->x = (X); \
17773 \
17774 if (n == 0) \
17775 first_s = s; \
17776 \
17777 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17778 } \
17779 \
17780 ++START; \
17781 s = first_s; \
17782 } while (0)
17783
17784
17785 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17786 of AREA of glyph row ROW on window W between indices START and END.
17787 HL overrides the face for drawing glyph strings, e.g. it is
17788 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17789 x-positions of the drawing area.
17790
17791 This is an ugly monster macro construct because we must use alloca
17792 to allocate glyph strings (because draw_glyphs can be called
17793 asynchronously). */
17794
17795 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17796 do \
17797 { \
17798 HEAD = TAIL = NULL; \
17799 while (START < END) \
17800 { \
17801 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17802 switch (first_glyph->type) \
17803 { \
17804 case CHAR_GLYPH: \
17805 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17806 HL, X, LAST_X); \
17807 break; \
17808 \
17809 case COMPOSITE_GLYPH: \
17810 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17811 HL, X, LAST_X); \
17812 break; \
17813 \
17814 case STRETCH_GLYPH: \
17815 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17816 HL, X, LAST_X); \
17817 break; \
17818 \
17819 case IMAGE_GLYPH: \
17820 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17821 HL, X, LAST_X); \
17822 break; \
17823 \
17824 default: \
17825 abort (); \
17826 } \
17827 \
17828 set_glyph_string_background_width (s, START, LAST_X); \
17829 (X) += s->width; \
17830 } \
17831 } \
17832 while (0)
17833
17834
17835 /* Draw glyphs between START and END in AREA of ROW on window W,
17836 starting at x-position X. X is relative to AREA in W. HL is a
17837 face-override with the following meaning:
17838
17839 DRAW_NORMAL_TEXT draw normally
17840 DRAW_CURSOR draw in cursor face
17841 DRAW_MOUSE_FACE draw in mouse face.
17842 DRAW_INVERSE_VIDEO draw in mode line face
17843 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17844 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17845
17846 If OVERLAPS_P is non-zero, draw only the foreground of characters
17847 and clip to the physical height of ROW.
17848
17849 Value is the x-position reached, relative to AREA of W. */
17850
17851 static int
17852 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17853 struct window *w;
17854 int x;
17855 struct glyph_row *row;
17856 enum glyph_row_area area;
17857 int start, end;
17858 enum draw_glyphs_face hl;
17859 int overlaps_p;
17860 {
17861 struct glyph_string *head, *tail;
17862 struct glyph_string *s;
17863 int last_x, area_width;
17864 int x_reached;
17865 int i, j;
17866 struct frame *f = XFRAME (WINDOW_FRAME (w));
17867 DECLARE_HDC (hdc);
17868
17869 ALLOCATE_HDC (hdc, f);
17870
17871 /* Let's rather be paranoid than getting a SEGV. */
17872 end = min (end, row->used[area]);
17873 start = max (0, start);
17874 start = min (end, start);
17875
17876 /* Translate X to frame coordinates. Set last_x to the right
17877 end of the drawing area. */
17878 if (row->full_width_p)
17879 {
17880 /* X is relative to the left edge of W, without scroll bars
17881 or fringes. */
17882 x += WINDOW_LEFT_EDGE_X (w);
17883 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17884 }
17885 else
17886 {
17887 int area_left = window_box_left (w, area);
17888 x += area_left;
17889 area_width = window_box_width (w, area);
17890 last_x = area_left + area_width;
17891 }
17892
17893 /* Build a doubly-linked list of glyph_string structures between
17894 head and tail from what we have to draw. Note that the macro
17895 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17896 the reason we use a separate variable `i'. */
17897 i = start;
17898 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17899 if (tail)
17900 x_reached = tail->x + tail->background_width;
17901 else
17902 x_reached = x;
17903
17904 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17905 the row, redraw some glyphs in front or following the glyph
17906 strings built above. */
17907 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17908 {
17909 int dummy_x = 0;
17910 struct glyph_string *h, *t;
17911
17912 /* Compute overhangs for all glyph strings. */
17913 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
17914 for (s = head; s; s = s->next)
17915 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
17916
17917 /* Prepend glyph strings for glyphs in front of the first glyph
17918 string that are overwritten because of the first glyph
17919 string's left overhang. The background of all strings
17920 prepended must be drawn because the first glyph string
17921 draws over it. */
17922 i = left_overwritten (head);
17923 if (i >= 0)
17924 {
17925 j = i;
17926 BUILD_GLYPH_STRINGS (j, start, h, t,
17927 DRAW_NORMAL_TEXT, dummy_x, last_x);
17928 start = i;
17929 compute_overhangs_and_x (t, head->x, 1);
17930 prepend_glyph_string_lists (&head, &tail, h, t);
17931 }
17932
17933 /* Prepend glyph strings for glyphs in front of the first glyph
17934 string that overwrite that glyph string because of their
17935 right overhang. For these strings, only the foreground must
17936 be drawn, because it draws over the glyph string at `head'.
17937 The background must not be drawn because this would overwrite
17938 right overhangs of preceding glyphs for which no glyph
17939 strings exist. */
17940 i = left_overwriting (head);
17941 if (i >= 0)
17942 {
17943 BUILD_GLYPH_STRINGS (i, start, h, t,
17944 DRAW_NORMAL_TEXT, dummy_x, last_x);
17945 for (s = h; s; s = s->next)
17946 s->background_filled_p = 1;
17947 compute_overhangs_and_x (t, head->x, 1);
17948 prepend_glyph_string_lists (&head, &tail, h, t);
17949 }
17950
17951 /* Append glyphs strings for glyphs following the last glyph
17952 string tail that are overwritten by tail. The background of
17953 these strings has to be drawn because tail's foreground draws
17954 over it. */
17955 i = right_overwritten (tail);
17956 if (i >= 0)
17957 {
17958 BUILD_GLYPH_STRINGS (end, i, h, t,
17959 DRAW_NORMAL_TEXT, x, last_x);
17960 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17961 append_glyph_string_lists (&head, &tail, h, t);
17962 }
17963
17964 /* Append glyph strings for glyphs following the last glyph
17965 string tail that overwrite tail. The foreground of such
17966 glyphs has to be drawn because it writes into the background
17967 of tail. The background must not be drawn because it could
17968 paint over the foreground of following glyphs. */
17969 i = right_overwriting (tail);
17970 if (i >= 0)
17971 {
17972 BUILD_GLYPH_STRINGS (end, i, h, t,
17973 DRAW_NORMAL_TEXT, x, last_x);
17974 for (s = h; s; s = s->next)
17975 s->background_filled_p = 1;
17976 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17977 append_glyph_string_lists (&head, &tail, h, t);
17978 }
17979 }
17980
17981 /* Draw all strings. */
17982 for (s = head; s; s = s->next)
17983 FRAME_RIF (f)->draw_glyph_string (s);
17984
17985 if (area == TEXT_AREA
17986 && !row->full_width_p
17987 /* When drawing overlapping rows, only the glyph strings'
17988 foreground is drawn, which doesn't erase a cursor
17989 completely. */
17990 && !overlaps_p)
17991 {
17992 int x0 = head ? head->x : x;
17993 int x1 = tail ? tail->x + tail->background_width : x;
17994
17995 int text_left = window_box_left (w, TEXT_AREA);
17996 x0 -= text_left;
17997 x1 -= text_left;
17998
17999 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18000 row->y, MATRIX_ROW_BOTTOM_Y (row));
18001 }
18002
18003 /* Value is the x-position up to which drawn, relative to AREA of W.
18004 This doesn't include parts drawn because of overhangs. */
18005 if (row->full_width_p)
18006 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18007 else
18008 x_reached -= window_box_left (w, area);
18009
18010 RELEASE_HDC (hdc, f);
18011
18012 return x_reached;
18013 }
18014
18015
18016 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18017 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18018
18019 static INLINE void
18020 append_glyph (it)
18021 struct it *it;
18022 {
18023 struct glyph *glyph;
18024 enum glyph_row_area area = it->area;
18025
18026 xassert (it->glyph_row);
18027 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18028
18029 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18030 if (glyph < it->glyph_row->glyphs[area + 1])
18031 {
18032 glyph->charpos = CHARPOS (it->position);
18033 glyph->object = it->object;
18034 glyph->pixel_width = it->pixel_width;
18035 glyph->ascent = it->ascent;
18036 glyph->descent = it->descent;
18037 glyph->voffset = it->voffset;
18038 glyph->type = CHAR_GLYPH;
18039 glyph->multibyte_p = it->multibyte_p;
18040 glyph->left_box_line_p = it->start_of_box_run_p;
18041 glyph->right_box_line_p = it->end_of_box_run_p;
18042 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18043 || it->phys_descent > it->descent);
18044 glyph->padding_p = 0;
18045 glyph->glyph_not_available_p = it->glyph_not_available_p;
18046 glyph->face_id = it->face_id;
18047 glyph->u.ch = it->char_to_display;
18048 glyph->font_type = FONT_TYPE_UNKNOWN;
18049 ++it->glyph_row->used[area];
18050 }
18051 }
18052
18053 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18054 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18055
18056 static INLINE void
18057 append_composite_glyph (it)
18058 struct it *it;
18059 {
18060 struct glyph *glyph;
18061 enum glyph_row_area area = it->area;
18062
18063 xassert (it->glyph_row);
18064
18065 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18066 if (glyph < it->glyph_row->glyphs[area + 1])
18067 {
18068 glyph->charpos = CHARPOS (it->position);
18069 glyph->object = it->object;
18070 glyph->pixel_width = it->pixel_width;
18071 glyph->ascent = it->ascent;
18072 glyph->descent = it->descent;
18073 glyph->voffset = it->voffset;
18074 glyph->type = COMPOSITE_GLYPH;
18075 glyph->multibyte_p = it->multibyte_p;
18076 glyph->left_box_line_p = it->start_of_box_run_p;
18077 glyph->right_box_line_p = it->end_of_box_run_p;
18078 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18079 || it->phys_descent > it->descent);
18080 glyph->padding_p = 0;
18081 glyph->glyph_not_available_p = 0;
18082 glyph->face_id = it->face_id;
18083 glyph->u.cmp_id = it->cmp_id;
18084 glyph->font_type = FONT_TYPE_UNKNOWN;
18085 ++it->glyph_row->used[area];
18086 }
18087 }
18088
18089
18090 /* Change IT->ascent and IT->height according to the setting of
18091 IT->voffset. */
18092
18093 static INLINE void
18094 take_vertical_position_into_account (it)
18095 struct it *it;
18096 {
18097 if (it->voffset)
18098 {
18099 if (it->voffset < 0)
18100 /* Increase the ascent so that we can display the text higher
18101 in the line. */
18102 it->ascent += abs (it->voffset);
18103 else
18104 /* Increase the descent so that we can display the text lower
18105 in the line. */
18106 it->descent += it->voffset;
18107 }
18108 }
18109
18110
18111 /* Produce glyphs/get display metrics for the image IT is loaded with.
18112 See the description of struct display_iterator in dispextern.h for
18113 an overview of struct display_iterator. */
18114
18115 static void
18116 produce_image_glyph (it)
18117 struct it *it;
18118 {
18119 struct image *img;
18120 struct face *face;
18121 int face_ascent, glyph_ascent;
18122
18123 xassert (it->what == IT_IMAGE);
18124
18125 face = FACE_FROM_ID (it->f, it->face_id);
18126 xassert (face);
18127 /* Make sure X resources of the face is loaded. */
18128 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18129
18130 if (it->image_id < 0)
18131 {
18132 /* Fringe bitmap. */
18133 it->ascent = it->phys_ascent = 0;
18134 it->descent = it->phys_descent = 0;
18135 it->pixel_width = 0;
18136 it->nglyphs = 0;
18137 return;
18138 }
18139
18140 img = IMAGE_FROM_ID (it->f, it->image_id);
18141 xassert (img);
18142 /* Make sure X resources of the image is loaded. */
18143 prepare_image_for_display (it->f, img);
18144
18145 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face);
18146 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
18147 it->pixel_width = img->width + 2 * img->hmargin;
18148
18149 /* It's quite possible for images to have an ascent greater than
18150 their height, so don't get confused in that case. */
18151 if (it->descent < 0)
18152 it->descent = 0;
18153
18154 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18155 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18156 if (face_ascent > it->ascent)
18157 it->ascent = it->phys_ascent = face_ascent;
18158
18159 it->nglyphs = 1;
18160
18161 if (face->box != FACE_NO_BOX)
18162 {
18163 if (face->box_line_width > 0)
18164 {
18165 it->ascent += face->box_line_width;
18166 it->descent += face->box_line_width;
18167 }
18168
18169 if (it->start_of_box_run_p)
18170 it->pixel_width += abs (face->box_line_width);
18171 if (it->end_of_box_run_p)
18172 it->pixel_width += abs (face->box_line_width);
18173 }
18174
18175 take_vertical_position_into_account (it);
18176
18177 if (it->glyph_row)
18178 {
18179 struct glyph *glyph;
18180 enum glyph_row_area area = it->area;
18181
18182 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18183 if (glyph < it->glyph_row->glyphs[area + 1])
18184 {
18185 glyph->charpos = CHARPOS (it->position);
18186 glyph->object = it->object;
18187 glyph->pixel_width = it->pixel_width;
18188 glyph->ascent = glyph_ascent;
18189 glyph->descent = it->descent;
18190 glyph->voffset = it->voffset;
18191 glyph->type = IMAGE_GLYPH;
18192 glyph->multibyte_p = it->multibyte_p;
18193 glyph->left_box_line_p = it->start_of_box_run_p;
18194 glyph->right_box_line_p = it->end_of_box_run_p;
18195 glyph->overlaps_vertically_p = 0;
18196 glyph->padding_p = 0;
18197 glyph->glyph_not_available_p = 0;
18198 glyph->face_id = it->face_id;
18199 glyph->u.img_id = img->id;
18200 glyph->font_type = FONT_TYPE_UNKNOWN;
18201 ++it->glyph_row->used[area];
18202 }
18203 }
18204 }
18205
18206
18207 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18208 of the glyph, WIDTH and HEIGHT are the width and height of the
18209 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18210
18211 static void
18212 append_stretch_glyph (it, object, width, height, ascent)
18213 struct it *it;
18214 Lisp_Object object;
18215 int width, height;
18216 int ascent;
18217 {
18218 struct glyph *glyph;
18219 enum glyph_row_area area = it->area;
18220
18221 xassert (ascent >= 0 && ascent <= height);
18222
18223 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18224 if (glyph < it->glyph_row->glyphs[area + 1])
18225 {
18226 glyph->charpos = CHARPOS (it->position);
18227 glyph->object = object;
18228 glyph->pixel_width = width;
18229 glyph->ascent = ascent;
18230 glyph->descent = height - ascent;
18231 glyph->voffset = it->voffset;
18232 glyph->type = STRETCH_GLYPH;
18233 glyph->multibyte_p = it->multibyte_p;
18234 glyph->left_box_line_p = it->start_of_box_run_p;
18235 glyph->right_box_line_p = it->end_of_box_run_p;
18236 glyph->overlaps_vertically_p = 0;
18237 glyph->padding_p = 0;
18238 glyph->glyph_not_available_p = 0;
18239 glyph->face_id = it->face_id;
18240 glyph->u.stretch.ascent = ascent;
18241 glyph->u.stretch.height = height;
18242 glyph->font_type = FONT_TYPE_UNKNOWN;
18243 ++it->glyph_row->used[area];
18244 }
18245 }
18246
18247
18248 /* Produce a stretch glyph for iterator IT. IT->object is the value
18249 of the glyph property displayed. The value must be a list
18250 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18251 being recognized:
18252
18253 1. `:width WIDTH' specifies that the space should be WIDTH *
18254 canonical char width wide. WIDTH may be an integer or floating
18255 point number.
18256
18257 2. `:relative-width FACTOR' specifies that the width of the stretch
18258 should be computed from the width of the first character having the
18259 `glyph' property, and should be FACTOR times that width.
18260
18261 3. `:align-to HPOS' specifies that the space should be wide enough
18262 to reach HPOS, a value in canonical character units.
18263
18264 Exactly one of the above pairs must be present.
18265
18266 4. `:height HEIGHT' specifies that the height of the stretch produced
18267 should be HEIGHT, measured in canonical character units.
18268
18269 5. `:relative-height FACTOR' specifies that the height of the
18270 stretch should be FACTOR times the height of the characters having
18271 the glyph property.
18272
18273 Either none or exactly one of 4 or 5 must be present.
18274
18275 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18276 of the stretch should be used for the ascent of the stretch.
18277 ASCENT must be in the range 0 <= ASCENT <= 100. */
18278
18279 static void
18280 produce_stretch_glyph (it)
18281 struct it *it;
18282 {
18283 /* (space :width WIDTH :height HEIGHT ...) */
18284 Lisp_Object prop, plist;
18285 int width = 0, height = 0, align_to = -1;
18286 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18287 int ascent = 0;
18288 double tem;
18289 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18290 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18291
18292 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18293
18294 /* List should start with `space'. */
18295 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18296 plist = XCDR (it->object);
18297
18298 /* Compute the width of the stretch. */
18299 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18300 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18301 {
18302 /* Absolute width `:width WIDTH' specified and valid. */
18303 zero_width_ok_p = 1;
18304 width = (int)tem;
18305 }
18306 else if (prop = Fplist_get (plist, QCrelative_width),
18307 NUMVAL (prop) > 0)
18308 {
18309 /* Relative width `:relative-width FACTOR' specified and valid.
18310 Compute the width of the characters having the `glyph'
18311 property. */
18312 struct it it2;
18313 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18314
18315 it2 = *it;
18316 if (it->multibyte_p)
18317 {
18318 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18319 - IT_BYTEPOS (*it));
18320 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18321 }
18322 else
18323 it2.c = *p, it2.len = 1;
18324
18325 it2.glyph_row = NULL;
18326 it2.what = IT_CHARACTER;
18327 x_produce_glyphs (&it2);
18328 width = NUMVAL (prop) * it2.pixel_width;
18329 }
18330 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18331 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18332 {
18333 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18334 align_to = (align_to < 0
18335 ? 0
18336 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18337 else if (align_to < 0)
18338 align_to = window_box_left_offset (it->w, TEXT_AREA);
18339 width = max (0, (int)tem + align_to - it->current_x);
18340 zero_width_ok_p = 1;
18341 }
18342 else
18343 /* Nothing specified -> width defaults to canonical char width. */
18344 width = FRAME_COLUMN_WIDTH (it->f);
18345
18346 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18347 width = 1;
18348
18349 /* Compute height. */
18350 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18351 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18352 {
18353 height = (int)tem;
18354 zero_height_ok_p = 1;
18355 }
18356 else if (prop = Fplist_get (plist, QCrelative_height),
18357 NUMVAL (prop) > 0)
18358 height = FONT_HEIGHT (font) * NUMVAL (prop);
18359 else
18360 height = FONT_HEIGHT (font);
18361
18362 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18363 height = 1;
18364
18365 /* Compute percentage of height used for ascent. If
18366 `:ascent ASCENT' is present and valid, use that. Otherwise,
18367 derive the ascent from the font in use. */
18368 if (prop = Fplist_get (plist, QCascent),
18369 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18370 ascent = height * NUMVAL (prop) / 100.0;
18371 else if (!NILP (prop)
18372 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18373 ascent = min (max (0, (int)tem), height);
18374 else
18375 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18376
18377 if (width > 0 && height > 0 && it->glyph_row)
18378 {
18379 Lisp_Object object = it->stack[it->sp - 1].string;
18380 if (!STRINGP (object))
18381 object = it->w->buffer;
18382 append_stretch_glyph (it, object, width, height, ascent);
18383 }
18384
18385 it->pixel_width = width;
18386 it->ascent = it->phys_ascent = ascent;
18387 it->descent = it->phys_descent = height - it->ascent;
18388 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18389
18390 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18391 {
18392 if (face->box_line_width > 0)
18393 {
18394 it->ascent += face->box_line_width;
18395 it->descent += face->box_line_width;
18396 }
18397
18398 if (it->start_of_box_run_p)
18399 it->pixel_width += abs (face->box_line_width);
18400 if (it->end_of_box_run_p)
18401 it->pixel_width += abs (face->box_line_width);
18402 }
18403
18404 take_vertical_position_into_account (it);
18405 }
18406
18407 /* RIF:
18408 Produce glyphs/get display metrics for the display element IT is
18409 loaded with. See the description of struct display_iterator in
18410 dispextern.h for an overview of struct display_iterator. */
18411
18412 void
18413 x_produce_glyphs (it)
18414 struct it *it;
18415 {
18416 it->glyph_not_available_p = 0;
18417
18418 if (it->what == IT_CHARACTER)
18419 {
18420 XChar2b char2b;
18421 XFontStruct *font;
18422 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18423 XCharStruct *pcm;
18424 int font_not_found_p;
18425 struct font_info *font_info;
18426 int boff; /* baseline offset */
18427 /* We may change it->multibyte_p upon unibyte<->multibyte
18428 conversion. So, save the current value now and restore it
18429 later.
18430
18431 Note: It seems that we don't have to record multibyte_p in
18432 struct glyph because the character code itself tells if or
18433 not the character is multibyte. Thus, in the future, we must
18434 consider eliminating the field `multibyte_p' in the struct
18435 glyph. */
18436 int saved_multibyte_p = it->multibyte_p;
18437
18438 /* Maybe translate single-byte characters to multibyte, or the
18439 other way. */
18440 it->char_to_display = it->c;
18441 if (!ASCII_BYTE_P (it->c))
18442 {
18443 if (unibyte_display_via_language_environment
18444 && SINGLE_BYTE_CHAR_P (it->c)
18445 && (it->c >= 0240
18446 || !NILP (Vnonascii_translation_table)))
18447 {
18448 it->char_to_display = unibyte_char_to_multibyte (it->c);
18449 it->multibyte_p = 1;
18450 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18451 face = FACE_FROM_ID (it->f, it->face_id);
18452 }
18453 else if (!SINGLE_BYTE_CHAR_P (it->c)
18454 && !it->multibyte_p)
18455 {
18456 it->multibyte_p = 1;
18457 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18458 face = FACE_FROM_ID (it->f, it->face_id);
18459 }
18460 }
18461
18462 /* Get font to use. Encode IT->char_to_display. */
18463 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18464 &char2b, it->multibyte_p, 0);
18465 font = face->font;
18466
18467 /* When no suitable font found, use the default font. */
18468 font_not_found_p = font == NULL;
18469 if (font_not_found_p)
18470 {
18471 font = FRAME_FONT (it->f);
18472 boff = FRAME_BASELINE_OFFSET (it->f);
18473 font_info = NULL;
18474 }
18475 else
18476 {
18477 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18478 boff = font_info->baseline_offset;
18479 if (font_info->vertical_centering)
18480 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18481 }
18482
18483 if (it->char_to_display >= ' '
18484 && (!it->multibyte_p || it->char_to_display < 128))
18485 {
18486 /* Either unibyte or ASCII. */
18487 int stretched_p;
18488
18489 it->nglyphs = 1;
18490
18491 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
18492 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18493 it->ascent = FONT_BASE (font) + boff;
18494 it->descent = FONT_DESCENT (font) - boff;
18495
18496 if (pcm)
18497 {
18498 it->phys_ascent = pcm->ascent + boff;
18499 it->phys_descent = pcm->descent - boff;
18500 it->pixel_width = pcm->width;
18501 }
18502 else
18503 {
18504 it->glyph_not_available_p = 1;
18505 it->phys_ascent = FONT_BASE (font) + boff;
18506 it->phys_descent = FONT_DESCENT (font) - boff;
18507 it->pixel_width = FONT_WIDTH (font);
18508 }
18509
18510 /* If this is a space inside a region of text with
18511 `space-width' property, change its width. */
18512 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18513 if (stretched_p)
18514 it->pixel_width *= XFLOATINT (it->space_width);
18515
18516 /* If face has a box, add the box thickness to the character
18517 height. If character has a box line to the left and/or
18518 right, add the box line width to the character's width. */
18519 if (face->box != FACE_NO_BOX)
18520 {
18521 int thick = face->box_line_width;
18522
18523 if (thick > 0)
18524 {
18525 it->ascent += thick;
18526 it->descent += thick;
18527 }
18528 else
18529 thick = -thick;
18530
18531 if (it->start_of_box_run_p)
18532 it->pixel_width += thick;
18533 if (it->end_of_box_run_p)
18534 it->pixel_width += thick;
18535 }
18536
18537 /* If face has an overline, add the height of the overline
18538 (1 pixel) and a 1 pixel margin to the character height. */
18539 if (face->overline_p)
18540 it->ascent += 2;
18541
18542 take_vertical_position_into_account (it);
18543
18544 /* If we have to actually produce glyphs, do it. */
18545 if (it->glyph_row)
18546 {
18547 if (stretched_p)
18548 {
18549 /* Translate a space with a `space-width' property
18550 into a stretch glyph. */
18551 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18552 / FONT_HEIGHT (font));
18553 append_stretch_glyph (it, it->object, it->pixel_width,
18554 it->ascent + it->descent, ascent);
18555 }
18556 else
18557 append_glyph (it);
18558
18559 /* If characters with lbearing or rbearing are displayed
18560 in this line, record that fact in a flag of the
18561 glyph row. This is used to optimize X output code. */
18562 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18563 it->glyph_row->contains_overlapping_glyphs_p = 1;
18564 }
18565 }
18566 else if (it->char_to_display == '\n')
18567 {
18568 /* A newline has no width but we need the height of the line. */
18569 it->pixel_width = 0;
18570 it->nglyphs = 0;
18571 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18572 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18573
18574 if (face->box != FACE_NO_BOX
18575 && face->box_line_width > 0)
18576 {
18577 it->ascent += face->box_line_width;
18578 it->descent += face->box_line_width;
18579 }
18580 }
18581 else if (it->char_to_display == '\t')
18582 {
18583 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18584 int x = it->current_x + it->continuation_lines_width;
18585 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18586
18587 /* If the distance from the current position to the next tab
18588 stop is less than a canonical character width, use the
18589 tab stop after that. */
18590 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18591 next_tab_x += tab_width;
18592
18593 it->pixel_width = next_tab_x - x;
18594 it->nglyphs = 1;
18595 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18596 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18597
18598 if (it->glyph_row)
18599 {
18600 append_stretch_glyph (it, it->object, it->pixel_width,
18601 it->ascent + it->descent, it->ascent);
18602 }
18603 }
18604 else
18605 {
18606 /* A multi-byte character. Assume that the display width of the
18607 character is the width of the character multiplied by the
18608 width of the font. */
18609
18610 /* If we found a font, this font should give us the right
18611 metrics. If we didn't find a font, use the frame's
18612 default font and calculate the width of the character
18613 from the charset width; this is what old redisplay code
18614 did. */
18615
18616 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
18617 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18618
18619 if (font_not_found_p || !pcm)
18620 {
18621 int charset = CHAR_CHARSET (it->char_to_display);
18622
18623 it->glyph_not_available_p = 1;
18624 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18625 * CHARSET_WIDTH (charset));
18626 it->phys_ascent = FONT_BASE (font) + boff;
18627 it->phys_descent = FONT_DESCENT (font) - boff;
18628 }
18629 else
18630 {
18631 it->pixel_width = pcm->width;
18632 it->phys_ascent = pcm->ascent + boff;
18633 it->phys_descent = pcm->descent - boff;
18634 if (it->glyph_row
18635 && (pcm->lbearing < 0
18636 || pcm->rbearing > pcm->width))
18637 it->glyph_row->contains_overlapping_glyphs_p = 1;
18638 }
18639 it->nglyphs = 1;
18640 it->ascent = FONT_BASE (font) + boff;
18641 it->descent = FONT_DESCENT (font) - boff;
18642 if (face->box != FACE_NO_BOX)
18643 {
18644 int thick = face->box_line_width;
18645
18646 if (thick > 0)
18647 {
18648 it->ascent += thick;
18649 it->descent += thick;
18650 }
18651 else
18652 thick = - thick;
18653
18654 if (it->start_of_box_run_p)
18655 it->pixel_width += thick;
18656 if (it->end_of_box_run_p)
18657 it->pixel_width += thick;
18658 }
18659
18660 /* If face has an overline, add the height of the overline
18661 (1 pixel) and a 1 pixel margin to the character height. */
18662 if (face->overline_p)
18663 it->ascent += 2;
18664
18665 take_vertical_position_into_account (it);
18666
18667 if (it->glyph_row)
18668 append_glyph (it);
18669 }
18670 it->multibyte_p = saved_multibyte_p;
18671 }
18672 else if (it->what == IT_COMPOSITION)
18673 {
18674 /* Note: A composition is represented as one glyph in the
18675 glyph matrix. There are no padding glyphs. */
18676 XChar2b char2b;
18677 XFontStruct *font;
18678 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18679 XCharStruct *pcm;
18680 int font_not_found_p;
18681 struct font_info *font_info;
18682 int boff; /* baseline offset */
18683 struct composition *cmp = composition_table[it->cmp_id];
18684
18685 /* Maybe translate single-byte characters to multibyte. */
18686 it->char_to_display = it->c;
18687 if (unibyte_display_via_language_environment
18688 && SINGLE_BYTE_CHAR_P (it->c)
18689 && (it->c >= 0240
18690 || (it->c >= 0200
18691 && !NILP (Vnonascii_translation_table))))
18692 {
18693 it->char_to_display = unibyte_char_to_multibyte (it->c);
18694 }
18695
18696 /* Get face and font to use. Encode IT->char_to_display. */
18697 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18698 face = FACE_FROM_ID (it->f, it->face_id);
18699 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18700 &char2b, it->multibyte_p, 0);
18701 font = face->font;
18702
18703 /* When no suitable font found, use the default font. */
18704 font_not_found_p = font == NULL;
18705 if (font_not_found_p)
18706 {
18707 font = FRAME_FONT (it->f);
18708 boff = FRAME_BASELINE_OFFSET (it->f);
18709 font_info = NULL;
18710 }
18711 else
18712 {
18713 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18714 boff = font_info->baseline_offset;
18715 if (font_info->vertical_centering)
18716 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18717 }
18718
18719 /* There are no padding glyphs, so there is only one glyph to
18720 produce for the composition. Important is that pixel_width,
18721 ascent and descent are the values of what is drawn by
18722 draw_glyphs (i.e. the values of the overall glyphs composed). */
18723 it->nglyphs = 1;
18724
18725 /* If we have not yet calculated pixel size data of glyphs of
18726 the composition for the current face font, calculate them
18727 now. Theoretically, we have to check all fonts for the
18728 glyphs, but that requires much time and memory space. So,
18729 here we check only the font of the first glyph. This leads
18730 to incorrect display very rarely, and C-l (recenter) can
18731 correct the display anyway. */
18732 if (cmp->font != (void *) font)
18733 {
18734 /* Ascent and descent of the font of the first character of
18735 this composition (adjusted by baseline offset). Ascent
18736 and descent of overall glyphs should not be less than
18737 them respectively. */
18738 int font_ascent = FONT_BASE (font) + boff;
18739 int font_descent = FONT_DESCENT (font) - boff;
18740 /* Bounding box of the overall glyphs. */
18741 int leftmost, rightmost, lowest, highest;
18742 int i, width, ascent, descent;
18743
18744 cmp->font = (void *) font;
18745
18746 /* Initialize the bounding box. */
18747 if (font_info
18748 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
18749 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18750 {
18751 width = pcm->width;
18752 ascent = pcm->ascent;
18753 descent = pcm->descent;
18754 }
18755 else
18756 {
18757 width = FONT_WIDTH (font);
18758 ascent = FONT_BASE (font);
18759 descent = FONT_DESCENT (font);
18760 }
18761
18762 rightmost = width;
18763 lowest = - descent + boff;
18764 highest = ascent + boff;
18765 leftmost = 0;
18766
18767 if (font_info
18768 && font_info->default_ascent
18769 && CHAR_TABLE_P (Vuse_default_ascent)
18770 && !NILP (Faref (Vuse_default_ascent,
18771 make_number (it->char_to_display))))
18772 highest = font_info->default_ascent + boff;
18773
18774 /* Draw the first glyph at the normal position. It may be
18775 shifted to right later if some other glyphs are drawn at
18776 the left. */
18777 cmp->offsets[0] = 0;
18778 cmp->offsets[1] = boff;
18779
18780 /* Set cmp->offsets for the remaining glyphs. */
18781 for (i = 1; i < cmp->glyph_len; i++)
18782 {
18783 int left, right, btm, top;
18784 int ch = COMPOSITION_GLYPH (cmp, i);
18785 int face_id = FACE_FOR_CHAR (it->f, face, ch);
18786
18787 face = FACE_FROM_ID (it->f, face_id);
18788 get_char_face_and_encoding (it->f, ch, face->id,
18789 &char2b, it->multibyte_p, 0);
18790 font = face->font;
18791 if (font == NULL)
18792 {
18793 font = FRAME_FONT (it->f);
18794 boff = FRAME_BASELINE_OFFSET (it->f);
18795 font_info = NULL;
18796 }
18797 else
18798 {
18799 font_info
18800 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18801 boff = font_info->baseline_offset;
18802 if (font_info->vertical_centering)
18803 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18804 }
18805
18806 if (font_info
18807 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
18808 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18809 {
18810 width = pcm->width;
18811 ascent = pcm->ascent;
18812 descent = pcm->descent;
18813 }
18814 else
18815 {
18816 width = FONT_WIDTH (font);
18817 ascent = 1;
18818 descent = 0;
18819 }
18820
18821 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18822 {
18823 /* Relative composition with or without
18824 alternate chars. */
18825 left = (leftmost + rightmost - width) / 2;
18826 btm = - descent + boff;
18827 if (font_info && font_info->relative_compose
18828 && (! CHAR_TABLE_P (Vignore_relative_composition)
18829 || NILP (Faref (Vignore_relative_composition,
18830 make_number (ch)))))
18831 {
18832
18833 if (- descent >= font_info->relative_compose)
18834 /* One extra pixel between two glyphs. */
18835 btm = highest + 1;
18836 else if (ascent <= 0)
18837 /* One extra pixel between two glyphs. */
18838 btm = lowest - 1 - ascent - descent;
18839 }
18840 }
18841 else
18842 {
18843 /* A composition rule is specified by an integer
18844 value that encodes global and new reference
18845 points (GREF and NREF). GREF and NREF are
18846 specified by numbers as below:
18847
18848 0---1---2 -- ascent
18849 | |
18850 | |
18851 | |
18852 9--10--11 -- center
18853 | |
18854 ---3---4---5--- baseline
18855 | |
18856 6---7---8 -- descent
18857 */
18858 int rule = COMPOSITION_RULE (cmp, i);
18859 int gref, nref, grefx, grefy, nrefx, nrefy;
18860
18861 COMPOSITION_DECODE_RULE (rule, gref, nref);
18862 grefx = gref % 3, nrefx = nref % 3;
18863 grefy = gref / 3, nrefy = nref / 3;
18864
18865 left = (leftmost
18866 + grefx * (rightmost - leftmost) / 2
18867 - nrefx * width / 2);
18868 btm = ((grefy == 0 ? highest
18869 : grefy == 1 ? 0
18870 : grefy == 2 ? lowest
18871 : (highest + lowest) / 2)
18872 - (nrefy == 0 ? ascent + descent
18873 : nrefy == 1 ? descent - boff
18874 : nrefy == 2 ? 0
18875 : (ascent + descent) / 2));
18876 }
18877
18878 cmp->offsets[i * 2] = left;
18879 cmp->offsets[i * 2 + 1] = btm + descent;
18880
18881 /* Update the bounding box of the overall glyphs. */
18882 right = left + width;
18883 top = btm + descent + ascent;
18884 if (left < leftmost)
18885 leftmost = left;
18886 if (right > rightmost)
18887 rightmost = right;
18888 if (top > highest)
18889 highest = top;
18890 if (btm < lowest)
18891 lowest = btm;
18892 }
18893
18894 /* If there are glyphs whose x-offsets are negative,
18895 shift all glyphs to the right and make all x-offsets
18896 non-negative. */
18897 if (leftmost < 0)
18898 {
18899 for (i = 0; i < cmp->glyph_len; i++)
18900 cmp->offsets[i * 2] -= leftmost;
18901 rightmost -= leftmost;
18902 }
18903
18904 cmp->pixel_width = rightmost;
18905 cmp->ascent = highest;
18906 cmp->descent = - lowest;
18907 if (cmp->ascent < font_ascent)
18908 cmp->ascent = font_ascent;
18909 if (cmp->descent < font_descent)
18910 cmp->descent = font_descent;
18911 }
18912
18913 it->pixel_width = cmp->pixel_width;
18914 it->ascent = it->phys_ascent = cmp->ascent;
18915 it->descent = it->phys_descent = cmp->descent;
18916
18917 if (face->box != FACE_NO_BOX)
18918 {
18919 int thick = face->box_line_width;
18920
18921 if (thick > 0)
18922 {
18923 it->ascent += thick;
18924 it->descent += thick;
18925 }
18926 else
18927 thick = - thick;
18928
18929 if (it->start_of_box_run_p)
18930 it->pixel_width += thick;
18931 if (it->end_of_box_run_p)
18932 it->pixel_width += thick;
18933 }
18934
18935 /* If face has an overline, add the height of the overline
18936 (1 pixel) and a 1 pixel margin to the character height. */
18937 if (face->overline_p)
18938 it->ascent += 2;
18939
18940 take_vertical_position_into_account (it);
18941
18942 if (it->glyph_row)
18943 append_composite_glyph (it);
18944 }
18945 else if (it->what == IT_IMAGE)
18946 produce_image_glyph (it);
18947 else if (it->what == IT_STRETCH)
18948 produce_stretch_glyph (it);
18949
18950 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18951 because this isn't true for images with `:ascent 100'. */
18952 xassert (it->ascent >= 0 && it->descent >= 0);
18953 if (it->area == TEXT_AREA)
18954 it->current_x += it->pixel_width;
18955
18956 it->descent += it->extra_line_spacing;
18957
18958 it->max_ascent = max (it->max_ascent, it->ascent);
18959 it->max_descent = max (it->max_descent, it->descent);
18960 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18961 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18962 }
18963
18964 /* EXPORT for RIF:
18965 Output LEN glyphs starting at START at the nominal cursor position.
18966 Advance the nominal cursor over the text. The global variable
18967 updated_window contains the window being updated, updated_row is
18968 the glyph row being updated, and updated_area is the area of that
18969 row being updated. */
18970
18971 void
18972 x_write_glyphs (start, len)
18973 struct glyph *start;
18974 int len;
18975 {
18976 int x, hpos;
18977
18978 xassert (updated_window && updated_row);
18979 BLOCK_INPUT;
18980
18981 /* Write glyphs. */
18982
18983 hpos = start - updated_row->glyphs[updated_area];
18984 x = draw_glyphs (updated_window, output_cursor.x,
18985 updated_row, updated_area,
18986 hpos, hpos + len,
18987 DRAW_NORMAL_TEXT, 0);
18988
18989 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18990 if (updated_area == TEXT_AREA
18991 && updated_window->phys_cursor_on_p
18992 && updated_window->phys_cursor.vpos == output_cursor.vpos
18993 && updated_window->phys_cursor.hpos >= hpos
18994 && updated_window->phys_cursor.hpos < hpos + len)
18995 updated_window->phys_cursor_on_p = 0;
18996
18997 UNBLOCK_INPUT;
18998
18999 /* Advance the output cursor. */
19000 output_cursor.hpos += len;
19001 output_cursor.x = x;
19002 }
19003
19004
19005 /* EXPORT for RIF:
19006 Insert LEN glyphs from START at the nominal cursor position. */
19007
19008 void
19009 x_insert_glyphs (start, len)
19010 struct glyph *start;
19011 int len;
19012 {
19013 struct frame *f;
19014 struct window *w;
19015 int line_height, shift_by_width, shifted_region_width;
19016 struct glyph_row *row;
19017 struct glyph *glyph;
19018 int frame_x, frame_y, hpos;
19019
19020 xassert (updated_window && updated_row);
19021 BLOCK_INPUT;
19022 w = updated_window;
19023 f = XFRAME (WINDOW_FRAME (w));
19024
19025 /* Get the height of the line we are in. */
19026 row = updated_row;
19027 line_height = row->height;
19028
19029 /* Get the width of the glyphs to insert. */
19030 shift_by_width = 0;
19031 for (glyph = start; glyph < start + len; ++glyph)
19032 shift_by_width += glyph->pixel_width;
19033
19034 /* Get the width of the region to shift right. */
19035 shifted_region_width = (window_box_width (w, updated_area)
19036 - output_cursor.x
19037 - shift_by_width);
19038
19039 /* Shift right. */
19040 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19041 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19042
19043 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19044 line_height, shift_by_width);
19045
19046 /* Write the glyphs. */
19047 hpos = start - row->glyphs[updated_area];
19048 draw_glyphs (w, output_cursor.x, row, updated_area,
19049 hpos, hpos + len,
19050 DRAW_NORMAL_TEXT, 0);
19051
19052 /* Advance the output cursor. */
19053 output_cursor.hpos += len;
19054 output_cursor.x += shift_by_width;
19055 UNBLOCK_INPUT;
19056 }
19057
19058
19059 /* EXPORT for RIF:
19060 Erase the current text line from the nominal cursor position
19061 (inclusive) to pixel column TO_X (exclusive). The idea is that
19062 everything from TO_X onward is already erased.
19063
19064 TO_X is a pixel position relative to updated_area of
19065 updated_window. TO_X == -1 means clear to the end of this area. */
19066
19067 void
19068 x_clear_end_of_line (to_x)
19069 int to_x;
19070 {
19071 struct frame *f;
19072 struct window *w = updated_window;
19073 int max_x, min_y, max_y;
19074 int from_x, from_y, to_y;
19075
19076 xassert (updated_window && updated_row);
19077 f = XFRAME (w->frame);
19078
19079 if (updated_row->full_width_p)
19080 max_x = WINDOW_TOTAL_WIDTH (w);
19081 else
19082 max_x = window_box_width (w, updated_area);
19083 max_y = window_text_bottom_y (w);
19084
19085 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19086 of window. For TO_X > 0, truncate to end of drawing area. */
19087 if (to_x == 0)
19088 return;
19089 else if (to_x < 0)
19090 to_x = max_x;
19091 else
19092 to_x = min (to_x, max_x);
19093
19094 to_y = min (max_y, output_cursor.y + updated_row->height);
19095
19096 /* Notice if the cursor will be cleared by this operation. */
19097 if (!updated_row->full_width_p)
19098 notice_overwritten_cursor (w, updated_area,
19099 output_cursor.x, -1,
19100 updated_row->y,
19101 MATRIX_ROW_BOTTOM_Y (updated_row));
19102
19103 from_x = output_cursor.x;
19104
19105 /* Translate to frame coordinates. */
19106 if (updated_row->full_width_p)
19107 {
19108 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19109 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19110 }
19111 else
19112 {
19113 int area_left = window_box_left (w, updated_area);
19114 from_x += area_left;
19115 to_x += area_left;
19116 }
19117
19118 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19119 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19120 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19121
19122 /* Prevent inadvertently clearing to end of the X window. */
19123 if (to_x > from_x && to_y > from_y)
19124 {
19125 BLOCK_INPUT;
19126 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
19127 to_x - from_x, to_y - from_y);
19128 UNBLOCK_INPUT;
19129 }
19130 }
19131
19132 #endif /* HAVE_WINDOW_SYSTEM */
19133
19134
19135 \f
19136 /***********************************************************************
19137 Cursor types
19138 ***********************************************************************/
19139
19140 /* Value is the internal representation of the specified cursor type
19141 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19142 of the bar cursor. */
19143
19144 static enum text_cursor_kinds
19145 get_specified_cursor_type (arg, width)
19146 Lisp_Object arg;
19147 int *width;
19148 {
19149 enum text_cursor_kinds type;
19150
19151 if (NILP (arg))
19152 return NO_CURSOR;
19153
19154 if (EQ (arg, Qbox))
19155 return FILLED_BOX_CURSOR;
19156
19157 if (EQ (arg, Qhollow))
19158 return HOLLOW_BOX_CURSOR;
19159
19160 if (EQ (arg, Qbar))
19161 {
19162 *width = 2;
19163 return BAR_CURSOR;
19164 }
19165
19166 if (CONSP (arg)
19167 && EQ (XCAR (arg), Qbar)
19168 && INTEGERP (XCDR (arg))
19169 && XINT (XCDR (arg)) >= 0)
19170 {
19171 *width = XINT (XCDR (arg));
19172 return BAR_CURSOR;
19173 }
19174
19175 if (EQ (arg, Qhbar))
19176 {
19177 *width = 2;
19178 return HBAR_CURSOR;
19179 }
19180
19181 if (CONSP (arg)
19182 && EQ (XCAR (arg), Qhbar)
19183 && INTEGERP (XCDR (arg))
19184 && XINT (XCDR (arg)) >= 0)
19185 {
19186 *width = XINT (XCDR (arg));
19187 return HBAR_CURSOR;
19188 }
19189
19190 /* Treat anything unknown as "hollow box cursor".
19191 It was bad to signal an error; people have trouble fixing
19192 .Xdefaults with Emacs, when it has something bad in it. */
19193 type = HOLLOW_BOX_CURSOR;
19194
19195 return type;
19196 }
19197
19198 /* Set the default cursor types for specified frame. */
19199 void
19200 set_frame_cursor_types (f, arg)
19201 struct frame *f;
19202 Lisp_Object arg;
19203 {
19204 int width;
19205 Lisp_Object tem;
19206
19207 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
19208 FRAME_CURSOR_WIDTH (f) = width;
19209
19210 /* By default, set up the blink-off state depending on the on-state. */
19211
19212 tem = Fassoc (arg, Vblink_cursor_alist);
19213 if (!NILP (tem))
19214 {
19215 FRAME_BLINK_OFF_CURSOR (f)
19216 = get_specified_cursor_type (XCDR (tem), &width);
19217 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
19218 }
19219 else
19220 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
19221 }
19222
19223
19224 /* Return the cursor we want to be displayed in window W. Return
19225 width of bar/hbar cursor through WIDTH arg. Return with
19226 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
19227 (i.e. if the `system caret' should track this cursor).
19228
19229 In a mini-buffer window, we want the cursor only to appear if we
19230 are reading input from this window. For the selected window, we
19231 want the cursor type given by the frame parameter or buffer local
19232 setting of cursor-type. If explicitly marked off, draw no cursor.
19233 In all other cases, we want a hollow box cursor. */
19234
19235 static enum text_cursor_kinds
19236 get_window_cursor_type (w, glyph, width, active_cursor)
19237 struct window *w;
19238 struct glyph *glyph;
19239 int *width;
19240 int *active_cursor;
19241 {
19242 struct frame *f = XFRAME (w->frame);
19243 struct buffer *b = XBUFFER (w->buffer);
19244 int cursor_type = DEFAULT_CURSOR;
19245 Lisp_Object alt_cursor;
19246 int non_selected = 0;
19247
19248 *active_cursor = 1;
19249
19250 /* Echo area */
19251 if (cursor_in_echo_area
19252 && FRAME_HAS_MINIBUF_P (f)
19253 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
19254 {
19255 if (w == XWINDOW (echo_area_window))
19256 {
19257 *width = FRAME_CURSOR_WIDTH (f);
19258 return FRAME_DESIRED_CURSOR (f);
19259 }
19260
19261 *active_cursor = 0;
19262 non_selected = 1;
19263 }
19264
19265 /* Nonselected window or nonselected frame. */
19266 else if (w != XWINDOW (f->selected_window)
19267 #ifdef HAVE_WINDOW_SYSTEM
19268 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19269 #endif
19270 )
19271 {
19272 *active_cursor = 0;
19273
19274 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19275 return NO_CURSOR;
19276
19277 non_selected = 1;
19278 }
19279
19280 /* Never display a cursor in a window in which cursor-type is nil. */
19281 if (NILP (b->cursor_type))
19282 return NO_CURSOR;
19283
19284 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19285 if (non_selected)
19286 {
19287 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19288 return get_specified_cursor_type (alt_cursor, width);
19289 }
19290
19291 /* Get the normal cursor type for this window. */
19292 if (EQ (b->cursor_type, Qt))
19293 {
19294 cursor_type = FRAME_DESIRED_CURSOR (f);
19295 *width = FRAME_CURSOR_WIDTH (f);
19296 }
19297 else
19298 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19299
19300 /* Use normal cursor if not blinked off. */
19301 if (!w->cursor_off_p)
19302 {
19303 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
19304 if (cursor_type == FILLED_BOX_CURSOR)
19305 cursor_type = HOLLOW_BOX_CURSOR;
19306 }
19307 return cursor_type;
19308 }
19309
19310 /* Cursor is blinked off, so determine how to "toggle" it. */
19311
19312 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19313 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19314 return get_specified_cursor_type (XCDR (alt_cursor), width);
19315
19316 /* Then see if frame has specified a specific blink off cursor type. */
19317 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19318 {
19319 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19320 return FRAME_BLINK_OFF_CURSOR (f);
19321 }
19322
19323 #if 0
19324 /* Some people liked having a permanently visible blinking cursor,
19325 while others had very strong opinions against it. So it was
19326 decided to remove it. KFS 2003-09-03 */
19327
19328 /* Finally perform built-in cursor blinking:
19329 filled box <-> hollow box
19330 wide [h]bar <-> narrow [h]bar
19331 narrow [h]bar <-> no cursor
19332 other type <-> no cursor */
19333
19334 if (cursor_type == FILLED_BOX_CURSOR)
19335 return HOLLOW_BOX_CURSOR;
19336
19337 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19338 {
19339 *width = 1;
19340 return cursor_type;
19341 }
19342 #endif
19343
19344 return NO_CURSOR;
19345 }
19346
19347
19348 #ifdef HAVE_WINDOW_SYSTEM
19349
19350 /* Notice when the text cursor of window W has been completely
19351 overwritten by a drawing operation that outputs glyphs in AREA
19352 starting at X0 and ending at X1 in the line starting at Y0 and
19353 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19354 the rest of the line after X0 has been written. Y coordinates
19355 are window-relative. */
19356
19357 static void
19358 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19359 struct window *w;
19360 enum glyph_row_area area;
19361 int x0, y0, x1, y1;
19362 {
19363 int cx0, cx1, cy0, cy1;
19364 struct glyph_row *row;
19365
19366 if (!w->phys_cursor_on_p)
19367 return;
19368 if (area != TEXT_AREA)
19369 return;
19370
19371 row = w->current_matrix->rows + w->phys_cursor.vpos;
19372 if (!row->displays_text_p)
19373 return;
19374
19375 if (row->cursor_in_fringe_p)
19376 {
19377 row->cursor_in_fringe_p = 0;
19378 draw_fringe_bitmap (w, row, 0);
19379 w->phys_cursor_on_p = 0;
19380 return;
19381 }
19382
19383 cx0 = w->phys_cursor.x;
19384 cx1 = cx0 + w->phys_cursor_width;
19385 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19386 return;
19387
19388 /* The cursor image will be completely removed from the
19389 screen if the output area intersects the cursor area in
19390 y-direction. When we draw in [y0 y1[, and some part of
19391 the cursor is at y < y0, that part must have been drawn
19392 before. When scrolling, the cursor is erased before
19393 actually scrolling, so we don't come here. When not
19394 scrolling, the rows above the old cursor row must have
19395 changed, and in this case these rows must have written
19396 over the cursor image.
19397
19398 Likewise if part of the cursor is below y1, with the
19399 exception of the cursor being in the first blank row at
19400 the buffer and window end because update_text_area
19401 doesn't draw that row. (Except when it does, but
19402 that's handled in update_text_area.) */
19403
19404 cy0 = w->phys_cursor.y;
19405 cy1 = cy0 + w->phys_cursor_height;
19406 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19407 return;
19408
19409 w->phys_cursor_on_p = 0;
19410 }
19411
19412 #endif /* HAVE_WINDOW_SYSTEM */
19413
19414 \f
19415 /************************************************************************
19416 Mouse Face
19417 ************************************************************************/
19418
19419 #ifdef HAVE_WINDOW_SYSTEM
19420
19421 /* EXPORT for RIF:
19422 Fix the display of area AREA of overlapping row ROW in window W. */
19423
19424 void
19425 x_fix_overlapping_area (w, row, area)
19426 struct window *w;
19427 struct glyph_row *row;
19428 enum glyph_row_area area;
19429 {
19430 int i, x;
19431
19432 BLOCK_INPUT;
19433
19434 x = 0;
19435 for (i = 0; i < row->used[area];)
19436 {
19437 if (row->glyphs[area][i].overlaps_vertically_p)
19438 {
19439 int start = i, start_x = x;
19440
19441 do
19442 {
19443 x += row->glyphs[area][i].pixel_width;
19444 ++i;
19445 }
19446 while (i < row->used[area]
19447 && row->glyphs[area][i].overlaps_vertically_p);
19448
19449 draw_glyphs (w, start_x, row, area,
19450 start, i,
19451 DRAW_NORMAL_TEXT, 1);
19452 }
19453 else
19454 {
19455 x += row->glyphs[area][i].pixel_width;
19456 ++i;
19457 }
19458 }
19459
19460 UNBLOCK_INPUT;
19461 }
19462
19463
19464 /* EXPORT:
19465 Draw the cursor glyph of window W in glyph row ROW. See the
19466 comment of draw_glyphs for the meaning of HL. */
19467
19468 void
19469 draw_phys_cursor_glyph (w, row, hl)
19470 struct window *w;
19471 struct glyph_row *row;
19472 enum draw_glyphs_face hl;
19473 {
19474 /* If cursor hpos is out of bounds, don't draw garbage. This can
19475 happen in mini-buffer windows when switching between echo area
19476 glyphs and mini-buffer. */
19477 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19478 {
19479 int on_p = w->phys_cursor_on_p;
19480 int x1;
19481 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19482 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19483 hl, 0);
19484 w->phys_cursor_on_p = on_p;
19485
19486 if (hl == DRAW_CURSOR)
19487 w->phys_cursor_width = x1 - w->phys_cursor.x;
19488 /* When we erase the cursor, and ROW is overlapped by other
19489 rows, make sure that these overlapping parts of other rows
19490 are redrawn. */
19491 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19492 {
19493 if (row > w->current_matrix->rows
19494 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19495 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19496
19497 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19498 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19499 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19500 }
19501 }
19502 }
19503
19504
19505 /* EXPORT:
19506 Erase the image of a cursor of window W from the screen. */
19507
19508 void
19509 erase_phys_cursor (w)
19510 struct window *w;
19511 {
19512 struct frame *f = XFRAME (w->frame);
19513 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19514 int hpos = w->phys_cursor.hpos;
19515 int vpos = w->phys_cursor.vpos;
19516 int mouse_face_here_p = 0;
19517 struct glyph_matrix *active_glyphs = w->current_matrix;
19518 struct glyph_row *cursor_row;
19519 struct glyph *cursor_glyph;
19520 enum draw_glyphs_face hl;
19521
19522 /* No cursor displayed or row invalidated => nothing to do on the
19523 screen. */
19524 if (w->phys_cursor_type == NO_CURSOR)
19525 goto mark_cursor_off;
19526
19527 /* VPOS >= active_glyphs->nrows means that window has been resized.
19528 Don't bother to erase the cursor. */
19529 if (vpos >= active_glyphs->nrows)
19530 goto mark_cursor_off;
19531
19532 /* If row containing cursor is marked invalid, there is nothing we
19533 can do. */
19534 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19535 if (!cursor_row->enabled_p)
19536 goto mark_cursor_off;
19537
19538 /* If row is completely invisible, don't attempt to delete a cursor which
19539 isn't there. This can happen if cursor is at top of a window, and
19540 we switch to a buffer with a header line in that window. */
19541 if (cursor_row->visible_height <= 0)
19542 goto mark_cursor_off;
19543
19544 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19545 if (cursor_row->cursor_in_fringe_p)
19546 {
19547 cursor_row->cursor_in_fringe_p = 0;
19548 draw_fringe_bitmap (w, cursor_row, 0);
19549 goto mark_cursor_off;
19550 }
19551
19552 /* This can happen when the new row is shorter than the old one.
19553 In this case, either draw_glyphs or clear_end_of_line
19554 should have cleared the cursor. Note that we wouldn't be
19555 able to erase the cursor in this case because we don't have a
19556 cursor glyph at hand. */
19557 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19558 goto mark_cursor_off;
19559
19560 /* If the cursor is in the mouse face area, redisplay that when
19561 we clear the cursor. */
19562 if (! NILP (dpyinfo->mouse_face_window)
19563 && w == XWINDOW (dpyinfo->mouse_face_window)
19564 && (vpos > dpyinfo->mouse_face_beg_row
19565 || (vpos == dpyinfo->mouse_face_beg_row
19566 && hpos >= dpyinfo->mouse_face_beg_col))
19567 && (vpos < dpyinfo->mouse_face_end_row
19568 || (vpos == dpyinfo->mouse_face_end_row
19569 && hpos < dpyinfo->mouse_face_end_col))
19570 /* Don't redraw the cursor's spot in mouse face if it is at the
19571 end of a line (on a newline). The cursor appears there, but
19572 mouse highlighting does not. */
19573 && cursor_row->used[TEXT_AREA] > hpos)
19574 mouse_face_here_p = 1;
19575
19576 /* Maybe clear the display under the cursor. */
19577 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19578 {
19579 int x, y;
19580 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19581
19582 cursor_glyph = get_phys_cursor_glyph (w);
19583 if (cursor_glyph == NULL)
19584 goto mark_cursor_off;
19585
19586 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19587 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19588
19589 FRAME_RIF (f)->clear_frame_area (f, x, y,
19590 cursor_glyph->pixel_width, cursor_row->visible_height);
19591 }
19592
19593 /* Erase the cursor by redrawing the character underneath it. */
19594 if (mouse_face_here_p)
19595 hl = DRAW_MOUSE_FACE;
19596 else
19597 hl = DRAW_NORMAL_TEXT;
19598 draw_phys_cursor_glyph (w, cursor_row, hl);
19599
19600 mark_cursor_off:
19601 w->phys_cursor_on_p = 0;
19602 w->phys_cursor_type = NO_CURSOR;
19603 }
19604
19605
19606 /* EXPORT:
19607 Display or clear cursor of window W. If ON is zero, clear the
19608 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19609 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19610
19611 void
19612 display_and_set_cursor (w, on, hpos, vpos, x, y)
19613 struct window *w;
19614 int on, hpos, vpos, x, y;
19615 {
19616 struct frame *f = XFRAME (w->frame);
19617 int new_cursor_type;
19618 int new_cursor_width;
19619 int active_cursor;
19620 struct glyph_row *glyph_row;
19621 struct glyph *glyph;
19622
19623 /* This is pointless on invisible frames, and dangerous on garbaged
19624 windows and frames; in the latter case, the frame or window may
19625 be in the midst of changing its size, and x and y may be off the
19626 window. */
19627 if (! FRAME_VISIBLE_P (f)
19628 || FRAME_GARBAGED_P (f)
19629 || vpos >= w->current_matrix->nrows
19630 || hpos >= w->current_matrix->matrix_w)
19631 return;
19632
19633 /* If cursor is off and we want it off, return quickly. */
19634 if (!on && !w->phys_cursor_on_p)
19635 return;
19636
19637 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
19638 /* If cursor row is not enabled, we don't really know where to
19639 display the cursor. */
19640 if (!glyph_row->enabled_p)
19641 {
19642 w->phys_cursor_on_p = 0;
19643 return;
19644 }
19645
19646 glyph = NULL;
19647 if (!glyph_row->exact_window_width_line_p
19648 || hpos < glyph_row->used[TEXT_AREA])
19649 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
19650
19651 xassert (interrupt_input_blocked);
19652
19653 /* Set new_cursor_type to the cursor we want to be displayed. */
19654 new_cursor_type = get_window_cursor_type (w, glyph,
19655 &new_cursor_width, &active_cursor);
19656
19657 /* If cursor is currently being shown and we don't want it to be or
19658 it is in the wrong place, or the cursor type is not what we want,
19659 erase it. */
19660 if (w->phys_cursor_on_p
19661 && (!on
19662 || w->phys_cursor.x != x
19663 || w->phys_cursor.y != y
19664 || new_cursor_type != w->phys_cursor_type
19665 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19666 && new_cursor_width != w->phys_cursor_width)))
19667 erase_phys_cursor (w);
19668
19669 /* Don't check phys_cursor_on_p here because that flag is only set
19670 to zero in some cases where we know that the cursor has been
19671 completely erased, to avoid the extra work of erasing the cursor
19672 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19673 still not be visible, or it has only been partly erased. */
19674 if (on)
19675 {
19676 w->phys_cursor_ascent = glyph_row->ascent;
19677 w->phys_cursor_height = glyph_row->height;
19678
19679 /* Set phys_cursor_.* before x_draw_.* is called because some
19680 of them may need the information. */
19681 w->phys_cursor.x = x;
19682 w->phys_cursor.y = glyph_row->y;
19683 w->phys_cursor.hpos = hpos;
19684 w->phys_cursor.vpos = vpos;
19685 }
19686
19687 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
19688 new_cursor_type, new_cursor_width,
19689 on, active_cursor);
19690 }
19691
19692
19693 /* Switch the display of W's cursor on or off, according to the value
19694 of ON. */
19695
19696 static void
19697 update_window_cursor (w, on)
19698 struct window *w;
19699 int on;
19700 {
19701 /* Don't update cursor in windows whose frame is in the process
19702 of being deleted. */
19703 if (w->current_matrix)
19704 {
19705 BLOCK_INPUT;
19706 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19707 w->phys_cursor.x, w->phys_cursor.y);
19708 UNBLOCK_INPUT;
19709 }
19710 }
19711
19712
19713 /* Call update_window_cursor with parameter ON_P on all leaf windows
19714 in the window tree rooted at W. */
19715
19716 static void
19717 update_cursor_in_window_tree (w, on_p)
19718 struct window *w;
19719 int on_p;
19720 {
19721 while (w)
19722 {
19723 if (!NILP (w->hchild))
19724 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19725 else if (!NILP (w->vchild))
19726 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19727 else
19728 update_window_cursor (w, on_p);
19729
19730 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19731 }
19732 }
19733
19734
19735 /* EXPORT:
19736 Display the cursor on window W, or clear it, according to ON_P.
19737 Don't change the cursor's position. */
19738
19739 void
19740 x_update_cursor (f, on_p)
19741 struct frame *f;
19742 int on_p;
19743 {
19744 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19745 }
19746
19747
19748 /* EXPORT:
19749 Clear the cursor of window W to background color, and mark the
19750 cursor as not shown. This is used when the text where the cursor
19751 is is about to be rewritten. */
19752
19753 void
19754 x_clear_cursor (w)
19755 struct window *w;
19756 {
19757 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19758 update_window_cursor (w, 0);
19759 }
19760
19761
19762 /* EXPORT:
19763 Display the active region described by mouse_face_* according to DRAW. */
19764
19765 void
19766 show_mouse_face (dpyinfo, draw)
19767 Display_Info *dpyinfo;
19768 enum draw_glyphs_face draw;
19769 {
19770 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19771 struct frame *f = XFRAME (WINDOW_FRAME (w));
19772
19773 if (/* If window is in the process of being destroyed, don't bother
19774 to do anything. */
19775 w->current_matrix != NULL
19776 /* Don't update mouse highlight if hidden */
19777 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19778 /* Recognize when we are called to operate on rows that don't exist
19779 anymore. This can happen when a window is split. */
19780 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19781 {
19782 int phys_cursor_on_p = w->phys_cursor_on_p;
19783 struct glyph_row *row, *first, *last;
19784
19785 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19786 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19787
19788 for (row = first; row <= last && row->enabled_p; ++row)
19789 {
19790 int start_hpos, end_hpos, start_x;
19791
19792 /* For all but the first row, the highlight starts at column 0. */
19793 if (row == first)
19794 {
19795 start_hpos = dpyinfo->mouse_face_beg_col;
19796 start_x = dpyinfo->mouse_face_beg_x;
19797 }
19798 else
19799 {
19800 start_hpos = 0;
19801 start_x = 0;
19802 }
19803
19804 if (row == last)
19805 end_hpos = dpyinfo->mouse_face_end_col;
19806 else
19807 end_hpos = row->used[TEXT_AREA];
19808
19809 if (end_hpos > start_hpos)
19810 {
19811 draw_glyphs (w, start_x, row, TEXT_AREA,
19812 start_hpos, end_hpos,
19813 draw, 0);
19814
19815 row->mouse_face_p
19816 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19817 }
19818 }
19819
19820 /* When we've written over the cursor, arrange for it to
19821 be displayed again. */
19822 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19823 {
19824 BLOCK_INPUT;
19825 display_and_set_cursor (w, 1,
19826 w->phys_cursor.hpos, w->phys_cursor.vpos,
19827 w->phys_cursor.x, w->phys_cursor.y);
19828 UNBLOCK_INPUT;
19829 }
19830 }
19831
19832 /* Change the mouse cursor. */
19833 if (draw == DRAW_NORMAL_TEXT)
19834 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19835 else if (draw == DRAW_MOUSE_FACE)
19836 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19837 else
19838 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19839 }
19840
19841 /* EXPORT:
19842 Clear out the mouse-highlighted active region.
19843 Redraw it un-highlighted first. Value is non-zero if mouse
19844 face was actually drawn unhighlighted. */
19845
19846 int
19847 clear_mouse_face (dpyinfo)
19848 Display_Info *dpyinfo;
19849 {
19850 int cleared = 0;
19851
19852 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
19853 {
19854 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19855 cleared = 1;
19856 }
19857
19858 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19859 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19860 dpyinfo->mouse_face_window = Qnil;
19861 dpyinfo->mouse_face_overlay = Qnil;
19862 return cleared;
19863 }
19864
19865
19866 /* EXPORT:
19867 Non-zero if physical cursor of window W is within mouse face. */
19868
19869 int
19870 cursor_in_mouse_face_p (w)
19871 struct window *w;
19872 {
19873 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19874 int in_mouse_face = 0;
19875
19876 if (WINDOWP (dpyinfo->mouse_face_window)
19877 && XWINDOW (dpyinfo->mouse_face_window) == w)
19878 {
19879 int hpos = w->phys_cursor.hpos;
19880 int vpos = w->phys_cursor.vpos;
19881
19882 if (vpos >= dpyinfo->mouse_face_beg_row
19883 && vpos <= dpyinfo->mouse_face_end_row
19884 && (vpos > dpyinfo->mouse_face_beg_row
19885 || hpos >= dpyinfo->mouse_face_beg_col)
19886 && (vpos < dpyinfo->mouse_face_end_row
19887 || hpos < dpyinfo->mouse_face_end_col
19888 || dpyinfo->mouse_face_past_end))
19889 in_mouse_face = 1;
19890 }
19891
19892 return in_mouse_face;
19893 }
19894
19895
19896
19897 \f
19898 /* Find the glyph matrix position of buffer position CHARPOS in window
19899 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19900 current glyphs must be up to date. If CHARPOS is above window
19901 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19902 of last line in W. In the row containing CHARPOS, stop before glyphs
19903 having STOP as object. */
19904
19905 #if 1 /* This is a version of fast_find_position that's more correct
19906 in the presence of hscrolling, for example. I didn't install
19907 it right away because the problem fixed is minor, it failed
19908 in 20.x as well, and I think it's too risky to install
19909 so near the release of 21.1. 2001-09-25 gerd. */
19910
19911 static int
19912 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19913 struct window *w;
19914 int charpos;
19915 int *hpos, *vpos, *x, *y;
19916 Lisp_Object stop;
19917 {
19918 struct glyph_row *row, *first;
19919 struct glyph *glyph, *end;
19920 int past_end = 0;
19921
19922 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19923 row = row_containing_pos (w, charpos, first, NULL, 0);
19924 if (row == NULL)
19925 {
19926 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19927 {
19928 *x = *y = *hpos = *vpos = 0;
19929 return 1;
19930 }
19931 else
19932 {
19933 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19934 past_end = 1;
19935 }
19936 }
19937
19938 *x = row->x;
19939 *y = row->y;
19940 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19941
19942 glyph = row->glyphs[TEXT_AREA];
19943 end = glyph + row->used[TEXT_AREA];
19944
19945 /* Skip over glyphs not having an object at the start of the row.
19946 These are special glyphs like truncation marks on terminal
19947 frames. */
19948 if (row->displays_text_p)
19949 while (glyph < end
19950 && INTEGERP (glyph->object)
19951 && !EQ (stop, glyph->object)
19952 && glyph->charpos < 0)
19953 {
19954 *x += glyph->pixel_width;
19955 ++glyph;
19956 }
19957
19958 while (glyph < end
19959 && !INTEGERP (glyph->object)
19960 && !EQ (stop, glyph->object)
19961 && (!BUFFERP (glyph->object)
19962 || glyph->charpos < charpos))
19963 {
19964 *x += glyph->pixel_width;
19965 ++glyph;
19966 }
19967
19968 *hpos = glyph - row->glyphs[TEXT_AREA];
19969 return !past_end;
19970 }
19971
19972 #else /* not 1 */
19973
19974 static int
19975 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19976 struct window *w;
19977 int pos;
19978 int *hpos, *vpos, *x, *y;
19979 Lisp_Object stop;
19980 {
19981 int i;
19982 int lastcol;
19983 int maybe_next_line_p = 0;
19984 int line_start_position;
19985 int yb = window_text_bottom_y (w);
19986 struct glyph_row *row, *best_row;
19987 int row_vpos, best_row_vpos;
19988 int current_x;
19989
19990 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19991 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19992
19993 while (row->y < yb)
19994 {
19995 if (row->used[TEXT_AREA])
19996 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19997 else
19998 line_start_position = 0;
19999
20000 if (line_start_position > pos)
20001 break;
20002 /* If the position sought is the end of the buffer,
20003 don't include the blank lines at the bottom of the window. */
20004 else if (line_start_position == pos
20005 && pos == BUF_ZV (XBUFFER (w->buffer)))
20006 {
20007 maybe_next_line_p = 1;
20008 break;
20009 }
20010 else if (line_start_position > 0)
20011 {
20012 best_row = row;
20013 best_row_vpos = row_vpos;
20014 }
20015
20016 if (row->y + row->height >= yb)
20017 break;
20018
20019 ++row;
20020 ++row_vpos;
20021 }
20022
20023 /* Find the right column within BEST_ROW. */
20024 lastcol = 0;
20025 current_x = best_row->x;
20026 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20027 {
20028 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20029 int charpos = glyph->charpos;
20030
20031 if (BUFFERP (glyph->object))
20032 {
20033 if (charpos == pos)
20034 {
20035 *hpos = i;
20036 *vpos = best_row_vpos;
20037 *x = current_x;
20038 *y = best_row->y;
20039 return 1;
20040 }
20041 else if (charpos > pos)
20042 break;
20043 }
20044 else if (EQ (glyph->object, stop))
20045 break;
20046
20047 if (charpos > 0)
20048 lastcol = i;
20049 current_x += glyph->pixel_width;
20050 }
20051
20052 /* If we're looking for the end of the buffer,
20053 and we didn't find it in the line we scanned,
20054 use the start of the following line. */
20055 if (maybe_next_line_p)
20056 {
20057 ++best_row;
20058 ++best_row_vpos;
20059 lastcol = 0;
20060 current_x = best_row->x;
20061 }
20062
20063 *vpos = best_row_vpos;
20064 *hpos = lastcol + 1;
20065 *x = current_x;
20066 *y = best_row->y;
20067 return 0;
20068 }
20069
20070 #endif /* not 1 */
20071
20072
20073 /* Find the position of the glyph for position POS in OBJECT in
20074 window W's current matrix, and return in *X, *Y the pixel
20075 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20076
20077 RIGHT_P non-zero means return the position of the right edge of the
20078 glyph, RIGHT_P zero means return the left edge position.
20079
20080 If no glyph for POS exists in the matrix, return the position of
20081 the glyph with the next smaller position that is in the matrix, if
20082 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20083 exists in the matrix, return the position of the glyph with the
20084 next larger position in OBJECT.
20085
20086 Value is non-zero if a glyph was found. */
20087
20088 static int
20089 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20090 struct window *w;
20091 int pos;
20092 Lisp_Object object;
20093 int *hpos, *vpos, *x, *y;
20094 int right_p;
20095 {
20096 int yb = window_text_bottom_y (w);
20097 struct glyph_row *r;
20098 struct glyph *best_glyph = NULL;
20099 struct glyph_row *best_row = NULL;
20100 int best_x = 0;
20101
20102 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20103 r->enabled_p && r->y < yb;
20104 ++r)
20105 {
20106 struct glyph *g = r->glyphs[TEXT_AREA];
20107 struct glyph *e = g + r->used[TEXT_AREA];
20108 int gx;
20109
20110 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20111 if (EQ (g->object, object))
20112 {
20113 if (g->charpos == pos)
20114 {
20115 best_glyph = g;
20116 best_x = gx;
20117 best_row = r;
20118 goto found;
20119 }
20120 else if (best_glyph == NULL
20121 || ((abs (g->charpos - pos)
20122 < abs (best_glyph->charpos - pos))
20123 && (right_p
20124 ? g->charpos < pos
20125 : g->charpos > pos)))
20126 {
20127 best_glyph = g;
20128 best_x = gx;
20129 best_row = r;
20130 }
20131 }
20132 }
20133
20134 found:
20135
20136 if (best_glyph)
20137 {
20138 *x = best_x;
20139 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
20140
20141 if (right_p)
20142 {
20143 *x += best_glyph->pixel_width;
20144 ++*hpos;
20145 }
20146
20147 *y = best_row->y;
20148 *vpos = best_row - w->current_matrix->rows;
20149 }
20150
20151 return best_glyph != NULL;
20152 }
20153
20154
20155 /* See if position X, Y is within a hot-spot of an image. */
20156
20157 static int
20158 on_hot_spot_p (hot_spot, x, y)
20159 Lisp_Object hot_spot;
20160 int x, y;
20161 {
20162 if (!CONSP (hot_spot))
20163 return 0;
20164
20165 if (EQ (XCAR (hot_spot), Qrect))
20166 {
20167 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
20168 Lisp_Object rect = XCDR (hot_spot);
20169 Lisp_Object tem;
20170 if (!CONSP (rect))
20171 return 0;
20172 if (!CONSP (XCAR (rect)))
20173 return 0;
20174 if (!CONSP (XCDR (rect)))
20175 return 0;
20176 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
20177 return 0;
20178 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
20179 return 0;
20180 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
20181 return 0;
20182 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
20183 return 0;
20184 return 1;
20185 }
20186 else if (EQ (XCAR (hot_spot), Qcircle))
20187 {
20188 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
20189 Lisp_Object circ = XCDR (hot_spot);
20190 Lisp_Object lr, lx0, ly0;
20191 if (CONSP (circ)
20192 && CONSP (XCAR (circ))
20193 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
20194 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
20195 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
20196 {
20197 double r = XFLOATINT (lr);
20198 double dx = XINT (lx0) - x;
20199 double dy = XINT (ly0) - y;
20200 return (dx * dx + dy * dy <= r * r);
20201 }
20202 }
20203 else if (EQ (XCAR (hot_spot), Qpoly))
20204 {
20205 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
20206 if (VECTORP (XCDR (hot_spot)))
20207 {
20208 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
20209 Lisp_Object *poly = v->contents;
20210 int n = v->size;
20211 int i;
20212 int inside = 0;
20213 Lisp_Object lx, ly;
20214 int x0, y0;
20215
20216 /* Need an even number of coordinates, and at least 3 edges. */
20217 if (n < 6 || n & 1)
20218 return 0;
20219
20220 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
20221 If count is odd, we are inside polygon. Pixels on edges
20222 may or may not be included depending on actual geometry of the
20223 polygon. */
20224 if ((lx = poly[n-2], !INTEGERP (lx))
20225 || (ly = poly[n-1], !INTEGERP (lx)))
20226 return 0;
20227 x0 = XINT (lx), y0 = XINT (ly);
20228 for (i = 0; i < n; i += 2)
20229 {
20230 int x1 = x0, y1 = y0;
20231 if ((lx = poly[i], !INTEGERP (lx))
20232 || (ly = poly[i+1], !INTEGERP (ly)))
20233 return 0;
20234 x0 = XINT (lx), y0 = XINT (ly);
20235
20236 /* Does this segment cross the X line? */
20237 if (x0 >= x)
20238 {
20239 if (x1 >= x)
20240 continue;
20241 }
20242 else if (x1 < x)
20243 continue;
20244 if (y > y0 && y > y1)
20245 continue;
20246 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
20247 inside = !inside;
20248 }
20249 return inside;
20250 }
20251 }
20252 return 0;
20253 }
20254
20255 Lisp_Object
20256 find_hot_spot (map, x, y)
20257 Lisp_Object map;
20258 int x, y;
20259 {
20260 while (CONSP (map))
20261 {
20262 if (CONSP (XCAR (map))
20263 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
20264 return XCAR (map);
20265 map = XCDR (map);
20266 }
20267
20268 return Qnil;
20269 }
20270
20271 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20272 3, 3, 0,
20273 doc: /* Lookup in image map MAP coordinates X and Y.
20274 An image map is an alist where each element has the format (AREA ID PLIST).
20275 An AREA is specified as either a rectangle, a circle, or a polygon:
20276 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20277 pixel coordinates of the upper left and bottom right corners.
20278 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20279 and the radius of the circle; r may be a float or integer.
20280 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20281 vector describes one corner in the polygon.
20282 Returns the alist element for the first matching AREA in MAP. */)
20283 (map, x, y)
20284 Lisp_Object map;
20285 Lisp_Object x, y;
20286 {
20287 if (NILP (map))
20288 return Qnil;
20289
20290 CHECK_NUMBER (x);
20291 CHECK_NUMBER (y);
20292
20293 return find_hot_spot (map, XINT (x), XINT (y));
20294 }
20295
20296
20297 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20298 static void
20299 define_frame_cursor1 (f, cursor, pointer)
20300 struct frame *f;
20301 Cursor cursor;
20302 Lisp_Object pointer;
20303 {
20304 if (!NILP (pointer))
20305 {
20306 if (EQ (pointer, Qarrow))
20307 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20308 else if (EQ (pointer, Qhand))
20309 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20310 else if (EQ (pointer, Qtext))
20311 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20312 else if (EQ (pointer, intern ("hdrag")))
20313 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20314 #ifdef HAVE_X_WINDOWS
20315 else if (EQ (pointer, intern ("vdrag")))
20316 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20317 #endif
20318 else if (EQ (pointer, intern ("hourglass")))
20319 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20320 else if (EQ (pointer, Qmodeline))
20321 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20322 else
20323 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20324 }
20325
20326 #ifndef HAVE_CARBON
20327 if (cursor != No_Cursor)
20328 #else
20329 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20330 #endif
20331 FRAME_RIF (f)->define_frame_cursor (f, cursor);
20332 }
20333
20334 /* Take proper action when mouse has moved to the mode or header line
20335 or marginal area AREA of window W, x-position X and y-position Y.
20336 X is relative to the start of the text display area of W, so the
20337 width of bitmap areas and scroll bars must be subtracted to get a
20338 position relative to the start of the mode line. */
20339
20340 static void
20341 note_mode_line_or_margin_highlight (w, x, y, area)
20342 struct window *w;
20343 int x, y;
20344 enum window_part area;
20345 {
20346 struct frame *f = XFRAME (w->frame);
20347 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20348 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20349 Lisp_Object pointer = Qnil;
20350 int charpos, dx, dy, width, height;
20351 Lisp_Object string, object = Qnil;
20352 Lisp_Object pos, help;
20353
20354 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20355 string = mode_line_string (w, area, &x, &y, &charpos,
20356 &object, &dx, &dy, &width, &height);
20357 else
20358 {
20359 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20360 string = marginal_area_string (w, area, &x, &y, &charpos,
20361 &object, &dx, &dy, &width, &height);
20362 }
20363
20364 help = Qnil;
20365
20366 if (IMAGEP (object))
20367 {
20368 Lisp_Object image_map, hotspot;
20369 if ((image_map = Fplist_get (XCDR (object), QCmap),
20370 !NILP (image_map))
20371 && (hotspot = find_hot_spot (image_map, dx, dy),
20372 CONSP (hotspot))
20373 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20374 {
20375 Lisp_Object area_id, plist;
20376
20377 area_id = XCAR (hotspot);
20378 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20379 If so, we could look for mouse-enter, mouse-leave
20380 properties in PLIST (and do something...). */
20381 if ((plist = XCDR (hotspot), CONSP (plist)))
20382 {
20383 pointer = Fplist_get (plist, Qpointer);
20384 if (NILP (pointer))
20385 pointer = Qhand;
20386 help = Fplist_get (plist, Qhelp_echo);
20387 if (!NILP (help))
20388 {
20389 help_echo_string = help;
20390 /* Is this correct? ++kfs */
20391 XSETWINDOW (help_echo_window, w);
20392 help_echo_object = w->buffer;
20393 help_echo_pos = charpos;
20394 }
20395 }
20396 if (NILP (pointer))
20397 pointer = Fplist_get (XCDR (object), QCpointer);
20398 }
20399 }
20400
20401 if (STRINGP (string))
20402 {
20403 pos = make_number (charpos);
20404 /* If we're on a string with `help-echo' text property, arrange
20405 for the help to be displayed. This is done by setting the
20406 global variable help_echo_string to the help string. */
20407 help = Fget_text_property (pos, Qhelp_echo, string);
20408 if (!NILP (help))
20409 {
20410 help_echo_string = help;
20411 XSETWINDOW (help_echo_window, w);
20412 help_echo_object = string;
20413 help_echo_pos = charpos;
20414 }
20415
20416 if (NILP (pointer))
20417 pointer = Fget_text_property (pos, Qpointer, string);
20418
20419 /* Change the mouse pointer according to what is under X/Y. */
20420 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
20421 {
20422 Lisp_Object map;
20423 map = Fget_text_property (pos, Qlocal_map, string);
20424 if (!KEYMAPP (map))
20425 map = Fget_text_property (pos, Qkeymap, string);
20426 if (!KEYMAPP (map))
20427 cursor = dpyinfo->vertical_scroll_bar_cursor;
20428 }
20429 }
20430
20431 define_frame_cursor1 (f, cursor, pointer);
20432 }
20433
20434
20435 /* EXPORT:
20436 Take proper action when the mouse has moved to position X, Y on
20437 frame F as regards highlighting characters that have mouse-face
20438 properties. Also de-highlighting chars where the mouse was before.
20439 X and Y can be negative or out of range. */
20440
20441 void
20442 note_mouse_highlight (f, x, y)
20443 struct frame *f;
20444 int x, y;
20445 {
20446 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20447 enum window_part part;
20448 Lisp_Object window;
20449 struct window *w;
20450 Cursor cursor = No_Cursor;
20451 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20452 struct buffer *b;
20453
20454 /* When a menu is active, don't highlight because this looks odd. */
20455 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20456 if (popup_activated ())
20457 return;
20458 #endif
20459
20460 if (NILP (Vmouse_highlight)
20461 || !f->glyphs_initialized_p)
20462 return;
20463
20464 dpyinfo->mouse_face_mouse_x = x;
20465 dpyinfo->mouse_face_mouse_y = y;
20466 dpyinfo->mouse_face_mouse_frame = f;
20467
20468 if (dpyinfo->mouse_face_defer)
20469 return;
20470
20471 if (gc_in_progress)
20472 {
20473 dpyinfo->mouse_face_deferred_gc = 1;
20474 return;
20475 }
20476
20477 /* Which window is that in? */
20478 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20479
20480 /* If we were displaying active text in another window, clear that. */
20481 if (! EQ (window, dpyinfo->mouse_face_window))
20482 clear_mouse_face (dpyinfo);
20483
20484 /* Not on a window -> return. */
20485 if (!WINDOWP (window))
20486 return;
20487
20488 /* Reset help_echo_string. It will get recomputed below. */
20489 help_echo_string = Qnil;
20490
20491 /* Convert to window-relative pixel coordinates. */
20492 w = XWINDOW (window);
20493 frame_to_window_pixel_xy (w, &x, &y);
20494
20495 /* Handle tool-bar window differently since it doesn't display a
20496 buffer. */
20497 if (EQ (window, f->tool_bar_window))
20498 {
20499 note_tool_bar_highlight (f, x, y);
20500 return;
20501 }
20502
20503 /* Mouse is on the mode, header line or margin? */
20504 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20505 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20506 {
20507 note_mode_line_or_margin_highlight (w, x, y, part);
20508 return;
20509 }
20510
20511 if (part == ON_VERTICAL_BORDER)
20512 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20513 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20514 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20515 else
20516 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20517
20518 /* Are we in a window whose display is up to date?
20519 And verify the buffer's text has not changed. */
20520 b = XBUFFER (w->buffer);
20521 if (part == ON_TEXT
20522 && EQ (w->window_end_valid, w->buffer)
20523 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20524 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20525 {
20526 int hpos, vpos, pos, i, dx, dy, area;
20527 struct glyph *glyph;
20528 Lisp_Object object;
20529 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20530 Lisp_Object *overlay_vec = NULL;
20531 int len, noverlays;
20532 struct buffer *obuf;
20533 int obegv, ozv, same_region;
20534
20535 /* Find the glyph under X/Y. */
20536 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20537
20538 /* Look for :pointer property on image. */
20539 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20540 {
20541 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20542 if (img != NULL && IMAGEP (img->spec))
20543 {
20544 Lisp_Object image_map, hotspot;
20545 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20546 !NILP (image_map))
20547 && (hotspot = find_hot_spot (image_map, dx, dy),
20548 CONSP (hotspot))
20549 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20550 {
20551 Lisp_Object area_id, plist;
20552
20553 area_id = XCAR (hotspot);
20554 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20555 If so, we could look for mouse-enter, mouse-leave
20556 properties in PLIST (and do something...). */
20557 if ((plist = XCDR (hotspot), CONSP (plist)))
20558 {
20559 pointer = Fplist_get (plist, Qpointer);
20560 if (NILP (pointer))
20561 pointer = Qhand;
20562 help_echo_string = Fplist_get (plist, Qhelp_echo);
20563 if (!NILP (help_echo_string))
20564 {
20565 help_echo_window = window;
20566 help_echo_object = glyph->object;
20567 help_echo_pos = glyph->charpos;
20568 }
20569 }
20570 }
20571 if (NILP (pointer))
20572 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20573 }
20574 }
20575
20576 /* Clear mouse face if X/Y not over text. */
20577 if (glyph == NULL
20578 || area != TEXT_AREA
20579 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20580 {
20581 if (clear_mouse_face (dpyinfo))
20582 cursor = No_Cursor;
20583 if (NILP (pointer))
20584 {
20585 if (area != TEXT_AREA)
20586 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20587 else
20588 pointer = Vvoid_text_area_pointer;
20589 }
20590 goto set_cursor;
20591 }
20592
20593 pos = glyph->charpos;
20594 object = glyph->object;
20595 if (!STRINGP (object) && !BUFFERP (object))
20596 goto set_cursor;
20597
20598 /* If we get an out-of-range value, return now; avoid an error. */
20599 if (BUFFERP (object) && pos > BUF_Z (b))
20600 goto set_cursor;
20601
20602 /* Make the window's buffer temporarily current for
20603 overlays_at and compute_char_face. */
20604 obuf = current_buffer;
20605 current_buffer = b;
20606 obegv = BEGV;
20607 ozv = ZV;
20608 BEGV = BEG;
20609 ZV = Z;
20610
20611 /* Is this char mouse-active or does it have help-echo? */
20612 position = make_number (pos);
20613
20614 if (BUFFERP (object))
20615 {
20616 /* Put all the overlays we want in a vector in overlay_vec.
20617 Store the length in len. If there are more than 10, make
20618 enough space for all, and try again. */
20619 len = 10;
20620 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20621 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
20622 if (noverlays > len)
20623 {
20624 len = noverlays;
20625 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20626 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
20627 }
20628
20629 /* Sort overlays into increasing priority order. */
20630 noverlays = sort_overlays (overlay_vec, noverlays, w);
20631 }
20632 else
20633 noverlays = 0;
20634
20635 same_region = (EQ (window, dpyinfo->mouse_face_window)
20636 && vpos >= dpyinfo->mouse_face_beg_row
20637 && vpos <= dpyinfo->mouse_face_end_row
20638 && (vpos > dpyinfo->mouse_face_beg_row
20639 || hpos >= dpyinfo->mouse_face_beg_col)
20640 && (vpos < dpyinfo->mouse_face_end_row
20641 || hpos < dpyinfo->mouse_face_end_col
20642 || dpyinfo->mouse_face_past_end));
20643
20644 if (same_region)
20645 cursor = No_Cursor;
20646
20647 /* Check mouse-face highlighting. */
20648 if (! same_region
20649 /* If there exists an overlay with mouse-face overlapping
20650 the one we are currently highlighting, we have to
20651 check if we enter the overlapping overlay, and then
20652 highlight only that. */
20653 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20654 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20655 {
20656 /* Find the highest priority overlay that has a mouse-face
20657 property. */
20658 overlay = Qnil;
20659 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20660 {
20661 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20662 if (!NILP (mouse_face))
20663 overlay = overlay_vec[i];
20664 }
20665
20666 /* If we're actually highlighting the same overlay as
20667 before, there's no need to do that again. */
20668 if (!NILP (overlay)
20669 && EQ (overlay, dpyinfo->mouse_face_overlay))
20670 goto check_help_echo;
20671
20672 dpyinfo->mouse_face_overlay = overlay;
20673
20674 /* Clear the display of the old active region, if any. */
20675 if (clear_mouse_face (dpyinfo))
20676 cursor = No_Cursor;
20677
20678 /* If no overlay applies, get a text property. */
20679 if (NILP (overlay))
20680 mouse_face = Fget_text_property (position, Qmouse_face, object);
20681
20682 /* Handle the overlay case. */
20683 if (!NILP (overlay))
20684 {
20685 /* Find the range of text around this char that
20686 should be active. */
20687 Lisp_Object before, after;
20688 int ignore;
20689
20690 before = Foverlay_start (overlay);
20691 after = Foverlay_end (overlay);
20692 /* Record this as the current active region. */
20693 fast_find_position (w, XFASTINT (before),
20694 &dpyinfo->mouse_face_beg_col,
20695 &dpyinfo->mouse_face_beg_row,
20696 &dpyinfo->mouse_face_beg_x,
20697 &dpyinfo->mouse_face_beg_y, Qnil);
20698
20699 dpyinfo->mouse_face_past_end
20700 = !fast_find_position (w, XFASTINT (after),
20701 &dpyinfo->mouse_face_end_col,
20702 &dpyinfo->mouse_face_end_row,
20703 &dpyinfo->mouse_face_end_x,
20704 &dpyinfo->mouse_face_end_y, Qnil);
20705 dpyinfo->mouse_face_window = window;
20706
20707 dpyinfo->mouse_face_face_id
20708 = face_at_buffer_position (w, pos, 0, 0,
20709 &ignore, pos + 1,
20710 !dpyinfo->mouse_face_hidden);
20711
20712 /* Display it as active. */
20713 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20714 cursor = No_Cursor;
20715 }
20716 /* Handle the text property case. */
20717 else if (!NILP (mouse_face) && BUFFERP (object))
20718 {
20719 /* Find the range of text around this char that
20720 should be active. */
20721 Lisp_Object before, after, beginning, end;
20722 int ignore;
20723
20724 beginning = Fmarker_position (w->start);
20725 end = make_number (BUF_Z (XBUFFER (object))
20726 - XFASTINT (w->window_end_pos));
20727 before
20728 = Fprevious_single_property_change (make_number (pos + 1),
20729 Qmouse_face,
20730 object, beginning);
20731 after
20732 = Fnext_single_property_change (position, Qmouse_face,
20733 object, end);
20734
20735 /* Record this as the current active region. */
20736 fast_find_position (w, XFASTINT (before),
20737 &dpyinfo->mouse_face_beg_col,
20738 &dpyinfo->mouse_face_beg_row,
20739 &dpyinfo->mouse_face_beg_x,
20740 &dpyinfo->mouse_face_beg_y, Qnil);
20741 dpyinfo->mouse_face_past_end
20742 = !fast_find_position (w, XFASTINT (after),
20743 &dpyinfo->mouse_face_end_col,
20744 &dpyinfo->mouse_face_end_row,
20745 &dpyinfo->mouse_face_end_x,
20746 &dpyinfo->mouse_face_end_y, Qnil);
20747 dpyinfo->mouse_face_window = window;
20748
20749 if (BUFFERP (object))
20750 dpyinfo->mouse_face_face_id
20751 = face_at_buffer_position (w, pos, 0, 0,
20752 &ignore, pos + 1,
20753 !dpyinfo->mouse_face_hidden);
20754
20755 /* Display it as active. */
20756 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20757 cursor = No_Cursor;
20758 }
20759 else if (!NILP (mouse_face) && STRINGP (object))
20760 {
20761 Lisp_Object b, e;
20762 int ignore;
20763
20764 b = Fprevious_single_property_change (make_number (pos + 1),
20765 Qmouse_face,
20766 object, Qnil);
20767 e = Fnext_single_property_change (position, Qmouse_face,
20768 object, Qnil);
20769 if (NILP (b))
20770 b = make_number (0);
20771 if (NILP (e))
20772 e = make_number (SCHARS (object) - 1);
20773 fast_find_string_pos (w, XINT (b), object,
20774 &dpyinfo->mouse_face_beg_col,
20775 &dpyinfo->mouse_face_beg_row,
20776 &dpyinfo->mouse_face_beg_x,
20777 &dpyinfo->mouse_face_beg_y, 0);
20778 fast_find_string_pos (w, XINT (e), object,
20779 &dpyinfo->mouse_face_end_col,
20780 &dpyinfo->mouse_face_end_row,
20781 &dpyinfo->mouse_face_end_x,
20782 &dpyinfo->mouse_face_end_y, 1);
20783 dpyinfo->mouse_face_past_end = 0;
20784 dpyinfo->mouse_face_window = window;
20785 dpyinfo->mouse_face_face_id
20786 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
20787 glyph->face_id, 1);
20788 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20789 cursor = No_Cursor;
20790 }
20791 else if (STRINGP (object) && NILP (mouse_face))
20792 {
20793 /* A string which doesn't have mouse-face, but
20794 the text ``under'' it might have. */
20795 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
20796 int start = MATRIX_ROW_START_CHARPOS (r);
20797
20798 pos = string_buffer_position (w, object, start);
20799 if (pos > 0)
20800 mouse_face = get_char_property_and_overlay (make_number (pos),
20801 Qmouse_face,
20802 w->buffer,
20803 &overlay);
20804 if (!NILP (mouse_face) && !NILP (overlay))
20805 {
20806 Lisp_Object before = Foverlay_start (overlay);
20807 Lisp_Object after = Foverlay_end (overlay);
20808 int ignore;
20809
20810 /* Note that we might not be able to find position
20811 BEFORE in the glyph matrix if the overlay is
20812 entirely covered by a `display' property. In
20813 this case, we overshoot. So let's stop in
20814 the glyph matrix before glyphs for OBJECT. */
20815 fast_find_position (w, XFASTINT (before),
20816 &dpyinfo->mouse_face_beg_col,
20817 &dpyinfo->mouse_face_beg_row,
20818 &dpyinfo->mouse_face_beg_x,
20819 &dpyinfo->mouse_face_beg_y,
20820 object);
20821
20822 dpyinfo->mouse_face_past_end
20823 = !fast_find_position (w, XFASTINT (after),
20824 &dpyinfo->mouse_face_end_col,
20825 &dpyinfo->mouse_face_end_row,
20826 &dpyinfo->mouse_face_end_x,
20827 &dpyinfo->mouse_face_end_y,
20828 Qnil);
20829 dpyinfo->mouse_face_window = window;
20830 dpyinfo->mouse_face_face_id
20831 = face_at_buffer_position (w, pos, 0, 0,
20832 &ignore, pos + 1,
20833 !dpyinfo->mouse_face_hidden);
20834
20835 /* Display it as active. */
20836 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20837 cursor = No_Cursor;
20838 }
20839 }
20840 }
20841
20842 check_help_echo:
20843
20844 /* Look for a `help-echo' property. */
20845 if (NILP (help_echo_string)) {
20846 Lisp_Object help, overlay;
20847
20848 /* Check overlays first. */
20849 help = overlay = Qnil;
20850 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
20851 {
20852 overlay = overlay_vec[i];
20853 help = Foverlay_get (overlay, Qhelp_echo);
20854 }
20855
20856 if (!NILP (help))
20857 {
20858 help_echo_string = help;
20859 help_echo_window = window;
20860 help_echo_object = overlay;
20861 help_echo_pos = pos;
20862 }
20863 else
20864 {
20865 Lisp_Object object = glyph->object;
20866 int charpos = glyph->charpos;
20867
20868 /* Try text properties. */
20869 if (STRINGP (object)
20870 && charpos >= 0
20871 && charpos < SCHARS (object))
20872 {
20873 help = Fget_text_property (make_number (charpos),
20874 Qhelp_echo, object);
20875 if (NILP (help))
20876 {
20877 /* If the string itself doesn't specify a help-echo,
20878 see if the buffer text ``under'' it does. */
20879 struct glyph_row *r
20880 = MATRIX_ROW (w->current_matrix, vpos);
20881 int start = MATRIX_ROW_START_CHARPOS (r);
20882 int pos = string_buffer_position (w, object, start);
20883 if (pos > 0)
20884 {
20885 help = Fget_char_property (make_number (pos),
20886 Qhelp_echo, w->buffer);
20887 if (!NILP (help))
20888 {
20889 charpos = pos;
20890 object = w->buffer;
20891 }
20892 }
20893 }
20894 }
20895 else if (BUFFERP (object)
20896 && charpos >= BEGV
20897 && charpos < ZV)
20898 help = Fget_text_property (make_number (charpos), Qhelp_echo,
20899 object);
20900
20901 if (!NILP (help))
20902 {
20903 help_echo_string = help;
20904 help_echo_window = window;
20905 help_echo_object = object;
20906 help_echo_pos = charpos;
20907 }
20908 }
20909 }
20910
20911 /* Look for a `pointer' property. */
20912 if (NILP (pointer))
20913 {
20914 /* Check overlays first. */
20915 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
20916 pointer = Foverlay_get (overlay_vec[i], Qpointer);
20917
20918 if (NILP (pointer))
20919 {
20920 Lisp_Object object = glyph->object;
20921 int charpos = glyph->charpos;
20922
20923 /* Try text properties. */
20924 if (STRINGP (object)
20925 && charpos >= 0
20926 && charpos < SCHARS (object))
20927 {
20928 pointer = Fget_text_property (make_number (charpos),
20929 Qpointer, object);
20930 if (NILP (pointer))
20931 {
20932 /* If the string itself doesn't specify a pointer,
20933 see if the buffer text ``under'' it does. */
20934 struct glyph_row *r
20935 = MATRIX_ROW (w->current_matrix, vpos);
20936 int start = MATRIX_ROW_START_CHARPOS (r);
20937 int pos = string_buffer_position (w, object, start);
20938 if (pos > 0)
20939 pointer = Fget_char_property (make_number (pos),
20940 Qpointer, w->buffer);
20941 }
20942 }
20943 else if (BUFFERP (object)
20944 && charpos >= BEGV
20945 && charpos < ZV)
20946 pointer = Fget_text_property (make_number (charpos),
20947 Qpointer, object);
20948 }
20949 }
20950
20951 BEGV = obegv;
20952 ZV = ozv;
20953 current_buffer = obuf;
20954 }
20955
20956 set_cursor:
20957
20958 define_frame_cursor1 (f, cursor, pointer);
20959 }
20960
20961
20962 /* EXPORT for RIF:
20963 Clear any mouse-face on window W. This function is part of the
20964 redisplay interface, and is called from try_window_id and similar
20965 functions to ensure the mouse-highlight is off. */
20966
20967 void
20968 x_clear_window_mouse_face (w)
20969 struct window *w;
20970 {
20971 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20972 Lisp_Object window;
20973
20974 BLOCK_INPUT;
20975 XSETWINDOW (window, w);
20976 if (EQ (window, dpyinfo->mouse_face_window))
20977 clear_mouse_face (dpyinfo);
20978 UNBLOCK_INPUT;
20979 }
20980
20981
20982 /* EXPORT:
20983 Just discard the mouse face information for frame F, if any.
20984 This is used when the size of F is changed. */
20985
20986 void
20987 cancel_mouse_face (f)
20988 struct frame *f;
20989 {
20990 Lisp_Object window;
20991 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20992
20993 window = dpyinfo->mouse_face_window;
20994 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20995 {
20996 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20997 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20998 dpyinfo->mouse_face_window = Qnil;
20999 }
21000 }
21001
21002
21003 #endif /* HAVE_WINDOW_SYSTEM */
21004
21005 \f
21006 /***********************************************************************
21007 Exposure Events
21008 ***********************************************************************/
21009
21010 #ifdef HAVE_WINDOW_SYSTEM
21011
21012 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21013 which intersects rectangle R. R is in window-relative coordinates. */
21014
21015 static void
21016 expose_area (w, row, r, area)
21017 struct window *w;
21018 struct glyph_row *row;
21019 XRectangle *r;
21020 enum glyph_row_area area;
21021 {
21022 struct glyph *first = row->glyphs[area];
21023 struct glyph *end = row->glyphs[area] + row->used[area];
21024 struct glyph *last;
21025 int first_x, start_x, x;
21026
21027 if (area == TEXT_AREA && row->fill_line_p)
21028 /* If row extends face to end of line write the whole line. */
21029 draw_glyphs (w, 0, row, area,
21030 0, row->used[area],
21031 DRAW_NORMAL_TEXT, 0);
21032 else
21033 {
21034 /* Set START_X to the window-relative start position for drawing glyphs of
21035 AREA. The first glyph of the text area can be partially visible.
21036 The first glyphs of other areas cannot. */
21037 start_x = window_box_left_offset (w, area);
21038 x = start_x;
21039 if (area == TEXT_AREA)
21040 x += row->x;
21041
21042 /* Find the first glyph that must be redrawn. */
21043 while (first < end
21044 && x + first->pixel_width < r->x)
21045 {
21046 x += first->pixel_width;
21047 ++first;
21048 }
21049
21050 /* Find the last one. */
21051 last = first;
21052 first_x = x;
21053 while (last < end
21054 && x < r->x + r->width)
21055 {
21056 x += last->pixel_width;
21057 ++last;
21058 }
21059
21060 /* Repaint. */
21061 if (last > first)
21062 draw_glyphs (w, first_x - start_x, row, area,
21063 first - row->glyphs[area], last - row->glyphs[area],
21064 DRAW_NORMAL_TEXT, 0);
21065 }
21066 }
21067
21068
21069 /* Redraw the parts of the glyph row ROW on window W intersecting
21070 rectangle R. R is in window-relative coordinates. Value is
21071 non-zero if mouse-face was overwritten. */
21072
21073 static int
21074 expose_line (w, row, r)
21075 struct window *w;
21076 struct glyph_row *row;
21077 XRectangle *r;
21078 {
21079 xassert (row->enabled_p);
21080
21081 if (row->mode_line_p || w->pseudo_window_p)
21082 draw_glyphs (w, 0, row, TEXT_AREA,
21083 0, row->used[TEXT_AREA],
21084 DRAW_NORMAL_TEXT, 0);
21085 else
21086 {
21087 if (row->used[LEFT_MARGIN_AREA])
21088 expose_area (w, row, r, LEFT_MARGIN_AREA);
21089 if (row->used[TEXT_AREA])
21090 expose_area (w, row, r, TEXT_AREA);
21091 if (row->used[RIGHT_MARGIN_AREA])
21092 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21093 draw_row_fringe_bitmaps (w, row);
21094 }
21095
21096 return row->mouse_face_p;
21097 }
21098
21099
21100 /* Redraw those parts of glyphs rows during expose event handling that
21101 overlap other rows. Redrawing of an exposed line writes over parts
21102 of lines overlapping that exposed line; this function fixes that.
21103
21104 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21105 row in W's current matrix that is exposed and overlaps other rows.
21106 LAST_OVERLAPPING_ROW is the last such row. */
21107
21108 static void
21109 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21110 struct window *w;
21111 struct glyph_row *first_overlapping_row;
21112 struct glyph_row *last_overlapping_row;
21113 {
21114 struct glyph_row *row;
21115
21116 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21117 if (row->overlapping_p)
21118 {
21119 xassert (row->enabled_p && !row->mode_line_p);
21120
21121 if (row->used[LEFT_MARGIN_AREA])
21122 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21123
21124 if (row->used[TEXT_AREA])
21125 x_fix_overlapping_area (w, row, TEXT_AREA);
21126
21127 if (row->used[RIGHT_MARGIN_AREA])
21128 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
21129 }
21130 }
21131
21132
21133 /* Return non-zero if W's cursor intersects rectangle R. */
21134
21135 static int
21136 phys_cursor_in_rect_p (w, r)
21137 struct window *w;
21138 XRectangle *r;
21139 {
21140 XRectangle cr, result;
21141 struct glyph *cursor_glyph;
21142
21143 cursor_glyph = get_phys_cursor_glyph (w);
21144 if (cursor_glyph)
21145 {
21146 /* r is relative to W's box, but w->phys_cursor.x is relative
21147 to left edge of W's TEXT area. Adjust it. */
21148 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
21149 cr.y = w->phys_cursor.y;
21150 cr.width = cursor_glyph->pixel_width;
21151 cr.height = w->phys_cursor_height;
21152 /* ++KFS: W32 version used W32-specific IntersectRect here, but
21153 I assume the effect is the same -- and this is portable. */
21154 return x_intersect_rectangles (&cr, r, &result);
21155 }
21156 else
21157 return 0;
21158 }
21159
21160
21161 /* EXPORT:
21162 Draw a vertical window border to the right of window W if W doesn't
21163 have vertical scroll bars. */
21164
21165 void
21166 x_draw_vertical_border (w)
21167 struct window *w;
21168 {
21169 struct frame *f = XFRAME (WINDOW_FRAME (w));
21170
21171 /* We could do better, if we knew what type of scroll-bar the adjacent
21172 windows (on either side) have... But we don't :-(
21173 However, I think this works ok. ++KFS 2003-04-25 */
21174
21175 /* Redraw borders between horizontally adjacent windows. Don't
21176 do it for frames with vertical scroll bars because either the
21177 right scroll bar of a window, or the left scroll bar of its
21178 neighbor will suffice as a border. */
21179 if (!WINDOW_RIGHTMOST_P (w)
21180 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
21181 {
21182 int x0, x1, y0, y1;
21183
21184 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21185 y1 -= 1;
21186
21187 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
21188 }
21189 else if (!WINDOW_LEFTMOST_P (w)
21190 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
21191 {
21192 int x0, x1, y0, y1;
21193
21194 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
21195 y1 -= 1;
21196
21197 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
21198 }
21199 }
21200
21201
21202 /* Redraw the part of window W intersection rectangle FR. Pixel
21203 coordinates in FR are frame-relative. Call this function with
21204 input blocked. Value is non-zero if the exposure overwrites
21205 mouse-face. */
21206
21207 static int
21208 expose_window (w, fr)
21209 struct window *w;
21210 XRectangle *fr;
21211 {
21212 struct frame *f = XFRAME (w->frame);
21213 XRectangle wr, r;
21214 int mouse_face_overwritten_p = 0;
21215
21216 /* If window is not yet fully initialized, do nothing. This can
21217 happen when toolkit scroll bars are used and a window is split.
21218 Reconfiguring the scroll bar will generate an expose for a newly
21219 created window. */
21220 if (w->current_matrix == NULL)
21221 return 0;
21222
21223 /* When we're currently updating the window, display and current
21224 matrix usually don't agree. Arrange for a thorough display
21225 later. */
21226 if (w == updated_window)
21227 {
21228 SET_FRAME_GARBAGED (f);
21229 return 0;
21230 }
21231
21232 /* Frame-relative pixel rectangle of W. */
21233 wr.x = WINDOW_LEFT_EDGE_X (w);
21234 wr.y = WINDOW_TOP_EDGE_Y (w);
21235 wr.width = WINDOW_TOTAL_WIDTH (w);
21236 wr.height = WINDOW_TOTAL_HEIGHT (w);
21237
21238 if (x_intersect_rectangles (fr, &wr, &r))
21239 {
21240 int yb = window_text_bottom_y (w);
21241 struct glyph_row *row;
21242 int cursor_cleared_p;
21243 struct glyph_row *first_overlapping_row, *last_overlapping_row;
21244
21245 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
21246 r.x, r.y, r.width, r.height));
21247
21248 /* Convert to window coordinates. */
21249 r.x -= WINDOW_LEFT_EDGE_X (w);
21250 r.y -= WINDOW_TOP_EDGE_Y (w);
21251
21252 /* Turn off the cursor. */
21253 if (!w->pseudo_window_p
21254 && phys_cursor_in_rect_p (w, &r))
21255 {
21256 x_clear_cursor (w);
21257 cursor_cleared_p = 1;
21258 }
21259 else
21260 cursor_cleared_p = 0;
21261
21262 /* Update lines intersecting rectangle R. */
21263 first_overlapping_row = last_overlapping_row = NULL;
21264 for (row = w->current_matrix->rows;
21265 row->enabled_p;
21266 ++row)
21267 {
21268 int y0 = row->y;
21269 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21270
21271 if ((y0 >= r.y && y0 < r.y + r.height)
21272 || (y1 > r.y && y1 < r.y + r.height)
21273 || (r.y >= y0 && r.y < y1)
21274 || (r.y + r.height > y0 && r.y + r.height < y1))
21275 {
21276 if (row->overlapping_p)
21277 {
21278 if (first_overlapping_row == NULL)
21279 first_overlapping_row = row;
21280 last_overlapping_row = row;
21281 }
21282
21283 if (expose_line (w, row, &r))
21284 mouse_face_overwritten_p = 1;
21285 }
21286
21287 if (y1 >= yb)
21288 break;
21289 }
21290
21291 /* Display the mode line if there is one. */
21292 if (WINDOW_WANTS_MODELINE_P (w)
21293 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21294 row->enabled_p)
21295 && row->y < r.y + r.height)
21296 {
21297 if (expose_line (w, row, &r))
21298 mouse_face_overwritten_p = 1;
21299 }
21300
21301 if (!w->pseudo_window_p)
21302 {
21303 /* Fix the display of overlapping rows. */
21304 if (first_overlapping_row)
21305 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21306
21307 /* Draw border between windows. */
21308 x_draw_vertical_border (w);
21309
21310 /* Turn the cursor on again. */
21311 if (cursor_cleared_p)
21312 update_window_cursor (w, 1);
21313 }
21314 }
21315
21316 #ifdef HAVE_CARBON
21317 /* Display scroll bar for this window. */
21318 if (!NILP (w->vertical_scroll_bar))
21319 {
21320 /* ++KFS:
21321 If this doesn't work here (maybe some header files are missing),
21322 make a function in macterm.c and call it to do the job! */
21323 ControlHandle ch
21324 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21325
21326 Draw1Control (ch);
21327 }
21328 #endif
21329
21330 return mouse_face_overwritten_p;
21331 }
21332
21333
21334
21335 /* Redraw (parts) of all windows in the window tree rooted at W that
21336 intersect R. R contains frame pixel coordinates. Value is
21337 non-zero if the exposure overwrites mouse-face. */
21338
21339 static int
21340 expose_window_tree (w, r)
21341 struct window *w;
21342 XRectangle *r;
21343 {
21344 struct frame *f = XFRAME (w->frame);
21345 int mouse_face_overwritten_p = 0;
21346
21347 while (w && !FRAME_GARBAGED_P (f))
21348 {
21349 if (!NILP (w->hchild))
21350 mouse_face_overwritten_p
21351 |= expose_window_tree (XWINDOW (w->hchild), r);
21352 else if (!NILP (w->vchild))
21353 mouse_face_overwritten_p
21354 |= expose_window_tree (XWINDOW (w->vchild), r);
21355 else
21356 mouse_face_overwritten_p |= expose_window (w, r);
21357
21358 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21359 }
21360
21361 return mouse_face_overwritten_p;
21362 }
21363
21364
21365 /* EXPORT:
21366 Redisplay an exposed area of frame F. X and Y are the upper-left
21367 corner of the exposed rectangle. W and H are width and height of
21368 the exposed area. All are pixel values. W or H zero means redraw
21369 the entire frame. */
21370
21371 void
21372 expose_frame (f, x, y, w, h)
21373 struct frame *f;
21374 int x, y, w, h;
21375 {
21376 XRectangle r;
21377 int mouse_face_overwritten_p = 0;
21378
21379 TRACE ((stderr, "expose_frame "));
21380
21381 /* No need to redraw if frame will be redrawn soon. */
21382 if (FRAME_GARBAGED_P (f))
21383 {
21384 TRACE ((stderr, " garbaged\n"));
21385 return;
21386 }
21387
21388 #ifdef HAVE_CARBON
21389 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21390 or deactivated here, for unknown reasons, activated scroll bars
21391 are shown in deactivated frames in some instances. */
21392 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21393 activate_scroll_bars (f);
21394 else
21395 deactivate_scroll_bars (f);
21396 #endif
21397
21398 /* If basic faces haven't been realized yet, there is no point in
21399 trying to redraw anything. This can happen when we get an expose
21400 event while Emacs is starting, e.g. by moving another window. */
21401 if (FRAME_FACE_CACHE (f) == NULL
21402 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21403 {
21404 TRACE ((stderr, " no faces\n"));
21405 return;
21406 }
21407
21408 if (w == 0 || h == 0)
21409 {
21410 r.x = r.y = 0;
21411 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21412 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21413 }
21414 else
21415 {
21416 r.x = x;
21417 r.y = y;
21418 r.width = w;
21419 r.height = h;
21420 }
21421
21422 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21423 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21424
21425 if (WINDOWP (f->tool_bar_window))
21426 mouse_face_overwritten_p
21427 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21428
21429 #ifdef HAVE_X_WINDOWS
21430 #ifndef MSDOS
21431 #ifndef USE_X_TOOLKIT
21432 if (WINDOWP (f->menu_bar_window))
21433 mouse_face_overwritten_p
21434 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21435 #endif /* not USE_X_TOOLKIT */
21436 #endif
21437 #endif
21438
21439 /* Some window managers support a focus-follows-mouse style with
21440 delayed raising of frames. Imagine a partially obscured frame,
21441 and moving the mouse into partially obscured mouse-face on that
21442 frame. The visible part of the mouse-face will be highlighted,
21443 then the WM raises the obscured frame. With at least one WM, KDE
21444 2.1, Emacs is not getting any event for the raising of the frame
21445 (even tried with SubstructureRedirectMask), only Expose events.
21446 These expose events will draw text normally, i.e. not
21447 highlighted. Which means we must redo the highlight here.
21448 Subsume it under ``we love X''. --gerd 2001-08-15 */
21449 /* Included in Windows version because Windows most likely does not
21450 do the right thing if any third party tool offers
21451 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21452 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21453 {
21454 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21455 if (f == dpyinfo->mouse_face_mouse_frame)
21456 {
21457 int x = dpyinfo->mouse_face_mouse_x;
21458 int y = dpyinfo->mouse_face_mouse_y;
21459 clear_mouse_face (dpyinfo);
21460 note_mouse_highlight (f, x, y);
21461 }
21462 }
21463 }
21464
21465
21466 /* EXPORT:
21467 Determine the intersection of two rectangles R1 and R2. Return
21468 the intersection in *RESULT. Value is non-zero if RESULT is not
21469 empty. */
21470
21471 int
21472 x_intersect_rectangles (r1, r2, result)
21473 XRectangle *r1, *r2, *result;
21474 {
21475 XRectangle *left, *right;
21476 XRectangle *upper, *lower;
21477 int intersection_p = 0;
21478
21479 /* Rearrange so that R1 is the left-most rectangle. */
21480 if (r1->x < r2->x)
21481 left = r1, right = r2;
21482 else
21483 left = r2, right = r1;
21484
21485 /* X0 of the intersection is right.x0, if this is inside R1,
21486 otherwise there is no intersection. */
21487 if (right->x <= left->x + left->width)
21488 {
21489 result->x = right->x;
21490
21491 /* The right end of the intersection is the minimum of the
21492 the right ends of left and right. */
21493 result->width = (min (left->x + left->width, right->x + right->width)
21494 - result->x);
21495
21496 /* Same game for Y. */
21497 if (r1->y < r2->y)
21498 upper = r1, lower = r2;
21499 else
21500 upper = r2, lower = r1;
21501
21502 /* The upper end of the intersection is lower.y0, if this is inside
21503 of upper. Otherwise, there is no intersection. */
21504 if (lower->y <= upper->y + upper->height)
21505 {
21506 result->y = lower->y;
21507
21508 /* The lower end of the intersection is the minimum of the lower
21509 ends of upper and lower. */
21510 result->height = (min (lower->y + lower->height,
21511 upper->y + upper->height)
21512 - result->y);
21513 intersection_p = 1;
21514 }
21515 }
21516
21517 return intersection_p;
21518 }
21519
21520 #endif /* HAVE_WINDOW_SYSTEM */
21521
21522 \f
21523 /***********************************************************************
21524 Initialization
21525 ***********************************************************************/
21526
21527 void
21528 syms_of_xdisp ()
21529 {
21530 Vwith_echo_area_save_vector = Qnil;
21531 staticpro (&Vwith_echo_area_save_vector);
21532
21533 Vmessage_stack = Qnil;
21534 staticpro (&Vmessage_stack);
21535
21536 Qinhibit_redisplay = intern ("inhibit-redisplay");
21537 staticpro (&Qinhibit_redisplay);
21538
21539 message_dolog_marker1 = Fmake_marker ();
21540 staticpro (&message_dolog_marker1);
21541 message_dolog_marker2 = Fmake_marker ();
21542 staticpro (&message_dolog_marker2);
21543 message_dolog_marker3 = Fmake_marker ();
21544 staticpro (&message_dolog_marker3);
21545
21546 #if GLYPH_DEBUG
21547 defsubr (&Sdump_frame_glyph_matrix);
21548 defsubr (&Sdump_glyph_matrix);
21549 defsubr (&Sdump_glyph_row);
21550 defsubr (&Sdump_tool_bar_row);
21551 defsubr (&Strace_redisplay);
21552 defsubr (&Strace_to_stderr);
21553 #endif
21554 #ifdef HAVE_WINDOW_SYSTEM
21555 defsubr (&Stool_bar_lines_needed);
21556 defsubr (&Slookup_image_map);
21557 #endif
21558 defsubr (&Sformat_mode_line);
21559
21560 staticpro (&Qmenu_bar_update_hook);
21561 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21562
21563 staticpro (&Qoverriding_terminal_local_map);
21564 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21565
21566 staticpro (&Qoverriding_local_map);
21567 Qoverriding_local_map = intern ("overriding-local-map");
21568
21569 staticpro (&Qwindow_scroll_functions);
21570 Qwindow_scroll_functions = intern ("window-scroll-functions");
21571
21572 staticpro (&Qredisplay_end_trigger_functions);
21573 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21574
21575 staticpro (&Qinhibit_point_motion_hooks);
21576 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21577
21578 QCdata = intern (":data");
21579 staticpro (&QCdata);
21580 Qdisplay = intern ("display");
21581 staticpro (&Qdisplay);
21582 Qspace_width = intern ("space-width");
21583 staticpro (&Qspace_width);
21584 Qraise = intern ("raise");
21585 staticpro (&Qraise);
21586 Qspace = intern ("space");
21587 staticpro (&Qspace);
21588 Qmargin = intern ("margin");
21589 staticpro (&Qmargin);
21590 Qpointer = intern ("pointer");
21591 staticpro (&Qpointer);
21592 Qleft_margin = intern ("left-margin");
21593 staticpro (&Qleft_margin);
21594 Qright_margin = intern ("right-margin");
21595 staticpro (&Qright_margin);
21596 Qcenter = intern ("center");
21597 staticpro (&Qcenter);
21598 QCalign_to = intern (":align-to");
21599 staticpro (&QCalign_to);
21600 QCrelative_width = intern (":relative-width");
21601 staticpro (&QCrelative_width);
21602 QCrelative_height = intern (":relative-height");
21603 staticpro (&QCrelative_height);
21604 QCeval = intern (":eval");
21605 staticpro (&QCeval);
21606 QCpropertize = intern (":propertize");
21607 staticpro (&QCpropertize);
21608 QCfile = intern (":file");
21609 staticpro (&QCfile);
21610 Qfontified = intern ("fontified");
21611 staticpro (&Qfontified);
21612 Qfontification_functions = intern ("fontification-functions");
21613 staticpro (&Qfontification_functions);
21614 Qtrailing_whitespace = intern ("trailing-whitespace");
21615 staticpro (&Qtrailing_whitespace);
21616 Qimage = intern ("image");
21617 staticpro (&Qimage);
21618 QCmap = intern (":map");
21619 staticpro (&QCmap);
21620 QCpointer = intern (":pointer");
21621 staticpro (&QCpointer);
21622 Qrect = intern ("rect");
21623 staticpro (&Qrect);
21624 Qcircle = intern ("circle");
21625 staticpro (&Qcircle);
21626 Qpoly = intern ("poly");
21627 staticpro (&Qpoly);
21628 Qmessage_truncate_lines = intern ("message-truncate-lines");
21629 staticpro (&Qmessage_truncate_lines);
21630 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21631 staticpro (&Qcursor_in_non_selected_windows);
21632 Qgrow_only = intern ("grow-only");
21633 staticpro (&Qgrow_only);
21634 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21635 staticpro (&Qinhibit_menubar_update);
21636 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21637 staticpro (&Qinhibit_eval_during_redisplay);
21638 Qposition = intern ("position");
21639 staticpro (&Qposition);
21640 Qbuffer_position = intern ("buffer-position");
21641 staticpro (&Qbuffer_position);
21642 Qobject = intern ("object");
21643 staticpro (&Qobject);
21644 Qbar = intern ("bar");
21645 staticpro (&Qbar);
21646 Qhbar = intern ("hbar");
21647 staticpro (&Qhbar);
21648 Qbox = intern ("box");
21649 staticpro (&Qbox);
21650 Qhollow = intern ("hollow");
21651 staticpro (&Qhollow);
21652 Qhand = intern ("hand");
21653 staticpro (&Qhand);
21654 Qarrow = intern ("arrow");
21655 staticpro (&Qarrow);
21656 Qtext = intern ("text");
21657 staticpro (&Qtext);
21658 Qrisky_local_variable = intern ("risky-local-variable");
21659 staticpro (&Qrisky_local_variable);
21660 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21661 staticpro (&Qinhibit_free_realized_faces);
21662
21663 list_of_error = Fcons (Fcons (intern ("error"),
21664 Fcons (intern ("void-variable"), Qnil)),
21665 Qnil);
21666 staticpro (&list_of_error);
21667
21668 Qlast_arrow_position = intern ("last-arrow-position");
21669 staticpro (&Qlast_arrow_position);
21670 Qlast_arrow_string = intern ("last-arrow-string");
21671 staticpro (&Qlast_arrow_string);
21672
21673 Qoverlay_arrow_string = intern ("overlay-arrow-string");
21674 staticpro (&Qoverlay_arrow_string);
21675 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
21676 staticpro (&Qoverlay_arrow_bitmap);
21677
21678 echo_buffer[0] = echo_buffer[1] = Qnil;
21679 staticpro (&echo_buffer[0]);
21680 staticpro (&echo_buffer[1]);
21681
21682 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21683 staticpro (&echo_area_buffer[0]);
21684 staticpro (&echo_area_buffer[1]);
21685
21686 Vmessages_buffer_name = build_string ("*Messages*");
21687 staticpro (&Vmessages_buffer_name);
21688
21689 mode_line_proptrans_alist = Qnil;
21690 staticpro (&mode_line_proptrans_alist);
21691
21692 mode_line_string_list = Qnil;
21693 staticpro (&mode_line_string_list);
21694
21695 help_echo_string = Qnil;
21696 staticpro (&help_echo_string);
21697 help_echo_object = Qnil;
21698 staticpro (&help_echo_object);
21699 help_echo_window = Qnil;
21700 staticpro (&help_echo_window);
21701 previous_help_echo_string = Qnil;
21702 staticpro (&previous_help_echo_string);
21703 help_echo_pos = -1;
21704
21705 #ifdef HAVE_WINDOW_SYSTEM
21706 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
21707 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
21708 For example, if a block cursor is over a tab, it will be drawn as
21709 wide as that tab on the display. */);
21710 x_stretch_cursor_p = 0;
21711 #endif
21712
21713 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
21714 doc: /* *Non-nil means highlight trailing whitespace.
21715 The face used for trailing whitespace is `trailing-whitespace'. */);
21716 Vshow_trailing_whitespace = Qnil;
21717
21718 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
21719 doc: /* *The pointer shape to show in void text areas.
21720 Nil means to show the text pointer. Other options are `arrow', `text',
21721 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
21722 Vvoid_text_area_pointer = Qarrow;
21723
21724 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
21725 doc: /* Non-nil means don't actually do any redisplay.
21726 This is used for internal purposes. */);
21727 Vinhibit_redisplay = Qnil;
21728
21729 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
21730 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21731 Vglobal_mode_string = Qnil;
21732
21733 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
21734 doc: /* Marker for where to display an arrow on top of the buffer text.
21735 This must be the beginning of a line in order to work.
21736 See also `overlay-arrow-string'. */);
21737 Voverlay_arrow_position = Qnil;
21738
21739 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
21740 doc: /* String to display as an arrow in non-window frames.
21741 See also `overlay-arrow-position'. */);
21742 Voverlay_arrow_string = Qnil;
21743
21744 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
21745 doc: /* List of variables (symbols) which hold markers for overlay arrows.
21746 The symbols on this list are examined during redisplay to determine
21747 where to display overlay arrows. */);
21748 Voverlay_arrow_variable_list
21749 = Fcons (intern ("overlay-arrow-position"), Qnil);
21750
21751 DEFVAR_INT ("scroll-step", &scroll_step,
21752 doc: /* *The number of lines to try scrolling a window by when point moves out.
21753 If that fails to bring point back on frame, point is centered instead.
21754 If this is zero, point is always centered after it moves off frame.
21755 If you want scrolling to always be a line at a time, you should set
21756 `scroll-conservatively' to a large value rather than set this to 1. */);
21757
21758 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
21759 doc: /* *Scroll up to this many lines, to bring point back on screen.
21760 A value of zero means to scroll the text to center point vertically
21761 in the window. */);
21762 scroll_conservatively = 0;
21763
21764 DEFVAR_INT ("scroll-margin", &scroll_margin,
21765 doc: /* *Number of lines of margin at the top and bottom of a window.
21766 Recenter the window whenever point gets within this many lines
21767 of the top or bottom of the window. */);
21768 scroll_margin = 0;
21769
21770 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
21771 doc: /* Pixels per inch on current display.
21772 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21773 Vdisplay_pixels_per_inch = make_float (72.0);
21774
21775 #if GLYPH_DEBUG
21776 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
21777 #endif
21778
21779 DEFVAR_BOOL ("truncate-partial-width-windows",
21780 &truncate_partial_width_windows,
21781 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21782 truncate_partial_width_windows = 1;
21783
21784 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
21785 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
21786 Any other value means to use the appropriate face, `mode-line',
21787 `header-line', or `menu' respectively. */);
21788 mode_line_inverse_video = 1;
21789
21790 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
21791 doc: /* *Maximum buffer size for which line number should be displayed.
21792 If the buffer is bigger than this, the line number does not appear
21793 in the mode line. A value of nil means no limit. */);
21794 Vline_number_display_limit = Qnil;
21795
21796 DEFVAR_INT ("line-number-display-limit-width",
21797 &line_number_display_limit_width,
21798 doc: /* *Maximum line width (in characters) for line number display.
21799 If the average length of the lines near point is bigger than this, then the
21800 line number may be omitted from the mode line. */);
21801 line_number_display_limit_width = 200;
21802
21803 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
21804 doc: /* *Non-nil means highlight region even in nonselected windows. */);
21805 highlight_nonselected_windows = 0;
21806
21807 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
21808 doc: /* Non-nil if more than one frame is visible on this display.
21809 Minibuffer-only frames don't count, but iconified frames do.
21810 This variable is not guaranteed to be accurate except while processing
21811 `frame-title-format' and `icon-title-format'. */);
21812
21813 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
21814 doc: /* Template for displaying the title bar of visible frames.
21815 \(Assuming the window manager supports this feature.)
21816 This variable has the same structure as `mode-line-format' (which see),
21817 and is used only on frames for which no explicit name has been set
21818 \(see `modify-frame-parameters'). */);
21819
21820 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
21821 doc: /* Template for displaying the title bar of an iconified frame.
21822 \(Assuming the window manager supports this feature.)
21823 This variable has the same structure as `mode-line-format' (which see),
21824 and is used only on frames for which no explicit name has been set
21825 \(see `modify-frame-parameters'). */);
21826 Vicon_title_format
21827 = Vframe_title_format
21828 = Fcons (intern ("multiple-frames"),
21829 Fcons (build_string ("%b"),
21830 Fcons (Fcons (empty_string,
21831 Fcons (intern ("invocation-name"),
21832 Fcons (build_string ("@"),
21833 Fcons (intern ("system-name"),
21834 Qnil)))),
21835 Qnil)));
21836
21837 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
21838 doc: /* Maximum number of lines to keep in the message log buffer.
21839 If nil, disable message logging. If t, log messages but don't truncate
21840 the buffer when it becomes large. */);
21841 Vmessage_log_max = make_number (50);
21842
21843 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
21844 doc: /* Functions called before redisplay, if window sizes have changed.
21845 The value should be a list of functions that take one argument.
21846 Just before redisplay, for each frame, if any of its windows have changed
21847 size since the last redisplay, or have been split or deleted,
21848 all the functions in the list are called, with the frame as argument. */);
21849 Vwindow_size_change_functions = Qnil;
21850
21851 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
21852 doc: /* List of Functions to call before redisplaying a window with scrolling.
21853 Each function is called with two arguments, the window
21854 and its new display-start position. Note that the value of `window-end'
21855 is not valid when these functions are called. */);
21856 Vwindow_scroll_functions = Qnil;
21857
21858 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
21859 doc: /* *Non-nil means autoselect window with mouse pointer. */);
21860 mouse_autoselect_window = 0;
21861
21862 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
21863 doc: /* *Non-nil means automatically resize tool-bars.
21864 This increases a tool-bar's height if not all tool-bar items are visible.
21865 It decreases a tool-bar's height when it would display blank lines
21866 otherwise. */);
21867 auto_resize_tool_bars_p = 1;
21868
21869 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
21870 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21871 auto_raise_tool_bar_buttons_p = 1;
21872
21873 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
21874 doc: /* *Margin around tool-bar buttons in pixels.
21875 If an integer, use that for both horizontal and vertical margins.
21876 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21877 HORZ specifying the horizontal margin, and VERT specifying the
21878 vertical margin. */);
21879 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
21880
21881 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
21882 doc: /* *Relief thickness of tool-bar buttons. */);
21883 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
21884
21885 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
21886 doc: /* List of functions to call to fontify regions of text.
21887 Each function is called with one argument POS. Functions must
21888 fontify a region starting at POS in the current buffer, and give
21889 fontified regions the property `fontified'. */);
21890 Vfontification_functions = Qnil;
21891 Fmake_variable_buffer_local (Qfontification_functions);
21892
21893 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21894 &unibyte_display_via_language_environment,
21895 doc: /* *Non-nil means display unibyte text according to language environment.
21896 Specifically this means that unibyte non-ASCII characters
21897 are displayed by converting them to the equivalent multibyte characters
21898 according to the current language environment. As a result, they are
21899 displayed according to the current fontset. */);
21900 unibyte_display_via_language_environment = 0;
21901
21902 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
21903 doc: /* *Maximum height for resizing mini-windows.
21904 If a float, it specifies a fraction of the mini-window frame's height.
21905 If an integer, it specifies a number of lines. */);
21906 Vmax_mini_window_height = make_float (0.25);
21907
21908 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
21909 doc: /* *How to resize mini-windows.
21910 A value of nil means don't automatically resize mini-windows.
21911 A value of t means resize them to fit the text displayed in them.
21912 A value of `grow-only', the default, means let mini-windows grow
21913 only, until their display becomes empty, at which point the windows
21914 go back to their normal size. */);
21915 Vresize_mini_windows = Qgrow_only;
21916
21917 DEFVAR_LISP ("cursor-in-non-selected-windows",
21918 &Vcursor_in_non_selected_windows,
21919 doc: /* *Cursor type to display in non-selected windows.
21920 t means to use hollow box cursor. See `cursor-type' for other values. */);
21921 Vcursor_in_non_selected_windows = Qt;
21922
21923 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
21924 doc: /* Alist specifying how to blink the cursor off.
21925 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21926 `cursor-type' frame-parameter or variable equals ON-STATE,
21927 comparing using `equal', Emacs uses OFF-STATE to specify
21928 how to blink it off. */);
21929 Vblink_cursor_alist = Qnil;
21930
21931 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
21932 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
21933 automatic_hscrolling_p = 1;
21934
21935 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
21936 doc: /* *How many columns away from the window edge point is allowed to get
21937 before automatic hscrolling will horizontally scroll the window. */);
21938 hscroll_margin = 5;
21939
21940 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
21941 doc: /* *How many columns to scroll the window when point gets too close to the edge.
21942 When point is less than `automatic-hscroll-margin' columns from the window
21943 edge, automatic hscrolling will scroll the window by the amount of columns
21944 determined by this variable. If its value is a positive integer, scroll that
21945 many columns. If it's a positive floating-point number, it specifies the
21946 fraction of the window's width to scroll. If it's nil or zero, point will be
21947 centered horizontally after the scroll. Any other value, including negative
21948 numbers, are treated as if the value were zero.
21949
21950 Automatic hscrolling always moves point outside the scroll margin, so if
21951 point was more than scroll step columns inside the margin, the window will
21952 scroll more than the value given by the scroll step.
21953
21954 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21955 and `scroll-right' overrides this variable's effect. */);
21956 Vhscroll_step = make_number (0);
21957
21958 DEFVAR_LISP ("image-types", &Vimage_types,
21959 doc: /* List of supported image types.
21960 Each element of the list is a symbol for a supported image type. */);
21961 Vimage_types = Qnil;
21962
21963 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
21964 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
21965 Bind this around calls to `message' to let it take effect. */);
21966 message_truncate_lines = 0;
21967
21968 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
21969 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21970 Can be used to update submenus whose contents should vary. */);
21971 Vmenu_bar_update_hook = Qnil;
21972
21973 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
21974 doc: /* Non-nil means don't update menu bars. Internal use only. */);
21975 inhibit_menubar_update = 0;
21976
21977 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
21978 doc: /* Non-nil means don't eval Lisp during redisplay. */);
21979 inhibit_eval_during_redisplay = 0;
21980
21981 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
21982 doc: /* Non-nil means don't free realized faces. Internal use only. */);
21983 inhibit_free_realized_faces = 0;
21984
21985 #if GLYPH_DEBUG
21986 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
21987 doc: /* Inhibit try_window_id display optimization. */);
21988 inhibit_try_window_id = 0;
21989
21990 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
21991 doc: /* Inhibit try_window_reusing display optimization. */);
21992 inhibit_try_window_reusing = 0;
21993
21994 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
21995 doc: /* Inhibit try_cursor_movement display optimization. */);
21996 inhibit_try_cursor_movement = 0;
21997 #endif /* GLYPH_DEBUG */
21998 }
21999
22000
22001 /* Initialize this module when Emacs starts. */
22002
22003 void
22004 init_xdisp ()
22005 {
22006 Lisp_Object root_window;
22007 struct window *mini_w;
22008
22009 current_header_line_height = current_mode_line_height = -1;
22010
22011 CHARPOS (this_line_start_pos) = 0;
22012
22013 mini_w = XWINDOW (minibuf_window);
22014 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22015
22016 if (!noninteractive)
22017 {
22018 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22019 int i;
22020
22021 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22022 set_window_height (root_window,
22023 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22024 0);
22025 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22026 set_window_height (minibuf_window, 1, 0);
22027
22028 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22029 mini_w->total_cols = make_number (FRAME_COLS (f));
22030
22031 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22032 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22033 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22034
22035 /* The default ellipsis glyphs `...'. */
22036 for (i = 0; i < 3; ++i)
22037 default_invis_vector[i] = make_number ('.');
22038 }
22039
22040 {
22041 /* Allocate the buffer for frame titles.
22042 Also used for `format-mode-line'. */
22043 int size = 100;
22044 frame_title_buf = (char *) xmalloc (size);
22045 frame_title_buf_end = frame_title_buf + size;
22046 frame_title_ptr = NULL;
22047 }
22048
22049 help_echo_showing_p = 0;
22050 }
22051
22052
22053 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22054 (do not change this comment) */