Lisp_Object/int mixup.
[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 Qmargin, Qpointer;
305 extern Lisp_Object Qheight;
306 extern Lisp_Object QCwidth, QCheight, QCascent;
307 extern Lisp_Object Qscroll_bar;
308
309 /* Non-nil means highlight trailing whitespace. */
310
311 Lisp_Object Vshow_trailing_whitespace;
312
313 #ifdef HAVE_WINDOW_SYSTEM
314 extern Lisp_Object Voverflow_newline_into_fringe;
315
316 /* Test if overflow newline into fringe. Called with iterator IT
317 at or past right window margin, and with IT->current_x set. */
318
319 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
320 (!NILP (Voverflow_newline_into_fringe) \
321 && FRAME_WINDOW_P (it->f) \
322 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
323 && it->current_x == it->last_visible_x)
324
325 #endif /* HAVE_WINDOW_SYSTEM */
326
327 /* Non-nil means show the text cursor in void text areas
328 i.e. in blank areas after eol and eob. This used to be
329 the default in 21.3. */
330
331 Lisp_Object Vvoid_text_area_pointer;
332
333 /* Name of the face used to highlight trailing whitespace. */
334
335 Lisp_Object Qtrailing_whitespace;
336
337 /* The symbol `image' which is the car of the lists used to represent
338 images in Lisp. */
339
340 Lisp_Object Qimage;
341
342 /* The image map types. */
343 Lisp_Object QCmap, QCpointer;
344 Lisp_Object Qrect, Qcircle, Qpoly;
345
346 /* Non-zero means print newline to stdout before next mini-buffer
347 message. */
348
349 int noninteractive_need_newline;
350
351 /* Non-zero means print newline to message log before next message. */
352
353 static int message_log_need_newline;
354
355 /* Three markers that message_dolog uses.
356 It could allocate them itself, but that causes trouble
357 in handling memory-full errors. */
358 static Lisp_Object message_dolog_marker1;
359 static Lisp_Object message_dolog_marker2;
360 static Lisp_Object message_dolog_marker3;
361 \f
362 /* The buffer position of the first character appearing entirely or
363 partially on the line of the selected window which contains the
364 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
365 redisplay optimization in redisplay_internal. */
366
367 static struct text_pos this_line_start_pos;
368
369 /* Number of characters past the end of the line above, including the
370 terminating newline. */
371
372 static struct text_pos this_line_end_pos;
373
374 /* The vertical positions and the height of this line. */
375
376 static int this_line_vpos;
377 static int this_line_y;
378 static int this_line_pixel_height;
379
380 /* X position at which this display line starts. Usually zero;
381 negative if first character is partially visible. */
382
383 static int this_line_start_x;
384
385 /* Buffer that this_line_.* variables are referring to. */
386
387 static struct buffer *this_line_buffer;
388
389 /* Nonzero means truncate lines in all windows less wide than the
390 frame. */
391
392 int truncate_partial_width_windows;
393
394 /* A flag to control how to display unibyte 8-bit character. */
395
396 int unibyte_display_via_language_environment;
397
398 /* Nonzero means we have more than one non-mini-buffer-only frame.
399 Not guaranteed to be accurate except while parsing
400 frame-title-format. */
401
402 int multiple_frames;
403
404 Lisp_Object Vglobal_mode_string;
405
406 /* Marker for where to display an arrow on top of the buffer text. */
407
408 Lisp_Object Voverlay_arrow_position;
409
410 /* String to display for the arrow. Only used on terminal frames. */
411
412 Lisp_Object Voverlay_arrow_string;
413
414 /* Values of those variables at last redisplay. However, if
415 Voverlay_arrow_position is a marker, last_arrow_position is its
416 numerical position. */
417
418 static Lisp_Object last_arrow_position, last_arrow_string;
419
420 /* Like mode-line-format, but for the title bar on a visible frame. */
421
422 Lisp_Object Vframe_title_format;
423
424 /* Like mode-line-format, but for the title bar on an iconified frame. */
425
426 Lisp_Object Vicon_title_format;
427
428 /* List of functions to call when a window's size changes. These
429 functions get one arg, a frame on which one or more windows' sizes
430 have changed. */
431
432 static Lisp_Object Vwindow_size_change_functions;
433
434 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
435
436 /* Nonzero if overlay arrow has been displayed once in this window. */
437
438 static int overlay_arrow_seen;
439
440 /* Nonzero means highlight the region even in nonselected windows. */
441
442 int highlight_nonselected_windows;
443
444 /* If cursor motion alone moves point off frame, try scrolling this
445 many lines up or down if that will bring it back. */
446
447 static EMACS_INT scroll_step;
448
449 /* Nonzero means scroll just far enough to bring point back on the
450 screen, when appropriate. */
451
452 static EMACS_INT scroll_conservatively;
453
454 /* Recenter the window whenever point gets within this many lines of
455 the top or bottom of the window. This value is translated into a
456 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
457 that there is really a fixed pixel height scroll margin. */
458
459 EMACS_INT scroll_margin;
460
461 /* Number of windows showing the buffer of the selected window (or
462 another buffer with the same base buffer). keyboard.c refers to
463 this. */
464
465 int buffer_shared;
466
467 /* Vector containing glyphs for an ellipsis `...'. */
468
469 static Lisp_Object default_invis_vector[3];
470
471 /* Zero means display the mode-line/header-line/menu-bar in the default face
472 (this slightly odd definition is for compatibility with previous versions
473 of emacs), non-zero means display them using their respective faces.
474
475 This variable is deprecated. */
476
477 int mode_line_inverse_video;
478
479 /* Prompt to display in front of the mini-buffer contents. */
480
481 Lisp_Object minibuf_prompt;
482
483 /* Width of current mini-buffer prompt. Only set after display_line
484 of the line that contains the prompt. */
485
486 int minibuf_prompt_width;
487
488 /* This is the window where the echo area message was displayed. It
489 is always a mini-buffer window, but it may not be the same window
490 currently active as a mini-buffer. */
491
492 Lisp_Object echo_area_window;
493
494 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
495 pushes the current message and the value of
496 message_enable_multibyte on the stack, the function restore_message
497 pops the stack and displays MESSAGE again. */
498
499 Lisp_Object Vmessage_stack;
500
501 /* Nonzero means multibyte characters were enabled when the echo area
502 message was specified. */
503
504 int message_enable_multibyte;
505
506 /* Nonzero if we should redraw the mode lines on the next redisplay. */
507
508 int update_mode_lines;
509
510 /* Nonzero if window sizes or contents have changed since last
511 redisplay that finished. */
512
513 int windows_or_buffers_changed;
514
515 /* Nonzero means a frame's cursor type has been changed. */
516
517 int cursor_type_changed;
518
519 /* Nonzero after display_mode_line if %l was used and it displayed a
520 line number. */
521
522 int line_number_displayed;
523
524 /* Maximum buffer size for which to display line numbers. */
525
526 Lisp_Object Vline_number_display_limit;
527
528 /* Line width to consider when repositioning for line number display. */
529
530 static EMACS_INT line_number_display_limit_width;
531
532 /* Number of lines to keep in the message log buffer. t means
533 infinite. nil means don't log at all. */
534
535 Lisp_Object Vmessage_log_max;
536
537 /* The name of the *Messages* buffer, a string. */
538
539 static Lisp_Object Vmessages_buffer_name;
540
541 /* Current, index 0, and last displayed echo area message. Either
542 buffers from echo_buffers, or nil to indicate no message. */
543
544 Lisp_Object echo_area_buffer[2];
545
546 /* The buffers referenced from echo_area_buffer. */
547
548 static Lisp_Object echo_buffer[2];
549
550 /* A vector saved used in with_area_buffer to reduce consing. */
551
552 static Lisp_Object Vwith_echo_area_save_vector;
553
554 /* Non-zero means display_echo_area should display the last echo area
555 message again. Set by redisplay_preserve_echo_area. */
556
557 static int display_last_displayed_message_p;
558
559 /* Nonzero if echo area is being used by print; zero if being used by
560 message. */
561
562 int message_buf_print;
563
564 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
565
566 Lisp_Object Qinhibit_menubar_update;
567 int inhibit_menubar_update;
568
569 /* Maximum height for resizing mini-windows. Either a float
570 specifying a fraction of the available height, or an integer
571 specifying a number of lines. */
572
573 Lisp_Object Vmax_mini_window_height;
574
575 /* Non-zero means messages should be displayed with truncated
576 lines instead of being continued. */
577
578 int message_truncate_lines;
579 Lisp_Object Qmessage_truncate_lines;
580
581 /* Set to 1 in clear_message to make redisplay_internal aware
582 of an emptied echo area. */
583
584 static int message_cleared_p;
585
586 /* Non-zero means we want a hollow cursor in windows that are not
587 selected. Zero means there's no cursor in such windows. */
588
589 Lisp_Object Vcursor_in_non_selected_windows;
590 Lisp_Object Qcursor_in_non_selected_windows;
591
592 /* How to blink the default frame cursor off. */
593 Lisp_Object Vblink_cursor_alist;
594
595 /* A scratch glyph row with contents used for generating truncation
596 glyphs. Also used in direct_output_for_insert. */
597
598 #define MAX_SCRATCH_GLYPHS 100
599 struct glyph_row scratch_glyph_row;
600 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
601
602 /* Ascent and height of the last line processed by move_it_to. */
603
604 static int last_max_ascent, last_height;
605
606 /* Non-zero if there's a help-echo in the echo area. */
607
608 int help_echo_showing_p;
609
610 /* If >= 0, computed, exact values of mode-line and header-line height
611 to use in the macros CURRENT_MODE_LINE_HEIGHT and
612 CURRENT_HEADER_LINE_HEIGHT. */
613
614 int current_mode_line_height, current_header_line_height;
615
616 /* The maximum distance to look ahead for text properties. Values
617 that are too small let us call compute_char_face and similar
618 functions too often which is expensive. Values that are too large
619 let us call compute_char_face and alike too often because we
620 might not be interested in text properties that far away. */
621
622 #define TEXT_PROP_DISTANCE_LIMIT 100
623
624 #if GLYPH_DEBUG
625
626 /* Variables to turn off display optimizations from Lisp. */
627
628 int inhibit_try_window_id, inhibit_try_window_reusing;
629 int inhibit_try_cursor_movement;
630
631 /* Non-zero means print traces of redisplay if compiled with
632 GLYPH_DEBUG != 0. */
633
634 int trace_redisplay_p;
635
636 #endif /* GLYPH_DEBUG */
637
638 #ifdef DEBUG_TRACE_MOVE
639 /* Non-zero means trace with TRACE_MOVE to stderr. */
640 int trace_move;
641
642 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
643 #else
644 #define TRACE_MOVE(x) (void) 0
645 #endif
646
647 /* Non-zero means automatically scroll windows horizontally to make
648 point visible. */
649
650 int automatic_hscrolling_p;
651
652 /* How close to the margin can point get before the window is scrolled
653 horizontally. */
654 EMACS_INT hscroll_margin;
655
656 /* How much to scroll horizontally when point is inside the above margin. */
657 Lisp_Object Vhscroll_step;
658
659 /* A list of symbols, one for each supported image type. */
660
661 Lisp_Object Vimage_types;
662
663 /* The variable `resize-mini-windows'. If nil, don't resize
664 mini-windows. If t, always resize them to fit the text they
665 display. If `grow-only', let mini-windows grow only until they
666 become empty. */
667
668 Lisp_Object Vresize_mini_windows;
669
670 /* Buffer being redisplayed -- for redisplay_window_error. */
671
672 struct buffer *displayed_buffer;
673
674 /* Value returned from text property handlers (see below). */
675
676 enum prop_handled
677 {
678 HANDLED_NORMALLY,
679 HANDLED_RECOMPUTE_PROPS,
680 HANDLED_OVERLAY_STRING_CONSUMED,
681 HANDLED_RETURN
682 };
683
684 /* A description of text properties that redisplay is interested
685 in. */
686
687 struct props
688 {
689 /* The name of the property. */
690 Lisp_Object *name;
691
692 /* A unique index for the property. */
693 enum prop_idx idx;
694
695 /* A handler function called to set up iterator IT from the property
696 at IT's current position. Value is used to steer handle_stop. */
697 enum prop_handled (*handler) P_ ((struct it *it));
698 };
699
700 static enum prop_handled handle_face_prop P_ ((struct it *));
701 static enum prop_handled handle_invisible_prop P_ ((struct it *));
702 static enum prop_handled handle_display_prop P_ ((struct it *));
703 static enum prop_handled handle_composition_prop P_ ((struct it *));
704 static enum prop_handled handle_overlay_change P_ ((struct it *));
705 static enum prop_handled handle_fontified_prop P_ ((struct it *));
706
707 /* Properties handled by iterators. */
708
709 static struct props it_props[] =
710 {
711 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
712 /* Handle `face' before `display' because some sub-properties of
713 `display' need to know the face. */
714 {&Qface, FACE_PROP_IDX, handle_face_prop},
715 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
716 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
717 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
718 {NULL, 0, NULL}
719 };
720
721 /* Value is the position described by X. If X is a marker, value is
722 the marker_position of X. Otherwise, value is X. */
723
724 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
725
726 /* Enumeration returned by some move_it_.* functions internally. */
727
728 enum move_it_result
729 {
730 /* Not used. Undefined value. */
731 MOVE_UNDEFINED,
732
733 /* Move ended at the requested buffer position or ZV. */
734 MOVE_POS_MATCH_OR_ZV,
735
736 /* Move ended at the requested X pixel position. */
737 MOVE_X_REACHED,
738
739 /* Move within a line ended at the end of a line that must be
740 continued. */
741 MOVE_LINE_CONTINUED,
742
743 /* Move within a line ended at the end of a line that would
744 be displayed truncated. */
745 MOVE_LINE_TRUNCATED,
746
747 /* Move within a line ended at a line end. */
748 MOVE_NEWLINE_OR_CR
749 };
750
751 /* This counter is used to clear the face cache every once in a while
752 in redisplay_internal. It is incremented for each redisplay.
753 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
754 cleared. */
755
756 #define CLEAR_FACE_CACHE_COUNT 500
757 static int clear_face_cache_count;
758
759 /* Record the previous terminal frame we displayed. */
760
761 static struct frame *previous_terminal_frame;
762
763 /* Non-zero while redisplay_internal is in progress. */
764
765 int redisplaying_p;
766
767 /* Non-zero means don't free realized faces. Bound while freeing
768 realized faces is dangerous because glyph matrices might still
769 reference them. */
770
771 int inhibit_free_realized_faces;
772 Lisp_Object Qinhibit_free_realized_faces;
773
774 /* If a string, XTread_socket generates an event to display that string.
775 (The display is done in read_char.) */
776
777 Lisp_Object help_echo_string;
778 Lisp_Object help_echo_window;
779 Lisp_Object help_echo_object;
780 int help_echo_pos;
781
782 /* Temporary variable for XTread_socket. */
783
784 Lisp_Object previous_help_echo_string;
785
786
787 \f
788 /* Function prototypes. */
789
790 static void setup_for_ellipsis P_ ((struct it *));
791 static void mark_window_display_accurate_1 P_ ((struct window *, int));
792 static int single_display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
793 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
794 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
795 static int redisplay_mode_lines P_ ((Lisp_Object, int));
796 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
797
798 #if 0
799 static int invisible_text_between_p P_ ((struct it *, int, int));
800 #endif
801
802 static int next_element_from_ellipsis P_ ((struct it *));
803 static void pint2str P_ ((char *, int, int));
804 static void pint2hrstr P_ ((char *, int, int));
805 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
806 struct text_pos));
807 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
808 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
809 static void store_frame_title_char P_ ((char));
810 static int store_frame_title P_ ((const unsigned char *, int, int));
811 static void x_consider_frame_title P_ ((Lisp_Object));
812 static void handle_stop P_ ((struct it *));
813 static int tool_bar_lines_needed P_ ((struct frame *));
814 static int single_display_prop_intangible_p P_ ((Lisp_Object));
815 static void ensure_echo_area_buffers P_ ((void));
816 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
817 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
818 static int with_echo_area_buffer P_ ((struct window *, int,
819 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
820 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
821 static void clear_garbaged_frames P_ ((void));
822 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
823 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
824 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
825 static int display_echo_area P_ ((struct window *));
826 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
827 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
828 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
829 static int string_char_and_length P_ ((const unsigned char *, int, int *));
830 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
831 struct text_pos));
832 static int compute_window_start_on_continuation_line P_ ((struct window *));
833 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
834 static void insert_left_trunc_glyphs P_ ((struct it *));
835 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *));
836 static void extend_face_to_end_of_line P_ ((struct it *));
837 static int append_space P_ ((struct it *, int));
838 static int make_cursor_line_fully_visible P_ ((struct window *));
839 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
840 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
841 static int trailing_whitespace_p P_ ((int));
842 static int message_log_check_duplicate P_ ((int, int, int, int));
843 static void push_it P_ ((struct it *));
844 static void pop_it P_ ((struct it *));
845 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
846 static void select_frame_for_redisplay P_ ((Lisp_Object));
847 static void redisplay_internal P_ ((int));
848 static int echo_area_display P_ ((int));
849 static void redisplay_windows P_ ((Lisp_Object));
850 static void redisplay_window P_ ((Lisp_Object, int));
851 static Lisp_Object redisplay_window_error ();
852 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
853 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
854 static void update_menu_bar P_ ((struct frame *, int));
855 static int try_window_reusing_current_matrix P_ ((struct window *));
856 static int try_window_id P_ ((struct window *));
857 static int display_line P_ ((struct it *));
858 static int display_mode_lines P_ ((struct window *));
859 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
860 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
861 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
862 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
863 static void display_menu_bar P_ ((struct window *));
864 static int display_count_lines P_ ((int, int, int, int, int *));
865 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
866 int, int, struct it *, int, int, int, int));
867 static void compute_line_metrics P_ ((struct it *));
868 static void run_redisplay_end_trigger_hook P_ ((struct it *));
869 static int get_overlay_strings P_ ((struct it *, int));
870 static void next_overlay_string P_ ((struct it *));
871 static void reseat P_ ((struct it *, struct text_pos, int));
872 static void reseat_1 P_ ((struct it *, struct text_pos, int));
873 static void back_to_previous_visible_line_start P_ ((struct it *));
874 static void reseat_at_previous_visible_line_start P_ ((struct it *));
875 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
876 static int next_element_from_display_vector P_ ((struct it *));
877 static int next_element_from_string P_ ((struct it *));
878 static int next_element_from_c_string P_ ((struct it *));
879 static int next_element_from_buffer P_ ((struct it *));
880 static int next_element_from_composition P_ ((struct it *));
881 static int next_element_from_image P_ ((struct it *));
882 static int next_element_from_stretch P_ ((struct it *));
883 static void load_overlay_strings P_ ((struct it *, int));
884 static int init_from_display_pos P_ ((struct it *, struct window *,
885 struct display_pos *));
886 static void reseat_to_string P_ ((struct it *, unsigned char *,
887 Lisp_Object, int, int, int, int));
888 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
889 int, int, int));
890 void move_it_vertically_backward P_ ((struct it *, int));
891 static void init_to_row_start P_ ((struct it *, struct window *,
892 struct glyph_row *));
893 static int init_to_row_end P_ ((struct it *, struct window *,
894 struct glyph_row *));
895 static void back_to_previous_line_start P_ ((struct it *));
896 static int forward_to_next_line_start P_ ((struct it *, int *));
897 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
898 Lisp_Object, int));
899 static struct text_pos string_pos P_ ((int, Lisp_Object));
900 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
901 static int number_of_chars P_ ((unsigned char *, int));
902 static void compute_stop_pos P_ ((struct it *));
903 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
904 Lisp_Object));
905 static int face_before_or_after_it_pos P_ ((struct it *, int));
906 static int next_overlay_change P_ ((int));
907 static int handle_single_display_prop P_ ((struct it *, Lisp_Object,
908 Lisp_Object, struct text_pos *,
909 int));
910 static int underlying_face_id P_ ((struct it *));
911 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
912 struct window *));
913
914 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
915 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
916
917 #ifdef HAVE_WINDOW_SYSTEM
918
919 static void update_tool_bar P_ ((struct frame *, int));
920 static void build_desired_tool_bar_string P_ ((struct frame *f));
921 static int redisplay_tool_bar P_ ((struct frame *));
922 static void display_tool_bar_line P_ ((struct it *));
923 static void notice_overwritten_cursor P_ ((struct window *,
924 enum glyph_row_area,
925 int, int, int, int));
926
927
928
929 #endif /* HAVE_WINDOW_SYSTEM */
930
931 \f
932 /***********************************************************************
933 Window display dimensions
934 ***********************************************************************/
935
936 /* Return the bottom boundary y-position for text lines in window W.
937 This is the first y position at which a line cannot start.
938 It is relative to the top of the window.
939
940 This is the height of W minus the height of a mode line, if any. */
941
942 INLINE int
943 window_text_bottom_y (w)
944 struct window *w;
945 {
946 int height = WINDOW_TOTAL_HEIGHT (w);
947
948 if (WINDOW_WANTS_MODELINE_P (w))
949 height -= CURRENT_MODE_LINE_HEIGHT (w);
950 return height;
951 }
952
953 /* Return the pixel width of display area AREA of window W. AREA < 0
954 means return the total width of W, not including fringes to
955 the left and right of the window. */
956
957 INLINE int
958 window_box_width (w, area)
959 struct window *w;
960 int area;
961 {
962 int cols = XFASTINT (w->total_cols);
963 int pixels = 0;
964
965 if (!w->pseudo_window_p)
966 {
967 cols -= WINDOW_SCROLL_BAR_COLS (w);
968
969 if (area == TEXT_AREA)
970 {
971 if (INTEGERP (w->left_margin_cols))
972 cols -= XFASTINT (w->left_margin_cols);
973 if (INTEGERP (w->right_margin_cols))
974 cols -= XFASTINT (w->right_margin_cols);
975 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
976 }
977 else if (area == LEFT_MARGIN_AREA)
978 {
979 cols = (INTEGERP (w->left_margin_cols)
980 ? XFASTINT (w->left_margin_cols) : 0);
981 pixels = 0;
982 }
983 else if (area == RIGHT_MARGIN_AREA)
984 {
985 cols = (INTEGERP (w->right_margin_cols)
986 ? XFASTINT (w->right_margin_cols) : 0);
987 pixels = 0;
988 }
989 }
990
991 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
992 }
993
994
995 /* Return the pixel height of the display area of window W, not
996 including mode lines of W, if any. */
997
998 INLINE int
999 window_box_height (w)
1000 struct window *w;
1001 {
1002 struct frame *f = XFRAME (w->frame);
1003 int height = WINDOW_TOTAL_HEIGHT (w);
1004
1005 xassert (height >= 0);
1006
1007 /* Note: the code below that determines the mode-line/header-line
1008 height is essentially the same as that contained in the macro
1009 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1010 the appropriate glyph row has its `mode_line_p' flag set,
1011 and if it doesn't, uses estimate_mode_line_height instead. */
1012
1013 if (WINDOW_WANTS_MODELINE_P (w))
1014 {
1015 struct glyph_row *ml_row
1016 = (w->current_matrix && w->current_matrix->rows
1017 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1018 : 0);
1019 if (ml_row && ml_row->mode_line_p)
1020 height -= ml_row->height;
1021 else
1022 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1023 }
1024
1025 if (WINDOW_WANTS_HEADER_LINE_P (w))
1026 {
1027 struct glyph_row *hl_row
1028 = (w->current_matrix && w->current_matrix->rows
1029 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1030 : 0);
1031 if (hl_row && hl_row->mode_line_p)
1032 height -= hl_row->height;
1033 else
1034 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1035 }
1036
1037 /* With a very small font and a mode-line that's taller than
1038 default, we might end up with a negative height. */
1039 return max (0, height);
1040 }
1041
1042 /* Return the window-relative coordinate of the left edge of display
1043 area AREA of window W. AREA < 0 means return the left edge of the
1044 whole window, to the right of the left fringe of W. */
1045
1046 INLINE int
1047 window_box_left_offset (w, area)
1048 struct window *w;
1049 int area;
1050 {
1051 int x;
1052
1053 if (w->pseudo_window_p)
1054 return 0;
1055
1056 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1057
1058 if (area == TEXT_AREA)
1059 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1060 + window_box_width (w, LEFT_MARGIN_AREA));
1061 else if (area == RIGHT_MARGIN_AREA)
1062 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1063 + window_box_width (w, LEFT_MARGIN_AREA)
1064 + window_box_width (w, TEXT_AREA)
1065 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1066 ? 0
1067 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1068 else if (area == LEFT_MARGIN_AREA
1069 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1070 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1071
1072 return x;
1073 }
1074
1075
1076 /* Return the window-relative coordinate of the right edge of display
1077 area AREA of window W. AREA < 0 means return the left edge of the
1078 whole window, to the left of the right fringe of W. */
1079
1080 INLINE int
1081 window_box_right_offset (w, area)
1082 struct window *w;
1083 int area;
1084 {
1085 return window_box_left_offset (w, area) + window_box_width (w, area);
1086 }
1087
1088 /* Return the frame-relative coordinate of the left edge of display
1089 area AREA of window W. AREA < 0 means return the left edge of the
1090 whole window, to the right of the left fringe of W. */
1091
1092 INLINE int
1093 window_box_left (w, area)
1094 struct window *w;
1095 int area;
1096 {
1097 struct frame *f = XFRAME (w->frame);
1098 int x;
1099
1100 if (w->pseudo_window_p)
1101 return FRAME_INTERNAL_BORDER_WIDTH (f);
1102
1103 x = (WINDOW_LEFT_EDGE_X (w)
1104 + window_box_left_offset (w, area));
1105
1106 return x;
1107 }
1108
1109
1110 /* Return the frame-relative coordinate of the right edge of display
1111 area AREA of window W. AREA < 0 means return the left edge of the
1112 whole window, to the left of the right fringe of W. */
1113
1114 INLINE int
1115 window_box_right (w, area)
1116 struct window *w;
1117 int area;
1118 {
1119 return window_box_left (w, area) + window_box_width (w, area);
1120 }
1121
1122 /* Get the bounding box of the display area AREA of window W, without
1123 mode lines, in frame-relative coordinates. AREA < 0 means the
1124 whole window, not including the left and right fringes of
1125 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1126 coordinates of the upper-left corner of the box. Return in
1127 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1128
1129 INLINE void
1130 window_box (w, area, box_x, box_y, box_width, box_height)
1131 struct window *w;
1132 int area;
1133 int *box_x, *box_y, *box_width, *box_height;
1134 {
1135 if (box_width)
1136 *box_width = window_box_width (w, area);
1137 if (box_height)
1138 *box_height = window_box_height (w);
1139 if (box_x)
1140 *box_x = window_box_left (w, area);
1141 if (box_y)
1142 {
1143 *box_y = WINDOW_TOP_EDGE_Y (w);
1144 if (WINDOW_WANTS_HEADER_LINE_P (w))
1145 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1146 }
1147 }
1148
1149
1150 /* Get the bounding box of the display area AREA of window W, without
1151 mode lines. AREA < 0 means the whole window, not including the
1152 left and right fringe of the window. Return in *TOP_LEFT_X
1153 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1154 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1155 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1156 box. */
1157
1158 INLINE void
1159 window_box_edges (w, area, top_left_x, top_left_y,
1160 bottom_right_x, bottom_right_y)
1161 struct window *w;
1162 int area;
1163 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1164 {
1165 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1166 bottom_right_y);
1167 *bottom_right_x += *top_left_x;
1168 *bottom_right_y += *top_left_y;
1169 }
1170
1171
1172 \f
1173 /***********************************************************************
1174 Utilities
1175 ***********************************************************************/
1176
1177 /* Return the bottom y-position of the line the iterator IT is in.
1178 This can modify IT's settings. */
1179
1180 int
1181 line_bottom_y (it)
1182 struct it *it;
1183 {
1184 int line_height = it->max_ascent + it->max_descent;
1185 int line_top_y = it->current_y;
1186
1187 if (line_height == 0)
1188 {
1189 if (last_height)
1190 line_height = last_height;
1191 else if (IT_CHARPOS (*it) < ZV)
1192 {
1193 move_it_by_lines (it, 1, 1);
1194 line_height = (it->max_ascent || it->max_descent
1195 ? it->max_ascent + it->max_descent
1196 : last_height);
1197 }
1198 else
1199 {
1200 struct glyph_row *row = it->glyph_row;
1201
1202 /* Use the default character height. */
1203 it->glyph_row = NULL;
1204 it->what = IT_CHARACTER;
1205 it->c = ' ';
1206 it->len = 1;
1207 PRODUCE_GLYPHS (it);
1208 line_height = it->ascent + it->descent;
1209 it->glyph_row = row;
1210 }
1211 }
1212
1213 return line_top_y + line_height;
1214 }
1215
1216
1217 /* Return 1 if position CHARPOS is visible in window W. Set *FULLY to
1218 1 if POS is visible and the line containing POS is fully visible.
1219 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1220 and header-lines heights. */
1221
1222 int
1223 pos_visible_p (w, charpos, fully, exact_mode_line_heights_p)
1224 struct window *w;
1225 int charpos, *fully, exact_mode_line_heights_p;
1226 {
1227 struct it it;
1228 struct text_pos top;
1229 int visible_p;
1230 struct buffer *old_buffer = NULL;
1231
1232 if (XBUFFER (w->buffer) != current_buffer)
1233 {
1234 old_buffer = current_buffer;
1235 set_buffer_internal_1 (XBUFFER (w->buffer));
1236 }
1237
1238 *fully = visible_p = 0;
1239 SET_TEXT_POS_FROM_MARKER (top, w->start);
1240
1241 /* Compute exact mode line heights, if requested. */
1242 if (exact_mode_line_heights_p)
1243 {
1244 if (WINDOW_WANTS_MODELINE_P (w))
1245 current_mode_line_height
1246 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1247 current_buffer->mode_line_format);
1248
1249 if (WINDOW_WANTS_HEADER_LINE_P (w))
1250 current_header_line_height
1251 = display_mode_line (w, HEADER_LINE_FACE_ID,
1252 current_buffer->header_line_format);
1253 }
1254
1255 start_display (&it, w, top);
1256 move_it_to (&it, charpos, 0, it.last_visible_y, -1,
1257 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
1258
1259 /* Note that we may overshoot because of invisible text. */
1260 if (IT_CHARPOS (it) >= charpos)
1261 {
1262 int top_y = it.current_y;
1263 int bottom_y = line_bottom_y (&it);
1264 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1265
1266 if (top_y < window_top_y)
1267 visible_p = bottom_y > window_top_y;
1268 else if (top_y < it.last_visible_y)
1269 {
1270 visible_p = 1;
1271 *fully = bottom_y <= it.last_visible_y;
1272 }
1273 }
1274 else if (it.current_y + it.max_ascent + it.max_descent > it.last_visible_y)
1275 {
1276 move_it_by_lines (&it, 1, 0);
1277 if (charpos < IT_CHARPOS (it))
1278 {
1279 visible_p = 1;
1280 *fully = 0;
1281 }
1282 }
1283
1284 if (old_buffer)
1285 set_buffer_internal_1 (old_buffer);
1286
1287 current_header_line_height = current_mode_line_height = -1;
1288 return visible_p;
1289 }
1290
1291
1292 /* Return the next character from STR which is MAXLEN bytes long.
1293 Return in *LEN the length of the character. This is like
1294 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1295 we find one, we return a `?', but with the length of the invalid
1296 character. */
1297
1298 static INLINE int
1299 string_char_and_length (str, maxlen, len)
1300 const unsigned char *str;
1301 int maxlen, *len;
1302 {
1303 int c;
1304
1305 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1306 if (!CHAR_VALID_P (c, 1))
1307 /* We may not change the length here because other places in Emacs
1308 don't use this function, i.e. they silently accept invalid
1309 characters. */
1310 c = '?';
1311
1312 return c;
1313 }
1314
1315
1316
1317 /* Given a position POS containing a valid character and byte position
1318 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1319
1320 static struct text_pos
1321 string_pos_nchars_ahead (pos, string, nchars)
1322 struct text_pos pos;
1323 Lisp_Object string;
1324 int nchars;
1325 {
1326 xassert (STRINGP (string) && nchars >= 0);
1327
1328 if (STRING_MULTIBYTE (string))
1329 {
1330 int rest = SBYTES (string) - BYTEPOS (pos);
1331 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1332 int len;
1333
1334 while (nchars--)
1335 {
1336 string_char_and_length (p, rest, &len);
1337 p += len, rest -= len;
1338 xassert (rest >= 0);
1339 CHARPOS (pos) += 1;
1340 BYTEPOS (pos) += len;
1341 }
1342 }
1343 else
1344 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1345
1346 return pos;
1347 }
1348
1349
1350 /* Value is the text position, i.e. character and byte position,
1351 for character position CHARPOS in STRING. */
1352
1353 static INLINE struct text_pos
1354 string_pos (charpos, string)
1355 int charpos;
1356 Lisp_Object string;
1357 {
1358 struct text_pos pos;
1359 xassert (STRINGP (string));
1360 xassert (charpos >= 0);
1361 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1362 return pos;
1363 }
1364
1365
1366 /* Value is a text position, i.e. character and byte position, for
1367 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1368 means recognize multibyte characters. */
1369
1370 static struct text_pos
1371 c_string_pos (charpos, s, multibyte_p)
1372 int charpos;
1373 unsigned char *s;
1374 int multibyte_p;
1375 {
1376 struct text_pos pos;
1377
1378 xassert (s != NULL);
1379 xassert (charpos >= 0);
1380
1381 if (multibyte_p)
1382 {
1383 int rest = strlen (s), len;
1384
1385 SET_TEXT_POS (pos, 0, 0);
1386 while (charpos--)
1387 {
1388 string_char_and_length (s, rest, &len);
1389 s += len, rest -= len;
1390 xassert (rest >= 0);
1391 CHARPOS (pos) += 1;
1392 BYTEPOS (pos) += len;
1393 }
1394 }
1395 else
1396 SET_TEXT_POS (pos, charpos, charpos);
1397
1398 return pos;
1399 }
1400
1401
1402 /* Value is the number of characters in C string S. MULTIBYTE_P
1403 non-zero means recognize multibyte characters. */
1404
1405 static int
1406 number_of_chars (s, multibyte_p)
1407 unsigned char *s;
1408 int multibyte_p;
1409 {
1410 int nchars;
1411
1412 if (multibyte_p)
1413 {
1414 int rest = strlen (s), len;
1415 unsigned char *p = (unsigned char *) s;
1416
1417 for (nchars = 0; rest > 0; ++nchars)
1418 {
1419 string_char_and_length (p, rest, &len);
1420 rest -= len, p += len;
1421 }
1422 }
1423 else
1424 nchars = strlen (s);
1425
1426 return nchars;
1427 }
1428
1429
1430 /* Compute byte position NEWPOS->bytepos corresponding to
1431 NEWPOS->charpos. POS is a known position in string STRING.
1432 NEWPOS->charpos must be >= POS.charpos. */
1433
1434 static void
1435 compute_string_pos (newpos, pos, string)
1436 struct text_pos *newpos, pos;
1437 Lisp_Object string;
1438 {
1439 xassert (STRINGP (string));
1440 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1441
1442 if (STRING_MULTIBYTE (string))
1443 *newpos = string_pos_nchars_ahead (pos, string,
1444 CHARPOS (*newpos) - CHARPOS (pos));
1445 else
1446 BYTEPOS (*newpos) = CHARPOS (*newpos);
1447 }
1448
1449 /* EXPORT:
1450 Return an estimation of the pixel height of mode or top lines on
1451 frame F. FACE_ID specifies what line's height to estimate. */
1452
1453 int
1454 estimate_mode_line_height (f, face_id)
1455 struct frame *f;
1456 enum face_id face_id;
1457 {
1458 #ifdef HAVE_WINDOW_SYSTEM
1459 if (FRAME_WINDOW_P (f))
1460 {
1461 int height = FONT_HEIGHT (FRAME_FONT (f));
1462
1463 /* This function is called so early when Emacs starts that the face
1464 cache and mode line face are not yet initialized. */
1465 if (FRAME_FACE_CACHE (f))
1466 {
1467 struct face *face = FACE_FROM_ID (f, face_id);
1468 if (face)
1469 {
1470 if (face->font)
1471 height = FONT_HEIGHT (face->font);
1472 if (face->box_line_width > 0)
1473 height += 2 * face->box_line_width;
1474 }
1475 }
1476
1477 return height;
1478 }
1479 #endif
1480
1481 return 1;
1482 }
1483
1484 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1485 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1486 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1487 not force the value into range. */
1488
1489 void
1490 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1491 FRAME_PTR f;
1492 register int pix_x, pix_y;
1493 int *x, *y;
1494 NativeRectangle *bounds;
1495 int noclip;
1496 {
1497
1498 #ifdef HAVE_WINDOW_SYSTEM
1499 if (FRAME_WINDOW_P (f))
1500 {
1501 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1502 even for negative values. */
1503 if (pix_x < 0)
1504 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1505 if (pix_y < 0)
1506 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1507
1508 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1509 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1510
1511 if (bounds)
1512 STORE_NATIVE_RECT (*bounds,
1513 FRAME_COL_TO_PIXEL_X (f, pix_x),
1514 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1515 FRAME_COLUMN_WIDTH (f) - 1,
1516 FRAME_LINE_HEIGHT (f) - 1);
1517
1518 if (!noclip)
1519 {
1520 if (pix_x < 0)
1521 pix_x = 0;
1522 else if (pix_x > FRAME_TOTAL_COLS (f))
1523 pix_x = FRAME_TOTAL_COLS (f);
1524
1525 if (pix_y < 0)
1526 pix_y = 0;
1527 else if (pix_y > FRAME_LINES (f))
1528 pix_y = FRAME_LINES (f);
1529 }
1530 }
1531 #endif
1532
1533 *x = pix_x;
1534 *y = pix_y;
1535 }
1536
1537
1538 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1539 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1540 can't tell the positions because W's display is not up to date,
1541 return 0. */
1542
1543 int
1544 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1545 struct window *w;
1546 int hpos, vpos;
1547 int *frame_x, *frame_y;
1548 {
1549 #ifdef HAVE_WINDOW_SYSTEM
1550 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1551 {
1552 int success_p;
1553
1554 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1555 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1556
1557 if (display_completed)
1558 {
1559 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1560 struct glyph *glyph = row->glyphs[TEXT_AREA];
1561 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1562
1563 hpos = row->x;
1564 vpos = row->y;
1565 while (glyph < end)
1566 {
1567 hpos += glyph->pixel_width;
1568 ++glyph;
1569 }
1570
1571 /* If first glyph is partially visible, its first visible position is still 0. */
1572 if (hpos < 0)
1573 hpos = 0;
1574
1575 success_p = 1;
1576 }
1577 else
1578 {
1579 hpos = vpos = 0;
1580 success_p = 0;
1581 }
1582
1583 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1584 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1585 return success_p;
1586 }
1587 #endif
1588
1589 *frame_x = hpos;
1590 *frame_y = vpos;
1591 return 1;
1592 }
1593
1594
1595 #ifdef HAVE_WINDOW_SYSTEM
1596
1597 /* Find the glyph under window-relative coordinates X/Y in window W.
1598 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1599 strings. Return in *HPOS and *VPOS the row and column number of
1600 the glyph found. Return in *AREA the glyph area containing X.
1601 Value is a pointer to the glyph found or null if X/Y is not on
1602 text, or we can't tell because W's current matrix is not up to
1603 date. */
1604
1605 static struct glyph *
1606 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1607 struct window *w;
1608 int x, y;
1609 int *hpos, *vpos, *dx, *dy, *area;
1610 {
1611 struct glyph *glyph, *end;
1612 struct glyph_row *row = NULL;
1613 int x0, i;
1614
1615 /* Find row containing Y. Give up if some row is not enabled. */
1616 for (i = 0; i < w->current_matrix->nrows; ++i)
1617 {
1618 row = MATRIX_ROW (w->current_matrix, i);
1619 if (!row->enabled_p)
1620 return NULL;
1621 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1622 break;
1623 }
1624
1625 *vpos = i;
1626 *hpos = 0;
1627
1628 /* Give up if Y is not in the window. */
1629 if (i == w->current_matrix->nrows)
1630 return NULL;
1631
1632 /* Get the glyph area containing X. */
1633 if (w->pseudo_window_p)
1634 {
1635 *area = TEXT_AREA;
1636 x0 = 0;
1637 }
1638 else
1639 {
1640 if (x < window_box_left_offset (w, TEXT_AREA))
1641 {
1642 *area = LEFT_MARGIN_AREA;
1643 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1644 }
1645 else if (x < window_box_right_offset (w, TEXT_AREA))
1646 {
1647 *area = TEXT_AREA;
1648 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1649 }
1650 else
1651 {
1652 *area = RIGHT_MARGIN_AREA;
1653 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1654 }
1655 }
1656
1657 /* Find glyph containing X. */
1658 glyph = row->glyphs[*area];
1659 end = glyph + row->used[*area];
1660 x -= x0;
1661 while (glyph < end && x >= glyph->pixel_width)
1662 {
1663 x -= glyph->pixel_width;
1664 ++glyph;
1665 }
1666
1667 if (glyph == end)
1668 return NULL;
1669
1670 if (dx)
1671 {
1672 *dx = x;
1673 *dy = y - (row->y + row->ascent - glyph->ascent);
1674 }
1675
1676 *hpos = glyph - row->glyphs[*area];
1677 return glyph;
1678 }
1679
1680
1681 /* EXPORT:
1682 Convert frame-relative x/y to coordinates relative to window W.
1683 Takes pseudo-windows into account. */
1684
1685 void
1686 frame_to_window_pixel_xy (w, x, y)
1687 struct window *w;
1688 int *x, *y;
1689 {
1690 if (w->pseudo_window_p)
1691 {
1692 /* A pseudo-window is always full-width, and starts at the
1693 left edge of the frame, plus a frame border. */
1694 struct frame *f = XFRAME (w->frame);
1695 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1696 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1697 }
1698 else
1699 {
1700 *x -= WINDOW_LEFT_EDGE_X (w);
1701 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1702 }
1703 }
1704
1705 /* EXPORT:
1706 Return in *R the clipping rectangle for glyph string S. */
1707
1708 void
1709 get_glyph_string_clip_rect (s, nr)
1710 struct glyph_string *s;
1711 NativeRectangle *nr;
1712 {
1713 XRectangle r;
1714
1715 if (s->row->full_width_p)
1716 {
1717 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1718 r.x = WINDOW_LEFT_EDGE_X (s->w);
1719 r.width = WINDOW_TOTAL_WIDTH (s->w);
1720
1721 /* Unless displaying a mode or menu bar line, which are always
1722 fully visible, clip to the visible part of the row. */
1723 if (s->w->pseudo_window_p)
1724 r.height = s->row->visible_height;
1725 else
1726 r.height = s->height;
1727 }
1728 else
1729 {
1730 /* This is a text line that may be partially visible. */
1731 r.x = window_box_left (s->w, s->area);
1732 r.width = window_box_width (s->w, s->area);
1733 r.height = s->row->visible_height;
1734 }
1735
1736 /* If S draws overlapping rows, it's sufficient to use the top and
1737 bottom of the window for clipping because this glyph string
1738 intentionally draws over other lines. */
1739 if (s->for_overlaps_p)
1740 {
1741 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1742 r.height = window_text_bottom_y (s->w) - r.y;
1743 }
1744 else
1745 {
1746 /* Don't use S->y for clipping because it doesn't take partially
1747 visible lines into account. For example, it can be negative for
1748 partially visible lines at the top of a window. */
1749 if (!s->row->full_width_p
1750 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1751 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1752 else
1753 r.y = max (0, s->row->y);
1754
1755 /* If drawing a tool-bar window, draw it over the internal border
1756 at the top of the window. */
1757 if (s->w == XWINDOW (s->f->tool_bar_window))
1758 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1759 }
1760
1761 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1762
1763 /* If drawing the cursor, don't let glyph draw outside its
1764 advertised boundaries. Cleartype does this under some circumstances. */
1765 if (s->hl == DRAW_CURSOR)
1766 {
1767 struct glyph *glyph = s->first_glyph;
1768 int height;
1769
1770 if (s->x > r.x)
1771 {
1772 r.width -= s->x - r.x;
1773 r.x = s->x;
1774 }
1775 r.width = min (r.width, glyph->pixel_width);
1776
1777 /* Don't draw cursor glyph taller than our actual glyph. */
1778 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1779 if (height < r.height)
1780 {
1781 r.y = s->ybase + glyph->descent - height;
1782 r.height = height;
1783 }
1784 }
1785
1786 #ifdef CONVERT_FROM_XRECT
1787 CONVERT_FROM_XRECT (r, *nr);
1788 #else
1789 *nr = r;
1790 #endif
1791 }
1792
1793 #endif /* HAVE_WINDOW_SYSTEM */
1794
1795 \f
1796 /***********************************************************************
1797 Lisp form evaluation
1798 ***********************************************************************/
1799
1800 /* Error handler for safe_eval and safe_call. */
1801
1802 static Lisp_Object
1803 safe_eval_handler (arg)
1804 Lisp_Object arg;
1805 {
1806 add_to_log ("Error during redisplay: %s", arg, Qnil);
1807 return Qnil;
1808 }
1809
1810
1811 /* Evaluate SEXPR and return the result, or nil if something went
1812 wrong. Prevent redisplay during the evaluation. */
1813
1814 Lisp_Object
1815 safe_eval (sexpr)
1816 Lisp_Object sexpr;
1817 {
1818 Lisp_Object val;
1819
1820 if (inhibit_eval_during_redisplay)
1821 val = Qnil;
1822 else
1823 {
1824 int count = SPECPDL_INDEX ();
1825 struct gcpro gcpro1;
1826
1827 GCPRO1 (sexpr);
1828 specbind (Qinhibit_redisplay, Qt);
1829 /* Use Qt to ensure debugger does not run,
1830 so there is no possibility of wanting to redisplay. */
1831 val = internal_condition_case_1 (Feval, sexpr, Qt,
1832 safe_eval_handler);
1833 UNGCPRO;
1834 val = unbind_to (count, val);
1835 }
1836
1837 return val;
1838 }
1839
1840
1841 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1842 Return the result, or nil if something went wrong. Prevent
1843 redisplay during the evaluation. */
1844
1845 Lisp_Object
1846 safe_call (nargs, args)
1847 int nargs;
1848 Lisp_Object *args;
1849 {
1850 Lisp_Object val;
1851
1852 if (inhibit_eval_during_redisplay)
1853 val = Qnil;
1854 else
1855 {
1856 int count = SPECPDL_INDEX ();
1857 struct gcpro gcpro1;
1858
1859 GCPRO1 (args[0]);
1860 gcpro1.nvars = nargs;
1861 specbind (Qinhibit_redisplay, Qt);
1862 /* Use Qt to ensure debugger does not run,
1863 so there is no possibility of wanting to redisplay. */
1864 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
1865 safe_eval_handler);
1866 UNGCPRO;
1867 val = unbind_to (count, val);
1868 }
1869
1870 return val;
1871 }
1872
1873
1874 /* Call function FN with one argument ARG.
1875 Return the result, or nil if something went wrong. */
1876
1877 Lisp_Object
1878 safe_call1 (fn, arg)
1879 Lisp_Object fn, arg;
1880 {
1881 Lisp_Object args[2];
1882 args[0] = fn;
1883 args[1] = arg;
1884 return safe_call (2, args);
1885 }
1886
1887
1888 \f
1889 /***********************************************************************
1890 Debugging
1891 ***********************************************************************/
1892
1893 #if 0
1894
1895 /* Define CHECK_IT to perform sanity checks on iterators.
1896 This is for debugging. It is too slow to do unconditionally. */
1897
1898 static void
1899 check_it (it)
1900 struct it *it;
1901 {
1902 if (it->method == next_element_from_string)
1903 {
1904 xassert (STRINGP (it->string));
1905 xassert (IT_STRING_CHARPOS (*it) >= 0);
1906 }
1907 else if (it->method == next_element_from_buffer)
1908 {
1909 /* Check that character and byte positions agree. */
1910 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
1911 }
1912
1913 if (it->dpvec)
1914 xassert (it->current.dpvec_index >= 0);
1915 else
1916 xassert (it->current.dpvec_index < 0);
1917 }
1918
1919 #define CHECK_IT(IT) check_it ((IT))
1920
1921 #else /* not 0 */
1922
1923 #define CHECK_IT(IT) (void) 0
1924
1925 #endif /* not 0 */
1926
1927
1928 #if GLYPH_DEBUG
1929
1930 /* Check that the window end of window W is what we expect it
1931 to be---the last row in the current matrix displaying text. */
1932
1933 static void
1934 check_window_end (w)
1935 struct window *w;
1936 {
1937 if (!MINI_WINDOW_P (w)
1938 && !NILP (w->window_end_valid))
1939 {
1940 struct glyph_row *row;
1941 xassert ((row = MATRIX_ROW (w->current_matrix,
1942 XFASTINT (w->window_end_vpos)),
1943 !row->enabled_p
1944 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
1945 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
1946 }
1947 }
1948
1949 #define CHECK_WINDOW_END(W) check_window_end ((W))
1950
1951 #else /* not GLYPH_DEBUG */
1952
1953 #define CHECK_WINDOW_END(W) (void) 0
1954
1955 #endif /* not GLYPH_DEBUG */
1956
1957
1958 \f
1959 /***********************************************************************
1960 Iterator initialization
1961 ***********************************************************************/
1962
1963 /* Initialize IT for displaying current_buffer in window W, starting
1964 at character position CHARPOS. CHARPOS < 0 means that no buffer
1965 position is specified which is useful when the iterator is assigned
1966 a position later. BYTEPOS is the byte position corresponding to
1967 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
1968
1969 If ROW is not null, calls to produce_glyphs with IT as parameter
1970 will produce glyphs in that row.
1971
1972 BASE_FACE_ID is the id of a base face to use. It must be one of
1973 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
1974 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
1975 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
1976
1977 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
1978 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
1979 will be initialized to use the corresponding mode line glyph row of
1980 the desired matrix of W. */
1981
1982 void
1983 init_iterator (it, w, charpos, bytepos, row, base_face_id)
1984 struct it *it;
1985 struct window *w;
1986 int charpos, bytepos;
1987 struct glyph_row *row;
1988 enum face_id base_face_id;
1989 {
1990 int highlight_region_p;
1991
1992 /* Some precondition checks. */
1993 xassert (w != NULL && it != NULL);
1994 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
1995 && charpos <= ZV));
1996
1997 /* If face attributes have been changed since the last redisplay,
1998 free realized faces now because they depend on face definitions
1999 that might have changed. Don't free faces while there might be
2000 desired matrices pending which reference these faces. */
2001 if (face_change_count && !inhibit_free_realized_faces)
2002 {
2003 face_change_count = 0;
2004 free_all_realized_faces (Qnil);
2005 }
2006
2007 /* Use one of the mode line rows of W's desired matrix if
2008 appropriate. */
2009 if (row == NULL)
2010 {
2011 if (base_face_id == MODE_LINE_FACE_ID
2012 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2013 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2014 else if (base_face_id == HEADER_LINE_FACE_ID)
2015 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2016 }
2017
2018 /* Clear IT. */
2019 bzero (it, sizeof *it);
2020 it->current.overlay_string_index = -1;
2021 it->current.dpvec_index = -1;
2022 it->base_face_id = base_face_id;
2023
2024 /* The window in which we iterate over current_buffer: */
2025 XSETWINDOW (it->window, w);
2026 it->w = w;
2027 it->f = XFRAME (w->frame);
2028
2029 /* Extra space between lines (on window systems only). */
2030 if (base_face_id == DEFAULT_FACE_ID
2031 && FRAME_WINDOW_P (it->f))
2032 {
2033 if (NATNUMP (current_buffer->extra_line_spacing))
2034 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2035 else if (it->f->extra_line_spacing > 0)
2036 it->extra_line_spacing = it->f->extra_line_spacing;
2037 }
2038
2039 /* If realized faces have been removed, e.g. because of face
2040 attribute changes of named faces, recompute them. When running
2041 in batch mode, the face cache of Vterminal_frame is null. If
2042 we happen to get called, make a dummy face cache. */
2043 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2044 init_frame_faces (it->f);
2045 if (FRAME_FACE_CACHE (it->f)->used == 0)
2046 recompute_basic_faces (it->f);
2047
2048 /* Current value of the `space-width', and 'height' properties. */
2049 it->space_width = Qnil;
2050 it->font_height = Qnil;
2051
2052 /* Are control characters displayed as `^C'? */
2053 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2054
2055 /* -1 means everything between a CR and the following line end
2056 is invisible. >0 means lines indented more than this value are
2057 invisible. */
2058 it->selective = (INTEGERP (current_buffer->selective_display)
2059 ? XFASTINT (current_buffer->selective_display)
2060 : (!NILP (current_buffer->selective_display)
2061 ? -1 : 0));
2062 it->selective_display_ellipsis_p
2063 = !NILP (current_buffer->selective_display_ellipses);
2064
2065 /* Display table to use. */
2066 it->dp = window_display_table (w);
2067
2068 /* Are multibyte characters enabled in current_buffer? */
2069 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2070
2071 /* Non-zero if we should highlight the region. */
2072 highlight_region_p
2073 = (!NILP (Vtransient_mark_mode)
2074 && !NILP (current_buffer->mark_active)
2075 && XMARKER (current_buffer->mark)->buffer != 0);
2076
2077 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2078 start and end of a visible region in window IT->w. Set both to
2079 -1 to indicate no region. */
2080 if (highlight_region_p
2081 /* Maybe highlight only in selected window. */
2082 && (/* Either show region everywhere. */
2083 highlight_nonselected_windows
2084 /* Or show region in the selected window. */
2085 || w == XWINDOW (selected_window)
2086 /* Or show the region if we are in the mini-buffer and W is
2087 the window the mini-buffer refers to. */
2088 || (MINI_WINDOW_P (XWINDOW (selected_window))
2089 && WINDOWP (minibuf_selected_window)
2090 && w == XWINDOW (minibuf_selected_window))))
2091 {
2092 int charpos = marker_position (current_buffer->mark);
2093 it->region_beg_charpos = min (PT, charpos);
2094 it->region_end_charpos = max (PT, charpos);
2095 }
2096 else
2097 it->region_beg_charpos = it->region_end_charpos = -1;
2098
2099 /* Get the position at which the redisplay_end_trigger hook should
2100 be run, if it is to be run at all. */
2101 if (MARKERP (w->redisplay_end_trigger)
2102 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2103 it->redisplay_end_trigger_charpos
2104 = marker_position (w->redisplay_end_trigger);
2105 else if (INTEGERP (w->redisplay_end_trigger))
2106 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2107
2108 /* Correct bogus values of tab_width. */
2109 it->tab_width = XINT (current_buffer->tab_width);
2110 if (it->tab_width <= 0 || it->tab_width > 1000)
2111 it->tab_width = 8;
2112
2113 /* Are lines in the display truncated? */
2114 it->truncate_lines_p
2115 = (base_face_id != DEFAULT_FACE_ID
2116 || XINT (it->w->hscroll)
2117 || (truncate_partial_width_windows
2118 && !WINDOW_FULL_WIDTH_P (it->w))
2119 || !NILP (current_buffer->truncate_lines));
2120
2121 /* Get dimensions of truncation and continuation glyphs. These are
2122 displayed as fringe bitmaps under X, so we don't need them for such
2123 frames. */
2124 if (!FRAME_WINDOW_P (it->f))
2125 {
2126 if (it->truncate_lines_p)
2127 {
2128 /* We will need the truncation glyph. */
2129 xassert (it->glyph_row == NULL);
2130 produce_special_glyphs (it, IT_TRUNCATION);
2131 it->truncation_pixel_width = it->pixel_width;
2132 }
2133 else
2134 {
2135 /* We will need the continuation glyph. */
2136 xassert (it->glyph_row == NULL);
2137 produce_special_glyphs (it, IT_CONTINUATION);
2138 it->continuation_pixel_width = it->pixel_width;
2139 }
2140
2141 /* Reset these values to zero because the produce_special_glyphs
2142 above has changed them. */
2143 it->pixel_width = it->ascent = it->descent = 0;
2144 it->phys_ascent = it->phys_descent = 0;
2145 }
2146
2147 /* Set this after getting the dimensions of truncation and
2148 continuation glyphs, so that we don't produce glyphs when calling
2149 produce_special_glyphs, above. */
2150 it->glyph_row = row;
2151 it->area = TEXT_AREA;
2152
2153 /* Get the dimensions of the display area. The display area
2154 consists of the visible window area plus a horizontally scrolled
2155 part to the left of the window. All x-values are relative to the
2156 start of this total display area. */
2157 if (base_face_id != DEFAULT_FACE_ID)
2158 {
2159 /* Mode lines, menu bar in terminal frames. */
2160 it->first_visible_x = 0;
2161 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2162 }
2163 else
2164 {
2165 it->first_visible_x
2166 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2167 it->last_visible_x = (it->first_visible_x
2168 + window_box_width (w, TEXT_AREA));
2169
2170 /* If we truncate lines, leave room for the truncator glyph(s) at
2171 the right margin. Otherwise, leave room for the continuation
2172 glyph(s). Truncation and continuation glyphs are not inserted
2173 for window-based redisplay. */
2174 if (!FRAME_WINDOW_P (it->f))
2175 {
2176 if (it->truncate_lines_p)
2177 it->last_visible_x -= it->truncation_pixel_width;
2178 else
2179 it->last_visible_x -= it->continuation_pixel_width;
2180 }
2181
2182 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2183 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2184 }
2185
2186 /* Leave room for a border glyph. */
2187 if (!FRAME_WINDOW_P (it->f)
2188 && !WINDOW_RIGHTMOST_P (it->w))
2189 it->last_visible_x -= 1;
2190
2191 it->last_visible_y = window_text_bottom_y (w);
2192
2193 /* For mode lines and alike, arrange for the first glyph having a
2194 left box line if the face specifies a box. */
2195 if (base_face_id != DEFAULT_FACE_ID)
2196 {
2197 struct face *face;
2198
2199 it->face_id = base_face_id;
2200
2201 /* If we have a boxed mode line, make the first character appear
2202 with a left box line. */
2203 face = FACE_FROM_ID (it->f, base_face_id);
2204 if (face->box != FACE_NO_BOX)
2205 it->start_of_box_run_p = 1;
2206 }
2207
2208 /* If a buffer position was specified, set the iterator there,
2209 getting overlays and face properties from that position. */
2210 if (charpos >= BUF_BEG (current_buffer))
2211 {
2212 it->end_charpos = ZV;
2213 it->face_id = -1;
2214 IT_CHARPOS (*it) = charpos;
2215
2216 /* Compute byte position if not specified. */
2217 if (bytepos < charpos)
2218 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2219 else
2220 IT_BYTEPOS (*it) = bytepos;
2221
2222 it->start = it->current;
2223
2224 /* Compute faces etc. */
2225 reseat (it, it->current.pos, 1);
2226 }
2227
2228 CHECK_IT (it);
2229 }
2230
2231
2232 /* Initialize IT for the display of window W with window start POS. */
2233
2234 void
2235 start_display (it, w, pos)
2236 struct it *it;
2237 struct window *w;
2238 struct text_pos pos;
2239 {
2240 struct glyph_row *row;
2241 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2242
2243 row = w->desired_matrix->rows + first_vpos;
2244 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2245 it->first_vpos = first_vpos;
2246
2247 if (!it->truncate_lines_p)
2248 {
2249 int start_at_line_beg_p;
2250 int first_y = it->current_y;
2251
2252 /* If window start is not at a line start, skip forward to POS to
2253 get the correct continuation lines width. */
2254 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2255 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2256 if (!start_at_line_beg_p)
2257 {
2258 int new_x;
2259
2260 reseat_at_previous_visible_line_start (it);
2261 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2262
2263 new_x = it->current_x + it->pixel_width;
2264
2265 /* If lines are continued, this line may end in the middle
2266 of a multi-glyph character (e.g. a control character
2267 displayed as \003, or in the middle of an overlay
2268 string). In this case move_it_to above will not have
2269 taken us to the start of the continuation line but to the
2270 end of the continued line. */
2271 if (it->current_x > 0
2272 && !it->truncate_lines_p /* Lines are continued. */
2273 && (/* And glyph doesn't fit on the line. */
2274 new_x > it->last_visible_x
2275 /* Or it fits exactly and we're on a window
2276 system frame. */
2277 || (new_x == it->last_visible_x
2278 && FRAME_WINDOW_P (it->f))))
2279 {
2280 if (it->current.dpvec_index >= 0
2281 || it->current.overlay_string_index >= 0)
2282 {
2283 set_iterator_to_next (it, 1);
2284 move_it_in_display_line_to (it, -1, -1, 0);
2285 }
2286
2287 it->continuation_lines_width += it->current_x;
2288 }
2289
2290 /* We're starting a new display line, not affected by the
2291 height of the continued line, so clear the appropriate
2292 fields in the iterator structure. */
2293 it->max_ascent = it->max_descent = 0;
2294 it->max_phys_ascent = it->max_phys_descent = 0;
2295
2296 it->current_y = first_y;
2297 it->vpos = 0;
2298 it->current_x = it->hpos = 0;
2299 }
2300 }
2301
2302 #if 0 /* Don't assert the following because start_display is sometimes
2303 called intentionally with a window start that is not at a
2304 line start. Please leave this code in as a comment. */
2305
2306 /* Window start should be on a line start, now. */
2307 xassert (it->continuation_lines_width
2308 || IT_CHARPOS (it) == BEGV
2309 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2310 #endif /* 0 */
2311 }
2312
2313
2314 /* Return 1 if POS is a position in ellipses displayed for invisible
2315 text. W is the window we display, for text property lookup. */
2316
2317 static int
2318 in_ellipses_for_invisible_text_p (pos, w)
2319 struct display_pos *pos;
2320 struct window *w;
2321 {
2322 Lisp_Object prop, window;
2323 int ellipses_p = 0;
2324 int charpos = CHARPOS (pos->pos);
2325
2326 /* If POS specifies a position in a display vector, this might
2327 be for an ellipsis displayed for invisible text. We won't
2328 get the iterator set up for delivering that ellipsis unless
2329 we make sure that it gets aware of the invisible text. */
2330 if (pos->dpvec_index >= 0
2331 && pos->overlay_string_index < 0
2332 && CHARPOS (pos->string_pos) < 0
2333 && charpos > BEGV
2334 && (XSETWINDOW (window, w),
2335 prop = Fget_char_property (make_number (charpos),
2336 Qinvisible, window),
2337 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2338 {
2339 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2340 window);
2341 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2342 }
2343
2344 return ellipses_p;
2345 }
2346
2347
2348 /* Initialize IT for stepping through current_buffer in window W,
2349 starting at position POS that includes overlay string and display
2350 vector/ control character translation position information. Value
2351 is zero if there are overlay strings with newlines at POS. */
2352
2353 static int
2354 init_from_display_pos (it, w, pos)
2355 struct it *it;
2356 struct window *w;
2357 struct display_pos *pos;
2358 {
2359 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2360 int i, overlay_strings_with_newlines = 0;
2361
2362 /* If POS specifies a position in a display vector, this might
2363 be for an ellipsis displayed for invisible text. We won't
2364 get the iterator set up for delivering that ellipsis unless
2365 we make sure that it gets aware of the invisible text. */
2366 if (in_ellipses_for_invisible_text_p (pos, w))
2367 {
2368 --charpos;
2369 bytepos = 0;
2370 }
2371
2372 /* Keep in mind: the call to reseat in init_iterator skips invisible
2373 text, so we might end up at a position different from POS. This
2374 is only a problem when POS is a row start after a newline and an
2375 overlay starts there with an after-string, and the overlay has an
2376 invisible property. Since we don't skip invisible text in
2377 display_line and elsewhere immediately after consuming the
2378 newline before the row start, such a POS will not be in a string,
2379 but the call to init_iterator below will move us to the
2380 after-string. */
2381 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2382
2383 for (i = 0; i < it->n_overlay_strings; ++i)
2384 {
2385 const char *s = SDATA (it->overlay_strings[i]);
2386 const char *e = s + SBYTES (it->overlay_strings[i]);
2387
2388 while (s < e && *s != '\n')
2389 ++s;
2390
2391 if (s < e)
2392 {
2393 overlay_strings_with_newlines = 1;
2394 break;
2395 }
2396 }
2397
2398 /* If position is within an overlay string, set up IT to the right
2399 overlay string. */
2400 if (pos->overlay_string_index >= 0)
2401 {
2402 int relative_index;
2403
2404 /* If the first overlay string happens to have a `display'
2405 property for an image, the iterator will be set up for that
2406 image, and we have to undo that setup first before we can
2407 correct the overlay string index. */
2408 if (it->method == next_element_from_image)
2409 pop_it (it);
2410
2411 /* We already have the first chunk of overlay strings in
2412 IT->overlay_strings. Load more until the one for
2413 pos->overlay_string_index is in IT->overlay_strings. */
2414 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2415 {
2416 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2417 it->current.overlay_string_index = 0;
2418 while (n--)
2419 {
2420 load_overlay_strings (it, 0);
2421 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2422 }
2423 }
2424
2425 it->current.overlay_string_index = pos->overlay_string_index;
2426 relative_index = (it->current.overlay_string_index
2427 % OVERLAY_STRING_CHUNK_SIZE);
2428 it->string = it->overlay_strings[relative_index];
2429 xassert (STRINGP (it->string));
2430 it->current.string_pos = pos->string_pos;
2431 it->method = next_element_from_string;
2432 }
2433
2434 #if 0 /* This is bogus because POS not having an overlay string
2435 position does not mean it's after the string. Example: A
2436 line starting with a before-string and initialization of IT
2437 to the previous row's end position. */
2438 else if (it->current.overlay_string_index >= 0)
2439 {
2440 /* If POS says we're already after an overlay string ending at
2441 POS, make sure to pop the iterator because it will be in
2442 front of that overlay string. When POS is ZV, we've thereby
2443 also ``processed'' overlay strings at ZV. */
2444 while (it->sp)
2445 pop_it (it);
2446 it->current.overlay_string_index = -1;
2447 it->method = next_element_from_buffer;
2448 if (CHARPOS (pos->pos) == ZV)
2449 it->overlay_strings_at_end_processed_p = 1;
2450 }
2451 #endif /* 0 */
2452
2453 if (CHARPOS (pos->string_pos) >= 0)
2454 {
2455 /* Recorded position is not in an overlay string, but in another
2456 string. This can only be a string from a `display' property.
2457 IT should already be filled with that string. */
2458 it->current.string_pos = pos->string_pos;
2459 xassert (STRINGP (it->string));
2460 }
2461
2462 /* Restore position in display vector translations, control
2463 character translations or ellipses. */
2464 if (pos->dpvec_index >= 0)
2465 {
2466 if (it->dpvec == NULL)
2467 get_next_display_element (it);
2468 xassert (it->dpvec && it->current.dpvec_index == 0);
2469 it->current.dpvec_index = pos->dpvec_index;
2470 }
2471
2472 CHECK_IT (it);
2473 return !overlay_strings_with_newlines;
2474 }
2475
2476
2477 /* Initialize IT for stepping through current_buffer in window W
2478 starting at ROW->start. */
2479
2480 static void
2481 init_to_row_start (it, w, row)
2482 struct it *it;
2483 struct window *w;
2484 struct glyph_row *row;
2485 {
2486 init_from_display_pos (it, w, &row->start);
2487 it->start = row->start;
2488 it->continuation_lines_width = row->continuation_lines_width;
2489 CHECK_IT (it);
2490 }
2491
2492
2493 /* Initialize IT for stepping through current_buffer in window W
2494 starting in the line following ROW, i.e. starting at ROW->end.
2495 Value is zero if there are overlay strings with newlines at ROW's
2496 end position. */
2497
2498 static int
2499 init_to_row_end (it, w, row)
2500 struct it *it;
2501 struct window *w;
2502 struct glyph_row *row;
2503 {
2504 int success = 0;
2505
2506 if (init_from_display_pos (it, w, &row->end))
2507 {
2508 if (row->continued_p)
2509 it->continuation_lines_width
2510 = row->continuation_lines_width + row->pixel_width;
2511 CHECK_IT (it);
2512 success = 1;
2513 }
2514
2515 return success;
2516 }
2517
2518
2519
2520 \f
2521 /***********************************************************************
2522 Text properties
2523 ***********************************************************************/
2524
2525 /* Called when IT reaches IT->stop_charpos. Handle text property and
2526 overlay changes. Set IT->stop_charpos to the next position where
2527 to stop. */
2528
2529 static void
2530 handle_stop (it)
2531 struct it *it;
2532 {
2533 enum prop_handled handled;
2534 int handle_overlay_change_p = 1;
2535 struct props *p;
2536
2537 it->dpvec = NULL;
2538 it->current.dpvec_index = -1;
2539
2540 do
2541 {
2542 handled = HANDLED_NORMALLY;
2543
2544 /* Call text property handlers. */
2545 for (p = it_props; p->handler; ++p)
2546 {
2547 handled = p->handler (it);
2548
2549 if (handled == HANDLED_RECOMPUTE_PROPS)
2550 break;
2551 else if (handled == HANDLED_RETURN)
2552 return;
2553 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2554 handle_overlay_change_p = 0;
2555 }
2556
2557 if (handled != HANDLED_RECOMPUTE_PROPS)
2558 {
2559 /* Don't check for overlay strings below when set to deliver
2560 characters from a display vector. */
2561 if (it->method == next_element_from_display_vector)
2562 handle_overlay_change_p = 0;
2563
2564 /* Handle overlay changes. */
2565 if (handle_overlay_change_p)
2566 handled = handle_overlay_change (it);
2567
2568 /* Determine where to stop next. */
2569 if (handled == HANDLED_NORMALLY)
2570 compute_stop_pos (it);
2571 }
2572 }
2573 while (handled == HANDLED_RECOMPUTE_PROPS);
2574 }
2575
2576
2577 /* Compute IT->stop_charpos from text property and overlay change
2578 information for IT's current position. */
2579
2580 static void
2581 compute_stop_pos (it)
2582 struct it *it;
2583 {
2584 register INTERVAL iv, next_iv;
2585 Lisp_Object object, limit, position;
2586
2587 /* If nowhere else, stop at the end. */
2588 it->stop_charpos = it->end_charpos;
2589
2590 if (STRINGP (it->string))
2591 {
2592 /* Strings are usually short, so don't limit the search for
2593 properties. */
2594 object = it->string;
2595 limit = Qnil;
2596 position = make_number (IT_STRING_CHARPOS (*it));
2597 }
2598 else
2599 {
2600 int charpos;
2601
2602 /* If next overlay change is in front of the current stop pos
2603 (which is IT->end_charpos), stop there. Note: value of
2604 next_overlay_change is point-max if no overlay change
2605 follows. */
2606 charpos = next_overlay_change (IT_CHARPOS (*it));
2607 if (charpos < it->stop_charpos)
2608 it->stop_charpos = charpos;
2609
2610 /* If showing the region, we have to stop at the region
2611 start or end because the face might change there. */
2612 if (it->region_beg_charpos > 0)
2613 {
2614 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2615 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2616 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2617 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2618 }
2619
2620 /* Set up variables for computing the stop position from text
2621 property changes. */
2622 XSETBUFFER (object, current_buffer);
2623 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2624 position = make_number (IT_CHARPOS (*it));
2625
2626 }
2627
2628 /* Get the interval containing IT's position. Value is a null
2629 interval if there isn't such an interval. */
2630 iv = validate_interval_range (object, &position, &position, 0);
2631 if (!NULL_INTERVAL_P (iv))
2632 {
2633 Lisp_Object values_here[LAST_PROP_IDX];
2634 struct props *p;
2635
2636 /* Get properties here. */
2637 for (p = it_props; p->handler; ++p)
2638 values_here[p->idx] = textget (iv->plist, *p->name);
2639
2640 /* Look for an interval following iv that has different
2641 properties. */
2642 for (next_iv = next_interval (iv);
2643 (!NULL_INTERVAL_P (next_iv)
2644 && (NILP (limit)
2645 || XFASTINT (limit) > next_iv->position));
2646 next_iv = next_interval (next_iv))
2647 {
2648 for (p = it_props; p->handler; ++p)
2649 {
2650 Lisp_Object new_value;
2651
2652 new_value = textget (next_iv->plist, *p->name);
2653 if (!EQ (values_here[p->idx], new_value))
2654 break;
2655 }
2656
2657 if (p->handler)
2658 break;
2659 }
2660
2661 if (!NULL_INTERVAL_P (next_iv))
2662 {
2663 if (INTEGERP (limit)
2664 && next_iv->position >= XFASTINT (limit))
2665 /* No text property change up to limit. */
2666 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2667 else
2668 /* Text properties change in next_iv. */
2669 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2670 }
2671 }
2672
2673 xassert (STRINGP (it->string)
2674 || (it->stop_charpos >= BEGV
2675 && it->stop_charpos >= IT_CHARPOS (*it)));
2676 }
2677
2678
2679 /* Return the position of the next overlay change after POS in
2680 current_buffer. Value is point-max if no overlay change
2681 follows. This is like `next-overlay-change' but doesn't use
2682 xmalloc. */
2683
2684 static int
2685 next_overlay_change (pos)
2686 int pos;
2687 {
2688 int noverlays;
2689 int endpos;
2690 Lisp_Object *overlays;
2691 int len;
2692 int i;
2693
2694 /* Get all overlays at the given position. */
2695 len = 10;
2696 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2697 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2698 if (noverlays > len)
2699 {
2700 len = noverlays;
2701 overlays = (Lisp_Object *) alloca (len * sizeof *overlays);
2702 noverlays = overlays_at (pos, 0, &overlays, &len, &endpos, NULL, 1);
2703 }
2704
2705 /* If any of these overlays ends before endpos,
2706 use its ending point instead. */
2707 for (i = 0; i < noverlays; ++i)
2708 {
2709 Lisp_Object oend;
2710 int oendpos;
2711
2712 oend = OVERLAY_END (overlays[i]);
2713 oendpos = OVERLAY_POSITION (oend);
2714 endpos = min (endpos, oendpos);
2715 }
2716
2717 return endpos;
2718 }
2719
2720
2721 \f
2722 /***********************************************************************
2723 Fontification
2724 ***********************************************************************/
2725
2726 /* Handle changes in the `fontified' property of the current buffer by
2727 calling hook functions from Qfontification_functions to fontify
2728 regions of text. */
2729
2730 static enum prop_handled
2731 handle_fontified_prop (it)
2732 struct it *it;
2733 {
2734 Lisp_Object prop, pos;
2735 enum prop_handled handled = HANDLED_NORMALLY;
2736
2737 /* Get the value of the `fontified' property at IT's current buffer
2738 position. (The `fontified' property doesn't have a special
2739 meaning in strings.) If the value is nil, call functions from
2740 Qfontification_functions. */
2741 if (!STRINGP (it->string)
2742 && it->s == NULL
2743 && !NILP (Vfontification_functions)
2744 && !NILP (Vrun_hooks)
2745 && (pos = make_number (IT_CHARPOS (*it)),
2746 prop = Fget_char_property (pos, Qfontified, Qnil),
2747 NILP (prop)))
2748 {
2749 int count = SPECPDL_INDEX ();
2750 Lisp_Object val;
2751
2752 val = Vfontification_functions;
2753 specbind (Qfontification_functions, Qnil);
2754
2755 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2756 safe_call1 (val, pos);
2757 else
2758 {
2759 Lisp_Object globals, fn;
2760 struct gcpro gcpro1, gcpro2;
2761
2762 globals = Qnil;
2763 GCPRO2 (val, globals);
2764
2765 for (; CONSP (val); val = XCDR (val))
2766 {
2767 fn = XCAR (val);
2768
2769 if (EQ (fn, Qt))
2770 {
2771 /* A value of t indicates this hook has a local
2772 binding; it means to run the global binding too.
2773 In a global value, t should not occur. If it
2774 does, we must ignore it to avoid an endless
2775 loop. */
2776 for (globals = Fdefault_value (Qfontification_functions);
2777 CONSP (globals);
2778 globals = XCDR (globals))
2779 {
2780 fn = XCAR (globals);
2781 if (!EQ (fn, Qt))
2782 safe_call1 (fn, pos);
2783 }
2784 }
2785 else
2786 safe_call1 (fn, pos);
2787 }
2788
2789 UNGCPRO;
2790 }
2791
2792 unbind_to (count, Qnil);
2793
2794 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2795 something. This avoids an endless loop if they failed to
2796 fontify the text for which reason ever. */
2797 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2798 handled = HANDLED_RECOMPUTE_PROPS;
2799 }
2800
2801 return handled;
2802 }
2803
2804
2805 \f
2806 /***********************************************************************
2807 Faces
2808 ***********************************************************************/
2809
2810 /* Set up iterator IT from face properties at its current position.
2811 Called from handle_stop. */
2812
2813 static enum prop_handled
2814 handle_face_prop (it)
2815 struct it *it;
2816 {
2817 int new_face_id, next_stop;
2818
2819 if (!STRINGP (it->string))
2820 {
2821 new_face_id
2822 = face_at_buffer_position (it->w,
2823 IT_CHARPOS (*it),
2824 it->region_beg_charpos,
2825 it->region_end_charpos,
2826 &next_stop,
2827 (IT_CHARPOS (*it)
2828 + TEXT_PROP_DISTANCE_LIMIT),
2829 0);
2830
2831 /* Is this a start of a run of characters with box face?
2832 Caveat: this can be called for a freshly initialized
2833 iterator; face_id is -1 in this case. We know that the new
2834 face will not change until limit, i.e. if the new face has a
2835 box, all characters up to limit will have one. But, as
2836 usual, we don't know whether limit is really the end. */
2837 if (new_face_id != it->face_id)
2838 {
2839 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2840
2841 /* If new face has a box but old face has not, this is
2842 the start of a run of characters with box, i.e. it has
2843 a shadow on the left side. The value of face_id of the
2844 iterator will be -1 if this is the initial call that gets
2845 the face. In this case, we have to look in front of IT's
2846 position and see whether there is a face != new_face_id. */
2847 it->start_of_box_run_p
2848 = (new_face->box != FACE_NO_BOX
2849 && (it->face_id >= 0
2850 || IT_CHARPOS (*it) == BEG
2851 || new_face_id != face_before_it_pos (it)));
2852 it->face_box_p = new_face->box != FACE_NO_BOX;
2853 }
2854 }
2855 else
2856 {
2857 int base_face_id, bufpos;
2858
2859 if (it->current.overlay_string_index >= 0)
2860 bufpos = IT_CHARPOS (*it);
2861 else
2862 bufpos = 0;
2863
2864 /* For strings from a buffer, i.e. overlay strings or strings
2865 from a `display' property, use the face at IT's current
2866 buffer position as the base face to merge with, so that
2867 overlay strings appear in the same face as surrounding
2868 text, unless they specify their own faces. */
2869 base_face_id = underlying_face_id (it);
2870
2871 new_face_id = face_at_string_position (it->w,
2872 it->string,
2873 IT_STRING_CHARPOS (*it),
2874 bufpos,
2875 it->region_beg_charpos,
2876 it->region_end_charpos,
2877 &next_stop,
2878 base_face_id, 0);
2879
2880 #if 0 /* This shouldn't be neccessary. Let's check it. */
2881 /* If IT is used to display a mode line we would really like to
2882 use the mode line face instead of the frame's default face. */
2883 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
2884 && new_face_id == DEFAULT_FACE_ID)
2885 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
2886 #endif
2887
2888 /* Is this a start of a run of characters with box? Caveat:
2889 this can be called for a freshly allocated iterator; face_id
2890 is -1 is this case. We know that the new face will not
2891 change until the next check pos, i.e. if the new face has a
2892 box, all characters up to that position will have a
2893 box. But, as usual, we don't know whether that position
2894 is really the end. */
2895 if (new_face_id != it->face_id)
2896 {
2897 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2898 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
2899
2900 /* If new face has a box but old face hasn't, this is the
2901 start of a run of characters with box, i.e. it has a
2902 shadow on the left side. */
2903 it->start_of_box_run_p
2904 = new_face->box && (old_face == NULL || !old_face->box);
2905 it->face_box_p = new_face->box != FACE_NO_BOX;
2906 }
2907 }
2908
2909 it->face_id = new_face_id;
2910 return HANDLED_NORMALLY;
2911 }
2912
2913
2914 /* Return the ID of the face ``underlying'' IT's current position,
2915 which is in a string. If the iterator is associated with a
2916 buffer, return the face at IT's current buffer position.
2917 Otherwise, use the iterator's base_face_id. */
2918
2919 static int
2920 underlying_face_id (it)
2921 struct it *it;
2922 {
2923 int face_id = it->base_face_id, i;
2924
2925 xassert (STRINGP (it->string));
2926
2927 for (i = it->sp - 1; i >= 0; --i)
2928 if (NILP (it->stack[i].string))
2929 face_id = it->stack[i].face_id;
2930
2931 return face_id;
2932 }
2933
2934
2935 /* Compute the face one character before or after the current position
2936 of IT. BEFORE_P non-zero means get the face in front of IT's
2937 position. Value is the id of the face. */
2938
2939 static int
2940 face_before_or_after_it_pos (it, before_p)
2941 struct it *it;
2942 int before_p;
2943 {
2944 int face_id, limit;
2945 int next_check_charpos;
2946 struct text_pos pos;
2947
2948 xassert (it->s == NULL);
2949
2950 if (STRINGP (it->string))
2951 {
2952 int bufpos, base_face_id;
2953
2954 /* No face change past the end of the string (for the case
2955 we are padding with spaces). No face change before the
2956 string start. */
2957 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
2958 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
2959 return it->face_id;
2960
2961 /* Set pos to the position before or after IT's current position. */
2962 if (before_p)
2963 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
2964 else
2965 /* For composition, we must check the character after the
2966 composition. */
2967 pos = (it->what == IT_COMPOSITION
2968 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
2969 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
2970
2971 if (it->current.overlay_string_index >= 0)
2972 bufpos = IT_CHARPOS (*it);
2973 else
2974 bufpos = 0;
2975
2976 base_face_id = underlying_face_id (it);
2977
2978 /* Get the face for ASCII, or unibyte. */
2979 face_id = face_at_string_position (it->w,
2980 it->string,
2981 CHARPOS (pos),
2982 bufpos,
2983 it->region_beg_charpos,
2984 it->region_end_charpos,
2985 &next_check_charpos,
2986 base_face_id, 0);
2987
2988 /* Correct the face for charsets different from ASCII. Do it
2989 for the multibyte case only. The face returned above is
2990 suitable for unibyte text if IT->string is unibyte. */
2991 if (STRING_MULTIBYTE (it->string))
2992 {
2993 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
2994 int rest = SBYTES (it->string) - BYTEPOS (pos);
2995 int c, len;
2996 struct face *face = FACE_FROM_ID (it->f, face_id);
2997
2998 c = string_char_and_length (p, rest, &len);
2999 face_id = FACE_FOR_CHAR (it->f, face, c);
3000 }
3001 }
3002 else
3003 {
3004 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3005 || (IT_CHARPOS (*it) <= BEGV && before_p))
3006 return it->face_id;
3007
3008 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3009 pos = it->current.pos;
3010
3011 if (before_p)
3012 DEC_TEXT_POS (pos, it->multibyte_p);
3013 else
3014 {
3015 if (it->what == IT_COMPOSITION)
3016 /* For composition, we must check the position after the
3017 composition. */
3018 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3019 else
3020 INC_TEXT_POS (pos, it->multibyte_p);
3021 }
3022
3023 /* Determine face for CHARSET_ASCII, or unibyte. */
3024 face_id = face_at_buffer_position (it->w,
3025 CHARPOS (pos),
3026 it->region_beg_charpos,
3027 it->region_end_charpos,
3028 &next_check_charpos,
3029 limit, 0);
3030
3031 /* Correct the face for charsets different from ASCII. Do it
3032 for the multibyte case only. The face returned above is
3033 suitable for unibyte text if current_buffer is unibyte. */
3034 if (it->multibyte_p)
3035 {
3036 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3037 struct face *face = FACE_FROM_ID (it->f, face_id);
3038 face_id = FACE_FOR_CHAR (it->f, face, c);
3039 }
3040 }
3041
3042 return face_id;
3043 }
3044
3045
3046 \f
3047 /***********************************************************************
3048 Invisible text
3049 ***********************************************************************/
3050
3051 /* Set up iterator IT from invisible properties at its current
3052 position. Called from handle_stop. */
3053
3054 static enum prop_handled
3055 handle_invisible_prop (it)
3056 struct it *it;
3057 {
3058 enum prop_handled handled = HANDLED_NORMALLY;
3059
3060 if (STRINGP (it->string))
3061 {
3062 extern Lisp_Object Qinvisible;
3063 Lisp_Object prop, end_charpos, limit, charpos;
3064
3065 /* Get the value of the invisible text property at the
3066 current position. Value will be nil if there is no such
3067 property. */
3068 charpos = make_number (IT_STRING_CHARPOS (*it));
3069 prop = Fget_text_property (charpos, Qinvisible, it->string);
3070
3071 if (!NILP (prop)
3072 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3073 {
3074 handled = HANDLED_RECOMPUTE_PROPS;
3075
3076 /* Get the position at which the next change of the
3077 invisible text property can be found in IT->string.
3078 Value will be nil if the property value is the same for
3079 all the rest of IT->string. */
3080 XSETINT (limit, SCHARS (it->string));
3081 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3082 it->string, limit);
3083
3084 /* Text at current position is invisible. The next
3085 change in the property is at position end_charpos.
3086 Move IT's current position to that position. */
3087 if (INTEGERP (end_charpos)
3088 && XFASTINT (end_charpos) < XFASTINT (limit))
3089 {
3090 struct text_pos old;
3091 old = it->current.string_pos;
3092 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3093 compute_string_pos (&it->current.string_pos, old, it->string);
3094 }
3095 else
3096 {
3097 /* The rest of the string is invisible. If this is an
3098 overlay string, proceed with the next overlay string
3099 or whatever comes and return a character from there. */
3100 if (it->current.overlay_string_index >= 0)
3101 {
3102 next_overlay_string (it);
3103 /* Don't check for overlay strings when we just
3104 finished processing them. */
3105 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3106 }
3107 else
3108 {
3109 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3110 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3111 }
3112 }
3113 }
3114 }
3115 else
3116 {
3117 int invis_p, newpos, next_stop, start_charpos;
3118 Lisp_Object pos, prop, overlay;
3119
3120 /* First of all, is there invisible text at this position? */
3121 start_charpos = IT_CHARPOS (*it);
3122 pos = make_number (IT_CHARPOS (*it));
3123 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3124 &overlay);
3125 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3126
3127 /* If we are on invisible text, skip over it. */
3128 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3129 {
3130 /* Record whether we have to display an ellipsis for the
3131 invisible text. */
3132 int display_ellipsis_p = invis_p == 2;
3133
3134 handled = HANDLED_RECOMPUTE_PROPS;
3135
3136 /* Loop skipping over invisible text. The loop is left at
3137 ZV or with IT on the first char being visible again. */
3138 do
3139 {
3140 /* Try to skip some invisible text. Return value is the
3141 position reached which can be equal to IT's position
3142 if there is nothing invisible here. This skips both
3143 over invisible text properties and overlays with
3144 invisible property. */
3145 newpos = skip_invisible (IT_CHARPOS (*it),
3146 &next_stop, ZV, it->window);
3147
3148 /* If we skipped nothing at all we weren't at invisible
3149 text in the first place. If everything to the end of
3150 the buffer was skipped, end the loop. */
3151 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3152 invis_p = 0;
3153 else
3154 {
3155 /* We skipped some characters but not necessarily
3156 all there are. Check if we ended up on visible
3157 text. Fget_char_property returns the property of
3158 the char before the given position, i.e. if we
3159 get invis_p = 0, this means that the char at
3160 newpos is visible. */
3161 pos = make_number (newpos);
3162 prop = Fget_char_property (pos, Qinvisible, it->window);
3163 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3164 }
3165
3166 /* If we ended up on invisible text, proceed to
3167 skip starting with next_stop. */
3168 if (invis_p)
3169 IT_CHARPOS (*it) = next_stop;
3170 }
3171 while (invis_p);
3172
3173 /* The position newpos is now either ZV or on visible text. */
3174 IT_CHARPOS (*it) = newpos;
3175 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3176
3177 /* If there are before-strings at the start of invisible
3178 text, and the text is invisible because of a text
3179 property, arrange to show before-strings because 20.x did
3180 it that way. (If the text is invisible because of an
3181 overlay property instead of a text property, this is
3182 already handled in the overlay code.) */
3183 if (NILP (overlay)
3184 && get_overlay_strings (it, start_charpos))
3185 {
3186 handled = HANDLED_RECOMPUTE_PROPS;
3187 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3188 }
3189 else if (display_ellipsis_p)
3190 setup_for_ellipsis (it);
3191 }
3192 }
3193
3194 return handled;
3195 }
3196
3197
3198 /* Make iterator IT return `...' next. */
3199
3200 static void
3201 setup_for_ellipsis (it)
3202 struct it *it;
3203 {
3204 if (it->dp
3205 && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3206 {
3207 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3208 it->dpvec = v->contents;
3209 it->dpend = v->contents + v->size;
3210 }
3211 else
3212 {
3213 /* Default `...'. */
3214 it->dpvec = default_invis_vector;
3215 it->dpend = default_invis_vector + 3;
3216 }
3217
3218 /* The ellipsis display does not replace the display of the
3219 character at the new position. Indicate this by setting
3220 IT->dpvec_char_len to zero. */
3221 it->dpvec_char_len = 0;
3222
3223 it->current.dpvec_index = 0;
3224 it->method = next_element_from_display_vector;
3225 }
3226
3227
3228 \f
3229 /***********************************************************************
3230 'display' property
3231 ***********************************************************************/
3232
3233 /* Set up iterator IT from `display' property at its current position.
3234 Called from handle_stop. */
3235
3236 static enum prop_handled
3237 handle_display_prop (it)
3238 struct it *it;
3239 {
3240 Lisp_Object prop, object;
3241 struct text_pos *position;
3242 int display_replaced_p = 0;
3243
3244 if (STRINGP (it->string))
3245 {
3246 object = it->string;
3247 position = &it->current.string_pos;
3248 }
3249 else
3250 {
3251 object = it->w->buffer;
3252 position = &it->current.pos;
3253 }
3254
3255 /* Reset those iterator values set from display property values. */
3256 it->font_height = Qnil;
3257 it->space_width = Qnil;
3258 it->voffset = 0;
3259
3260 /* We don't support recursive `display' properties, i.e. string
3261 values that have a string `display' property, that have a string
3262 `display' property etc. */
3263 if (!it->string_from_display_prop_p)
3264 it->area = TEXT_AREA;
3265
3266 prop = Fget_char_property (make_number (position->charpos),
3267 Qdisplay, object);
3268 if (NILP (prop))
3269 return HANDLED_NORMALLY;
3270
3271 if (CONSP (prop)
3272 /* Simple properties. */
3273 && !EQ (XCAR (prop), Qimage)
3274 && !EQ (XCAR (prop), Qspace)
3275 && !EQ (XCAR (prop), Qwhen)
3276 && !EQ (XCAR (prop), Qspace_width)
3277 && !EQ (XCAR (prop), Qheight)
3278 && !EQ (XCAR (prop), Qraise)
3279 /* Marginal area specifications. */
3280 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3281 && !EQ (XCAR (prop), Qleft_fringe)
3282 && !EQ (XCAR (prop), Qright_fringe)
3283 && !NILP (XCAR (prop)))
3284 {
3285 for (; CONSP (prop); prop = XCDR (prop))
3286 {
3287 if (handle_single_display_prop (it, XCAR (prop), object,
3288 position, display_replaced_p))
3289 display_replaced_p = 1;
3290 }
3291 }
3292 else if (VECTORP (prop))
3293 {
3294 int i;
3295 for (i = 0; i < ASIZE (prop); ++i)
3296 if (handle_single_display_prop (it, AREF (prop, i), object,
3297 position, display_replaced_p))
3298 display_replaced_p = 1;
3299 }
3300 else
3301 {
3302 if (handle_single_display_prop (it, prop, object, position, 0))
3303 display_replaced_p = 1;
3304 }
3305
3306 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3307 }
3308
3309
3310 /* Value is the position of the end of the `display' property starting
3311 at START_POS in OBJECT. */
3312
3313 static struct text_pos
3314 display_prop_end (it, object, start_pos)
3315 struct it *it;
3316 Lisp_Object object;
3317 struct text_pos start_pos;
3318 {
3319 Lisp_Object end;
3320 struct text_pos end_pos;
3321
3322 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3323 Qdisplay, object, Qnil);
3324 CHARPOS (end_pos) = XFASTINT (end);
3325 if (STRINGP (object))
3326 compute_string_pos (&end_pos, start_pos, it->string);
3327 else
3328 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3329
3330 return end_pos;
3331 }
3332
3333
3334 /* Set up IT from a single `display' sub-property value PROP. OBJECT
3335 is the object in which the `display' property was found. *POSITION
3336 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3337 means that we previously saw a display sub-property which already
3338 replaced text display with something else, for example an image;
3339 ignore such properties after the first one has been processed.
3340
3341 If PROP is a `space' or `image' sub-property, set *POSITION to the
3342 end position of the `display' property.
3343
3344 Value is non-zero if something was found which replaces the display
3345 of buffer or string text. */
3346
3347 static int
3348 handle_single_display_prop (it, prop, object, position,
3349 display_replaced_before_p)
3350 struct it *it;
3351 Lisp_Object prop;
3352 Lisp_Object object;
3353 struct text_pos *position;
3354 int display_replaced_before_p;
3355 {
3356 Lisp_Object value;
3357 int replaces_text_display_p = 0;
3358 Lisp_Object form;
3359
3360 /* If PROP is a list of the form `(when FORM . VALUE)', FORM is
3361 evaluated. If the result is nil, VALUE is ignored. */
3362 form = Qt;
3363 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3364 {
3365 prop = XCDR (prop);
3366 if (!CONSP (prop))
3367 return 0;
3368 form = XCAR (prop);
3369 prop = XCDR (prop);
3370 }
3371
3372 if (!NILP (form) && !EQ (form, Qt))
3373 {
3374 int count = SPECPDL_INDEX ();
3375 struct gcpro gcpro1;
3376
3377 /* Bind `object' to the object having the `display' property, a
3378 buffer or string. Bind `position' to the position in the
3379 object where the property was found, and `buffer-position'
3380 to the current position in the buffer. */
3381 specbind (Qobject, object);
3382 specbind (Qposition, make_number (CHARPOS (*position)));
3383 specbind (Qbuffer_position,
3384 make_number (STRINGP (object)
3385 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3386 GCPRO1 (form);
3387 form = safe_eval (form);
3388 UNGCPRO;
3389 unbind_to (count, Qnil);
3390 }
3391
3392 if (NILP (form))
3393 return 0;
3394
3395 if (CONSP (prop)
3396 && EQ (XCAR (prop), Qheight)
3397 && CONSP (XCDR (prop)))
3398 {
3399 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3400 return 0;
3401
3402 /* `(height HEIGHT)'. */
3403 it->font_height = XCAR (XCDR (prop));
3404 if (!NILP (it->font_height))
3405 {
3406 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3407 int new_height = -1;
3408
3409 if (CONSP (it->font_height)
3410 && (EQ (XCAR (it->font_height), Qplus)
3411 || EQ (XCAR (it->font_height), Qminus))
3412 && CONSP (XCDR (it->font_height))
3413 && INTEGERP (XCAR (XCDR (it->font_height))))
3414 {
3415 /* `(+ N)' or `(- N)' where N is an integer. */
3416 int steps = XINT (XCAR (XCDR (it->font_height)));
3417 if (EQ (XCAR (it->font_height), Qplus))
3418 steps = - steps;
3419 it->face_id = smaller_face (it->f, it->face_id, steps);
3420 }
3421 else if (FUNCTIONP (it->font_height))
3422 {
3423 /* Call function with current height as argument.
3424 Value is the new height. */
3425 Lisp_Object height;
3426 height = safe_call1 (it->font_height,
3427 face->lface[LFACE_HEIGHT_INDEX]);
3428 if (NUMBERP (height))
3429 new_height = XFLOATINT (height);
3430 }
3431 else if (NUMBERP (it->font_height))
3432 {
3433 /* Value is a multiple of the canonical char height. */
3434 struct face *face;
3435
3436 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3437 new_height = (XFLOATINT (it->font_height)
3438 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3439 }
3440 else
3441 {
3442 /* Evaluate IT->font_height with `height' bound to the
3443 current specified height to get the new height. */
3444 Lisp_Object value;
3445 int count = SPECPDL_INDEX ();
3446
3447 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3448 value = safe_eval (it->font_height);
3449 unbind_to (count, Qnil);
3450
3451 if (NUMBERP (value))
3452 new_height = XFLOATINT (value);
3453 }
3454
3455 if (new_height > 0)
3456 it->face_id = face_with_height (it->f, it->face_id, new_height);
3457 }
3458 }
3459 else if (CONSP (prop)
3460 && EQ (XCAR (prop), Qspace_width)
3461 && CONSP (XCDR (prop)))
3462 {
3463 /* `(space_width WIDTH)'. */
3464 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3465 return 0;
3466
3467 value = XCAR (XCDR (prop));
3468 if (NUMBERP (value) && XFLOATINT (value) > 0)
3469 it->space_width = value;
3470 }
3471 else if (CONSP (prop)
3472 && EQ (XCAR (prop), Qraise)
3473 && CONSP (XCDR (prop)))
3474 {
3475 /* `(raise FACTOR)'. */
3476 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3477 return 0;
3478
3479 #ifdef HAVE_WINDOW_SYSTEM
3480 value = XCAR (XCDR (prop));
3481 if (NUMBERP (value))
3482 {
3483 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3484 it->voffset = - (XFLOATINT (value)
3485 * (FONT_HEIGHT (face->font)));
3486 }
3487 #endif /* HAVE_WINDOW_SYSTEM */
3488 }
3489 else if (CONSP (prop)
3490 && (EQ (XCAR (prop), Qleft_fringe)
3491 || EQ (XCAR (prop), Qright_fringe))
3492 && CONSP (XCDR (prop)))
3493 {
3494 unsigned face_id = DEFAULT_FACE_ID;
3495
3496 /* `(left-fringe BITMAP FACE)'. */
3497 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3498 return 0;
3499
3500 #ifdef HAVE_WINDOW_SYSTEM
3501 value = XCAR (XCDR (prop));
3502 if (!NUMBERP (value)
3503 || !valid_fringe_bitmap_id_p (XINT (value)))
3504 return 0;
3505
3506 if (CONSP (XCDR (XCDR (prop))))
3507 {
3508 Lisp_Object face_name = XCAR (XCDR (XCDR (prop)));
3509 face_id = lookup_named_face (it->f, face_name, 'A');
3510 if (face_id < 0)
3511 return 0;
3512 }
3513
3514 if (EQ (XCAR (prop), Qleft_fringe))
3515 {
3516 it->left_user_fringe_bitmap = XINT (value);
3517 it->left_user_fringe_face_id = face_id;
3518 }
3519 else
3520 {
3521 it->right_user_fringe_bitmap = XINT (value);
3522 it->right_user_fringe_face_id = face_id;
3523 }
3524 #endif /* HAVE_WINDOW_SYSTEM */
3525 }
3526 else if (!it->string_from_display_prop_p)
3527 {
3528 /* `((margin left-margin) VALUE)' or `((margin right-margin)
3529 VALUE) or `((margin nil) VALUE)' or VALUE. */
3530 Lisp_Object location, value;
3531 struct text_pos start_pos;
3532 int valid_p;
3533
3534 /* Characters having this form of property are not displayed, so
3535 we have to find the end of the property. */
3536 start_pos = *position;
3537 *position = display_prop_end (it, object, start_pos);
3538 value = Qnil;
3539
3540 /* Let's stop at the new position and assume that all
3541 text properties change there. */
3542 it->stop_charpos = position->charpos;
3543
3544 location = Qunbound;
3545 if (CONSP (prop) && CONSP (XCAR (prop)))
3546 {
3547 Lisp_Object tem;
3548
3549 value = XCDR (prop);
3550 if (CONSP (value))
3551 value = XCAR (value);
3552
3553 tem = XCAR (prop);
3554 if (EQ (XCAR (tem), Qmargin)
3555 && (tem = XCDR (tem),
3556 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3557 (NILP (tem)
3558 || EQ (tem, Qleft_margin)
3559 || EQ (tem, Qright_margin))))
3560 location = tem;
3561 }
3562
3563 if (EQ (location, Qunbound))
3564 {
3565 location = Qnil;
3566 value = prop;
3567 }
3568
3569 #ifdef HAVE_WINDOW_SYSTEM
3570 if (FRAME_TERMCAP_P (it->f))
3571 valid_p = STRINGP (value);
3572 else
3573 valid_p = (STRINGP (value)
3574 || (CONSP (value) && EQ (XCAR (value), Qspace))
3575 || valid_image_p (value));
3576 #else /* not HAVE_WINDOW_SYSTEM */
3577 valid_p = STRINGP (value);
3578 #endif /* not HAVE_WINDOW_SYSTEM */
3579
3580 if ((EQ (location, Qleft_margin)
3581 || EQ (location, Qright_margin)
3582 || NILP (location))
3583 && valid_p
3584 && !display_replaced_before_p)
3585 {
3586 replaces_text_display_p = 1;
3587
3588 /* Save current settings of IT so that we can restore them
3589 when we are finished with the glyph property value. */
3590 push_it (it);
3591
3592 if (NILP (location))
3593 it->area = TEXT_AREA;
3594 else if (EQ (location, Qleft_margin))
3595 it->area = LEFT_MARGIN_AREA;
3596 else
3597 it->area = RIGHT_MARGIN_AREA;
3598
3599 if (STRINGP (value))
3600 {
3601 it->string = value;
3602 it->multibyte_p = STRING_MULTIBYTE (it->string);
3603 it->current.overlay_string_index = -1;
3604 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3605 it->end_charpos = it->string_nchars = SCHARS (it->string);
3606 it->method = next_element_from_string;
3607 it->stop_charpos = 0;
3608 it->string_from_display_prop_p = 1;
3609 /* Say that we haven't consumed the characters with
3610 `display' property yet. The call to pop_it in
3611 set_iterator_to_next will clean this up. */
3612 *position = start_pos;
3613 }
3614 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3615 {
3616 it->method = next_element_from_stretch;
3617 it->object = value;
3618 it->current.pos = it->position = start_pos;
3619 }
3620 #ifdef HAVE_WINDOW_SYSTEM
3621 else
3622 {
3623 it->what = IT_IMAGE;
3624 it->image_id = lookup_image (it->f, value);
3625 it->position = start_pos;
3626 it->object = NILP (object) ? it->w->buffer : object;
3627 it->method = next_element_from_image;
3628
3629 /* Say that we haven't consumed the characters with
3630 `display' property yet. The call to pop_it in
3631 set_iterator_to_next will clean this up. */
3632 *position = start_pos;
3633 }
3634 #endif /* HAVE_WINDOW_SYSTEM */
3635 }
3636 else
3637 /* Invalid property or property not supported. Restore
3638 the position to what it was before. */
3639 *position = start_pos;
3640 }
3641
3642 return replaces_text_display_p;
3643 }
3644
3645
3646 /* Check if PROP is a display sub-property value whose text should be
3647 treated as intangible. */
3648
3649 static int
3650 single_display_prop_intangible_p (prop)
3651 Lisp_Object prop;
3652 {
3653 /* Skip over `when FORM'. */
3654 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3655 {
3656 prop = XCDR (prop);
3657 if (!CONSP (prop))
3658 return 0;
3659 prop = XCDR (prop);
3660 }
3661
3662 if (STRINGP (prop))
3663 return 1;
3664
3665 if (!CONSP (prop))
3666 return 0;
3667
3668 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3669 we don't need to treat text as intangible. */
3670 if (EQ (XCAR (prop), Qmargin))
3671 {
3672 prop = XCDR (prop);
3673 if (!CONSP (prop))
3674 return 0;
3675
3676 prop = XCDR (prop);
3677 if (!CONSP (prop)
3678 || EQ (XCAR (prop), Qleft_margin)
3679 || EQ (XCAR (prop), Qright_margin))
3680 return 0;
3681 }
3682
3683 return (CONSP (prop)
3684 && (EQ (XCAR (prop), Qimage)
3685 || EQ (XCAR (prop), Qspace)));
3686 }
3687
3688
3689 /* Check if PROP is a display property value whose text should be
3690 treated as intangible. */
3691
3692 int
3693 display_prop_intangible_p (prop)
3694 Lisp_Object prop;
3695 {
3696 if (CONSP (prop)
3697 && CONSP (XCAR (prop))
3698 && !EQ (Qmargin, XCAR (XCAR (prop))))
3699 {
3700 /* A list of sub-properties. */
3701 while (CONSP (prop))
3702 {
3703 if (single_display_prop_intangible_p (XCAR (prop)))
3704 return 1;
3705 prop = XCDR (prop);
3706 }
3707 }
3708 else if (VECTORP (prop))
3709 {
3710 /* A vector of sub-properties. */
3711 int i;
3712 for (i = 0; i < ASIZE (prop); ++i)
3713 if (single_display_prop_intangible_p (AREF (prop, i)))
3714 return 1;
3715 }
3716 else
3717 return single_display_prop_intangible_p (prop);
3718
3719 return 0;
3720 }
3721
3722
3723 /* Return 1 if PROP is a display sub-property value containing STRING. */
3724
3725 static int
3726 single_display_prop_string_p (prop, string)
3727 Lisp_Object prop, string;
3728 {
3729 if (EQ (string, prop))
3730 return 1;
3731
3732 /* Skip over `when FORM'. */
3733 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3734 {
3735 prop = XCDR (prop);
3736 if (!CONSP (prop))
3737 return 0;
3738 prop = XCDR (prop);
3739 }
3740
3741 if (CONSP (prop))
3742 /* Skip over `margin LOCATION'. */
3743 if (EQ (XCAR (prop), Qmargin))
3744 {
3745 prop = XCDR (prop);
3746 if (!CONSP (prop))
3747 return 0;
3748
3749 prop = XCDR (prop);
3750 if (!CONSP (prop))
3751 return 0;
3752 }
3753
3754 return CONSP (prop) && EQ (XCAR (prop), string);
3755 }
3756
3757
3758 /* Return 1 if STRING appears in the `display' property PROP. */
3759
3760 static int
3761 display_prop_string_p (prop, string)
3762 Lisp_Object prop, string;
3763 {
3764 if (CONSP (prop)
3765 && CONSP (XCAR (prop))
3766 && !EQ (Qmargin, XCAR (XCAR (prop))))
3767 {
3768 /* A list of sub-properties. */
3769 while (CONSP (prop))
3770 {
3771 if (single_display_prop_string_p (XCAR (prop), string))
3772 return 1;
3773 prop = XCDR (prop);
3774 }
3775 }
3776 else if (VECTORP (prop))
3777 {
3778 /* A vector of sub-properties. */
3779 int i;
3780 for (i = 0; i < ASIZE (prop); ++i)
3781 if (single_display_prop_string_p (AREF (prop, i), string))
3782 return 1;
3783 }
3784 else
3785 return single_display_prop_string_p (prop, string);
3786
3787 return 0;
3788 }
3789
3790
3791 /* Determine from which buffer position in W's buffer STRING comes
3792 from. AROUND_CHARPOS is an approximate position where it could
3793 be from. Value is the buffer position or 0 if it couldn't be
3794 determined.
3795
3796 W's buffer must be current.
3797
3798 This function is necessary because we don't record buffer positions
3799 in glyphs generated from strings (to keep struct glyph small).
3800 This function may only use code that doesn't eval because it is
3801 called asynchronously from note_mouse_highlight. */
3802
3803 int
3804 string_buffer_position (w, string, around_charpos)
3805 struct window *w;
3806 Lisp_Object string;
3807 int around_charpos;
3808 {
3809 Lisp_Object limit, prop, pos;
3810 const int MAX_DISTANCE = 1000;
3811 int found = 0;
3812
3813 pos = make_number (around_charpos);
3814 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
3815 while (!found && !EQ (pos, limit))
3816 {
3817 prop = Fget_char_property (pos, Qdisplay, Qnil);
3818 if (!NILP (prop) && display_prop_string_p (prop, string))
3819 found = 1;
3820 else
3821 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
3822 }
3823
3824 if (!found)
3825 {
3826 pos = make_number (around_charpos);
3827 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
3828 while (!found && !EQ (pos, limit))
3829 {
3830 prop = Fget_char_property (pos, Qdisplay, Qnil);
3831 if (!NILP (prop) && display_prop_string_p (prop, string))
3832 found = 1;
3833 else
3834 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
3835 limit);
3836 }
3837 }
3838
3839 return found ? XINT (pos) : 0;
3840 }
3841
3842
3843 \f
3844 /***********************************************************************
3845 `composition' property
3846 ***********************************************************************/
3847
3848 /* Set up iterator IT from `composition' property at its current
3849 position. Called from handle_stop. */
3850
3851 static enum prop_handled
3852 handle_composition_prop (it)
3853 struct it *it;
3854 {
3855 Lisp_Object prop, string;
3856 int pos, pos_byte, end;
3857 enum prop_handled handled = HANDLED_NORMALLY;
3858
3859 if (STRINGP (it->string))
3860 {
3861 pos = IT_STRING_CHARPOS (*it);
3862 pos_byte = IT_STRING_BYTEPOS (*it);
3863 string = it->string;
3864 }
3865 else
3866 {
3867 pos = IT_CHARPOS (*it);
3868 pos_byte = IT_BYTEPOS (*it);
3869 string = Qnil;
3870 }
3871
3872 /* If there's a valid composition and point is not inside of the
3873 composition (in the case that the composition is from the current
3874 buffer), draw a glyph composed from the composition components. */
3875 if (find_composition (pos, -1, &pos, &end, &prop, string)
3876 && COMPOSITION_VALID_P (pos, end, prop)
3877 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
3878 {
3879 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
3880
3881 if (id >= 0)
3882 {
3883 it->method = next_element_from_composition;
3884 it->cmp_id = id;
3885 it->cmp_len = COMPOSITION_LENGTH (prop);
3886 /* For a terminal, draw only the first character of the
3887 components. */
3888 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
3889 it->len = (STRINGP (it->string)
3890 ? string_char_to_byte (it->string, end)
3891 : CHAR_TO_BYTE (end)) - pos_byte;
3892 it->stop_charpos = end;
3893 handled = HANDLED_RETURN;
3894 }
3895 }
3896
3897 return handled;
3898 }
3899
3900
3901 \f
3902 /***********************************************************************
3903 Overlay strings
3904 ***********************************************************************/
3905
3906 /* The following structure is used to record overlay strings for
3907 later sorting in load_overlay_strings. */
3908
3909 struct overlay_entry
3910 {
3911 Lisp_Object overlay;
3912 Lisp_Object string;
3913 int priority;
3914 int after_string_p;
3915 };
3916
3917
3918 /* Set up iterator IT from overlay strings at its current position.
3919 Called from handle_stop. */
3920
3921 static enum prop_handled
3922 handle_overlay_change (it)
3923 struct it *it;
3924 {
3925 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
3926 return HANDLED_RECOMPUTE_PROPS;
3927 else
3928 return HANDLED_NORMALLY;
3929 }
3930
3931
3932 /* Set up the next overlay string for delivery by IT, if there is an
3933 overlay string to deliver. Called by set_iterator_to_next when the
3934 end of the current overlay string is reached. If there are more
3935 overlay strings to display, IT->string and
3936 IT->current.overlay_string_index are set appropriately here.
3937 Otherwise IT->string is set to nil. */
3938
3939 static void
3940 next_overlay_string (it)
3941 struct it *it;
3942 {
3943 ++it->current.overlay_string_index;
3944 if (it->current.overlay_string_index == it->n_overlay_strings)
3945 {
3946 /* No more overlay strings. Restore IT's settings to what
3947 they were before overlay strings were processed, and
3948 continue to deliver from current_buffer. */
3949 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
3950
3951 pop_it (it);
3952 xassert (it->stop_charpos >= BEGV
3953 && it->stop_charpos <= it->end_charpos);
3954 it->string = Qnil;
3955 it->current.overlay_string_index = -1;
3956 SET_TEXT_POS (it->current.string_pos, -1, -1);
3957 it->n_overlay_strings = 0;
3958 it->method = next_element_from_buffer;
3959
3960 /* If we're at the end of the buffer, record that we have
3961 processed the overlay strings there already, so that
3962 next_element_from_buffer doesn't try it again. */
3963 if (IT_CHARPOS (*it) >= it->end_charpos)
3964 it->overlay_strings_at_end_processed_p = 1;
3965
3966 /* If we have to display `...' for invisible text, set
3967 the iterator up for that. */
3968 if (display_ellipsis_p)
3969 setup_for_ellipsis (it);
3970 }
3971 else
3972 {
3973 /* There are more overlay strings to process. If
3974 IT->current.overlay_string_index has advanced to a position
3975 where we must load IT->overlay_strings with more strings, do
3976 it. */
3977 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
3978
3979 if (it->current.overlay_string_index && i == 0)
3980 load_overlay_strings (it, 0);
3981
3982 /* Initialize IT to deliver display elements from the overlay
3983 string. */
3984 it->string = it->overlay_strings[i];
3985 it->multibyte_p = STRING_MULTIBYTE (it->string);
3986 SET_TEXT_POS (it->current.string_pos, 0, 0);
3987 it->method = next_element_from_string;
3988 it->stop_charpos = 0;
3989 }
3990
3991 CHECK_IT (it);
3992 }
3993
3994
3995 /* Compare two overlay_entry structures E1 and E2. Used as a
3996 comparison function for qsort in load_overlay_strings. Overlay
3997 strings for the same position are sorted so that
3998
3999 1. All after-strings come in front of before-strings, except
4000 when they come from the same overlay.
4001
4002 2. Within after-strings, strings are sorted so that overlay strings
4003 from overlays with higher priorities come first.
4004
4005 2. Within before-strings, strings are sorted so that overlay
4006 strings from overlays with higher priorities come last.
4007
4008 Value is analogous to strcmp. */
4009
4010
4011 static int
4012 compare_overlay_entries (e1, e2)
4013 void *e1, *e2;
4014 {
4015 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4016 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4017 int result;
4018
4019 if (entry1->after_string_p != entry2->after_string_p)
4020 {
4021 /* Let after-strings appear in front of before-strings if
4022 they come from different overlays. */
4023 if (EQ (entry1->overlay, entry2->overlay))
4024 result = entry1->after_string_p ? 1 : -1;
4025 else
4026 result = entry1->after_string_p ? -1 : 1;
4027 }
4028 else if (entry1->after_string_p)
4029 /* After-strings sorted in order of decreasing priority. */
4030 result = entry2->priority - entry1->priority;
4031 else
4032 /* Before-strings sorted in order of increasing priority. */
4033 result = entry1->priority - entry2->priority;
4034
4035 return result;
4036 }
4037
4038
4039 /* Load the vector IT->overlay_strings with overlay strings from IT's
4040 current buffer position, or from CHARPOS if that is > 0. Set
4041 IT->n_overlays to the total number of overlay strings found.
4042
4043 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4044 a time. On entry into load_overlay_strings,
4045 IT->current.overlay_string_index gives the number of overlay
4046 strings that have already been loaded by previous calls to this
4047 function.
4048
4049 IT->add_overlay_start contains an additional overlay start
4050 position to consider for taking overlay strings from, if non-zero.
4051 This position comes into play when the overlay has an `invisible'
4052 property, and both before and after-strings. When we've skipped to
4053 the end of the overlay, because of its `invisible' property, we
4054 nevertheless want its before-string to appear.
4055 IT->add_overlay_start will contain the overlay start position
4056 in this case.
4057
4058 Overlay strings are sorted so that after-string strings come in
4059 front of before-string strings. Within before and after-strings,
4060 strings are sorted by overlay priority. See also function
4061 compare_overlay_entries. */
4062
4063 static void
4064 load_overlay_strings (it, charpos)
4065 struct it *it;
4066 int charpos;
4067 {
4068 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4069 Lisp_Object overlay, window, str, invisible;
4070 struct Lisp_Overlay *ov;
4071 int start, end;
4072 int size = 20;
4073 int n = 0, i, j, invis_p;
4074 struct overlay_entry *entries
4075 = (struct overlay_entry *) alloca (size * sizeof *entries);
4076
4077 if (charpos <= 0)
4078 charpos = IT_CHARPOS (*it);
4079
4080 /* Append the overlay string STRING of overlay OVERLAY to vector
4081 `entries' which has size `size' and currently contains `n'
4082 elements. AFTER_P non-zero means STRING is an after-string of
4083 OVERLAY. */
4084 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4085 do \
4086 { \
4087 Lisp_Object priority; \
4088 \
4089 if (n == size) \
4090 { \
4091 int new_size = 2 * size; \
4092 struct overlay_entry *old = entries; \
4093 entries = \
4094 (struct overlay_entry *) alloca (new_size \
4095 * sizeof *entries); \
4096 bcopy (old, entries, size * sizeof *entries); \
4097 size = new_size; \
4098 } \
4099 \
4100 entries[n].string = (STRING); \
4101 entries[n].overlay = (OVERLAY); \
4102 priority = Foverlay_get ((OVERLAY), Qpriority); \
4103 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4104 entries[n].after_string_p = (AFTER_P); \
4105 ++n; \
4106 } \
4107 while (0)
4108
4109 /* Process overlay before the overlay center. */
4110 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4111 {
4112 XSETMISC (overlay, ov);
4113 xassert (OVERLAYP (overlay));
4114 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4115 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4116
4117 if (end < charpos)
4118 break;
4119
4120 /* Skip this overlay if it doesn't start or end at IT's current
4121 position. */
4122 if (end != charpos && start != charpos)
4123 continue;
4124
4125 /* Skip this overlay if it doesn't apply to IT->w. */
4126 window = Foverlay_get (overlay, Qwindow);
4127 if (WINDOWP (window) && XWINDOW (window) != it->w)
4128 continue;
4129
4130 /* If the text ``under'' the overlay is invisible, both before-
4131 and after-strings from this overlay are visible; start and
4132 end position are indistinguishable. */
4133 invisible = Foverlay_get (overlay, Qinvisible);
4134 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4135
4136 /* If overlay has a non-empty before-string, record it. */
4137 if ((start == charpos || (end == charpos && invis_p))
4138 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4139 && SCHARS (str))
4140 RECORD_OVERLAY_STRING (overlay, str, 0);
4141
4142 /* If overlay has a non-empty after-string, record it. */
4143 if ((end == charpos || (start == charpos && invis_p))
4144 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4145 && SCHARS (str))
4146 RECORD_OVERLAY_STRING (overlay, str, 1);
4147 }
4148
4149 /* Process overlays after the overlay center. */
4150 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4151 {
4152 XSETMISC (overlay, ov);
4153 xassert (OVERLAYP (overlay));
4154 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4155 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4156
4157 if (start > charpos)
4158 break;
4159
4160 /* Skip this overlay if it doesn't start or end at IT's current
4161 position. */
4162 if (end != charpos && start != charpos)
4163 continue;
4164
4165 /* Skip this overlay if it doesn't apply to IT->w. */
4166 window = Foverlay_get (overlay, Qwindow);
4167 if (WINDOWP (window) && XWINDOW (window) != it->w)
4168 continue;
4169
4170 /* If the text ``under'' the overlay is invisible, it has a zero
4171 dimension, and both before- and after-strings apply. */
4172 invisible = Foverlay_get (overlay, Qinvisible);
4173 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4174
4175 /* If overlay has a non-empty before-string, record it. */
4176 if ((start == charpos || (end == charpos && invis_p))
4177 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4178 && SCHARS (str))
4179 RECORD_OVERLAY_STRING (overlay, str, 0);
4180
4181 /* If overlay has a non-empty after-string, record it. */
4182 if ((end == charpos || (start == charpos && invis_p))
4183 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4184 && SCHARS (str))
4185 RECORD_OVERLAY_STRING (overlay, str, 1);
4186 }
4187
4188 #undef RECORD_OVERLAY_STRING
4189
4190 /* Sort entries. */
4191 if (n > 1)
4192 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4193
4194 /* Record the total number of strings to process. */
4195 it->n_overlay_strings = n;
4196
4197 /* IT->current.overlay_string_index is the number of overlay strings
4198 that have already been consumed by IT. Copy some of the
4199 remaining overlay strings to IT->overlay_strings. */
4200 i = 0;
4201 j = it->current.overlay_string_index;
4202 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4203 it->overlay_strings[i++] = entries[j++].string;
4204
4205 CHECK_IT (it);
4206 }
4207
4208
4209 /* Get the first chunk of overlay strings at IT's current buffer
4210 position, or at CHARPOS if that is > 0. Value is non-zero if at
4211 least one overlay string was found. */
4212
4213 static int
4214 get_overlay_strings (it, charpos)
4215 struct it *it;
4216 int charpos;
4217 {
4218 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4219 process. This fills IT->overlay_strings with strings, and sets
4220 IT->n_overlay_strings to the total number of strings to process.
4221 IT->pos.overlay_string_index has to be set temporarily to zero
4222 because load_overlay_strings needs this; it must be set to -1
4223 when no overlay strings are found because a zero value would
4224 indicate a position in the first overlay string. */
4225 it->current.overlay_string_index = 0;
4226 load_overlay_strings (it, charpos);
4227
4228 /* If we found overlay strings, set up IT to deliver display
4229 elements from the first one. Otherwise set up IT to deliver
4230 from current_buffer. */
4231 if (it->n_overlay_strings)
4232 {
4233 /* Make sure we know settings in current_buffer, so that we can
4234 restore meaningful values when we're done with the overlay
4235 strings. */
4236 compute_stop_pos (it);
4237 xassert (it->face_id >= 0);
4238
4239 /* Save IT's settings. They are restored after all overlay
4240 strings have been processed. */
4241 xassert (it->sp == 0);
4242 push_it (it);
4243
4244 /* Set up IT to deliver display elements from the first overlay
4245 string. */
4246 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4247 it->string = it->overlay_strings[0];
4248 it->stop_charpos = 0;
4249 xassert (STRINGP (it->string));
4250 it->end_charpos = SCHARS (it->string);
4251 it->multibyte_p = STRING_MULTIBYTE (it->string);
4252 it->method = next_element_from_string;
4253 }
4254 else
4255 {
4256 it->string = Qnil;
4257 it->current.overlay_string_index = -1;
4258 it->method = next_element_from_buffer;
4259 }
4260
4261 CHECK_IT (it);
4262
4263 /* Value is non-zero if we found at least one overlay string. */
4264 return STRINGP (it->string);
4265 }
4266
4267
4268 \f
4269 /***********************************************************************
4270 Saving and restoring state
4271 ***********************************************************************/
4272
4273 /* Save current settings of IT on IT->stack. Called, for example,
4274 before setting up IT for an overlay string, to be able to restore
4275 IT's settings to what they were after the overlay string has been
4276 processed. */
4277
4278 static void
4279 push_it (it)
4280 struct it *it;
4281 {
4282 struct iterator_stack_entry *p;
4283
4284 xassert (it->sp < 2);
4285 p = it->stack + it->sp;
4286
4287 p->stop_charpos = it->stop_charpos;
4288 xassert (it->face_id >= 0);
4289 p->face_id = it->face_id;
4290 p->string = it->string;
4291 p->pos = it->current;
4292 p->end_charpos = it->end_charpos;
4293 p->string_nchars = it->string_nchars;
4294 p->area = it->area;
4295 p->multibyte_p = it->multibyte_p;
4296 p->space_width = it->space_width;
4297 p->font_height = it->font_height;
4298 p->voffset = it->voffset;
4299 p->string_from_display_prop_p = it->string_from_display_prop_p;
4300 p->display_ellipsis_p = 0;
4301 ++it->sp;
4302 }
4303
4304
4305 /* Restore IT's settings from IT->stack. Called, for example, when no
4306 more overlay strings must be processed, and we return to delivering
4307 display elements from a buffer, or when the end of a string from a
4308 `display' property is reached and we return to delivering display
4309 elements from an overlay string, or from a buffer. */
4310
4311 static void
4312 pop_it (it)
4313 struct it *it;
4314 {
4315 struct iterator_stack_entry *p;
4316
4317 xassert (it->sp > 0);
4318 --it->sp;
4319 p = it->stack + it->sp;
4320 it->stop_charpos = p->stop_charpos;
4321 it->face_id = p->face_id;
4322 it->string = p->string;
4323 it->current = p->pos;
4324 it->end_charpos = p->end_charpos;
4325 it->string_nchars = p->string_nchars;
4326 it->area = p->area;
4327 it->multibyte_p = p->multibyte_p;
4328 it->space_width = p->space_width;
4329 it->font_height = p->font_height;
4330 it->voffset = p->voffset;
4331 it->string_from_display_prop_p = p->string_from_display_prop_p;
4332 }
4333
4334
4335 \f
4336 /***********************************************************************
4337 Moving over lines
4338 ***********************************************************************/
4339
4340 /* Set IT's current position to the previous line start. */
4341
4342 static void
4343 back_to_previous_line_start (it)
4344 struct it *it;
4345 {
4346 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4347 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4348 }
4349
4350
4351 /* Move IT to the next line start.
4352
4353 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4354 we skipped over part of the text (as opposed to moving the iterator
4355 continuously over the text). Otherwise, don't change the value
4356 of *SKIPPED_P.
4357
4358 Newlines may come from buffer text, overlay strings, or strings
4359 displayed via the `display' property. That's the reason we can't
4360 simply use find_next_newline_no_quit.
4361
4362 Note that this function may not skip over invisible text that is so
4363 because of text properties and immediately follows a newline. If
4364 it would, function reseat_at_next_visible_line_start, when called
4365 from set_iterator_to_next, would effectively make invisible
4366 characters following a newline part of the wrong glyph row, which
4367 leads to wrong cursor motion. */
4368
4369 static int
4370 forward_to_next_line_start (it, skipped_p)
4371 struct it *it;
4372 int *skipped_p;
4373 {
4374 int old_selective, newline_found_p, n;
4375 const int MAX_NEWLINE_DISTANCE = 500;
4376
4377 /* If already on a newline, just consume it to avoid unintended
4378 skipping over invisible text below. */
4379 if (it->what == IT_CHARACTER
4380 && it->c == '\n'
4381 && CHARPOS (it->position) == IT_CHARPOS (*it))
4382 {
4383 set_iterator_to_next (it, 0);
4384 it->c = 0;
4385 return 1;
4386 }
4387
4388 /* Don't handle selective display in the following. It's (a)
4389 unnecessary because it's done by the caller, and (b) leads to an
4390 infinite recursion because next_element_from_ellipsis indirectly
4391 calls this function. */
4392 old_selective = it->selective;
4393 it->selective = 0;
4394
4395 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4396 from buffer text. */
4397 for (n = newline_found_p = 0;
4398 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4399 n += STRINGP (it->string) ? 0 : 1)
4400 {
4401 if (!get_next_display_element (it))
4402 return 0;
4403 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4404 set_iterator_to_next (it, 0);
4405 }
4406
4407 /* If we didn't find a newline near enough, see if we can use a
4408 short-cut. */
4409 if (!newline_found_p)
4410 {
4411 int start = IT_CHARPOS (*it);
4412 int limit = find_next_newline_no_quit (start, 1);
4413 Lisp_Object pos;
4414
4415 xassert (!STRINGP (it->string));
4416
4417 /* If there isn't any `display' property in sight, and no
4418 overlays, we can just use the position of the newline in
4419 buffer text. */
4420 if (it->stop_charpos >= limit
4421 || ((pos = Fnext_single_property_change (make_number (start),
4422 Qdisplay,
4423 Qnil, make_number (limit)),
4424 NILP (pos))
4425 && next_overlay_change (start) == ZV))
4426 {
4427 IT_CHARPOS (*it) = limit;
4428 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4429 *skipped_p = newline_found_p = 1;
4430 }
4431 else
4432 {
4433 while (get_next_display_element (it)
4434 && !newline_found_p)
4435 {
4436 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4437 set_iterator_to_next (it, 0);
4438 }
4439 }
4440 }
4441
4442 it->selective = old_selective;
4443 return newline_found_p;
4444 }
4445
4446
4447 /* Set IT's current position to the previous visible line start. Skip
4448 invisible text that is so either due to text properties or due to
4449 selective display. Caution: this does not change IT->current_x and
4450 IT->hpos. */
4451
4452 static void
4453 back_to_previous_visible_line_start (it)
4454 struct it *it;
4455 {
4456 int visible_p = 0;
4457
4458 /* Go back one newline if not on BEGV already. */
4459 if (IT_CHARPOS (*it) > BEGV)
4460 back_to_previous_line_start (it);
4461
4462 /* Move over lines that are invisible because of selective display
4463 or text properties. */
4464 while (IT_CHARPOS (*it) > BEGV
4465 && !visible_p)
4466 {
4467 visible_p = 1;
4468
4469 /* If selective > 0, then lines indented more than that values
4470 are invisible. */
4471 if (it->selective > 0
4472 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4473 (double) it->selective)) /* iftc */
4474 visible_p = 0;
4475 else
4476 {
4477 Lisp_Object prop;
4478
4479 prop = Fget_char_property (make_number (IT_CHARPOS (*it)),
4480 Qinvisible, it->window);
4481 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4482 visible_p = 0;
4483 }
4484
4485 /* Back one more newline if the current one is invisible. */
4486 if (!visible_p)
4487 back_to_previous_line_start (it);
4488 }
4489
4490 xassert (IT_CHARPOS (*it) >= BEGV);
4491 xassert (IT_CHARPOS (*it) == BEGV
4492 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4493 CHECK_IT (it);
4494 }
4495
4496
4497 /* Reseat iterator IT at the previous visible line start. Skip
4498 invisible text that is so either due to text properties or due to
4499 selective display. At the end, update IT's overlay information,
4500 face information etc. */
4501
4502 static void
4503 reseat_at_previous_visible_line_start (it)
4504 struct it *it;
4505 {
4506 back_to_previous_visible_line_start (it);
4507 reseat (it, it->current.pos, 1);
4508 CHECK_IT (it);
4509 }
4510
4511
4512 /* Reseat iterator IT on the next visible line start in the current
4513 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4514 preceding the line start. Skip over invisible text that is so
4515 because of selective display. Compute faces, overlays etc at the
4516 new position. Note that this function does not skip over text that
4517 is invisible because of text properties. */
4518
4519 static void
4520 reseat_at_next_visible_line_start (it, on_newline_p)
4521 struct it *it;
4522 int on_newline_p;
4523 {
4524 int newline_found_p, skipped_p = 0;
4525
4526 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4527
4528 /* Skip over lines that are invisible because they are indented
4529 more than the value of IT->selective. */
4530 if (it->selective > 0)
4531 while (IT_CHARPOS (*it) < ZV
4532 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4533 (double) it->selective)) /* iftc */
4534 {
4535 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4536 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4537 }
4538
4539 /* Position on the newline if that's what's requested. */
4540 if (on_newline_p && newline_found_p)
4541 {
4542 if (STRINGP (it->string))
4543 {
4544 if (IT_STRING_CHARPOS (*it) > 0)
4545 {
4546 --IT_STRING_CHARPOS (*it);
4547 --IT_STRING_BYTEPOS (*it);
4548 }
4549 }
4550 else if (IT_CHARPOS (*it) > BEGV)
4551 {
4552 --IT_CHARPOS (*it);
4553 --IT_BYTEPOS (*it);
4554 reseat (it, it->current.pos, 0);
4555 }
4556 }
4557 else if (skipped_p)
4558 reseat (it, it->current.pos, 0);
4559
4560 CHECK_IT (it);
4561 }
4562
4563
4564 \f
4565 /***********************************************************************
4566 Changing an iterator's position
4567 ***********************************************************************/
4568
4569 /* Change IT's current position to POS in current_buffer. If FORCE_P
4570 is non-zero, always check for text properties at the new position.
4571 Otherwise, text properties are only looked up if POS >=
4572 IT->check_charpos of a property. */
4573
4574 static void
4575 reseat (it, pos, force_p)
4576 struct it *it;
4577 struct text_pos pos;
4578 int force_p;
4579 {
4580 int original_pos = IT_CHARPOS (*it);
4581
4582 reseat_1 (it, pos, 0);
4583
4584 /* Determine where to check text properties. Avoid doing it
4585 where possible because text property lookup is very expensive. */
4586 if (force_p
4587 || CHARPOS (pos) > it->stop_charpos
4588 || CHARPOS (pos) < original_pos)
4589 handle_stop (it);
4590
4591 CHECK_IT (it);
4592 }
4593
4594
4595 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4596 IT->stop_pos to POS, also. */
4597
4598 static void
4599 reseat_1 (it, pos, set_stop_p)
4600 struct it *it;
4601 struct text_pos pos;
4602 int set_stop_p;
4603 {
4604 /* Don't call this function when scanning a C string. */
4605 xassert (it->s == NULL);
4606
4607 /* POS must be a reasonable value. */
4608 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4609
4610 it->current.pos = it->position = pos;
4611 XSETBUFFER (it->object, current_buffer);
4612 it->end_charpos = ZV;
4613 it->dpvec = NULL;
4614 it->current.dpvec_index = -1;
4615 it->current.overlay_string_index = -1;
4616 IT_STRING_CHARPOS (*it) = -1;
4617 IT_STRING_BYTEPOS (*it) = -1;
4618 it->string = Qnil;
4619 it->method = next_element_from_buffer;
4620 /* RMS: I added this to fix a bug in move_it_vertically_backward
4621 where it->area continued to relate to the starting point
4622 for the backward motion. Bug report from
4623 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4624 However, I am not sure whether reseat still does the right thing
4625 in general after this change. */
4626 it->area = TEXT_AREA;
4627 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4628 it->sp = 0;
4629 it->face_before_selective_p = 0;
4630
4631 if (set_stop_p)
4632 it->stop_charpos = CHARPOS (pos);
4633 }
4634
4635
4636 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4637 If S is non-null, it is a C string to iterate over. Otherwise,
4638 STRING gives a Lisp string to iterate over.
4639
4640 If PRECISION > 0, don't return more then PRECISION number of
4641 characters from the string.
4642
4643 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4644 characters have been returned. FIELD_WIDTH < 0 means an infinite
4645 field width.
4646
4647 MULTIBYTE = 0 means disable processing of multibyte characters,
4648 MULTIBYTE > 0 means enable it,
4649 MULTIBYTE < 0 means use IT->multibyte_p.
4650
4651 IT must be initialized via a prior call to init_iterator before
4652 calling this function. */
4653
4654 static void
4655 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4656 struct it *it;
4657 unsigned char *s;
4658 Lisp_Object string;
4659 int charpos;
4660 int precision, field_width, multibyte;
4661 {
4662 /* No region in strings. */
4663 it->region_beg_charpos = it->region_end_charpos = -1;
4664
4665 /* No text property checks performed by default, but see below. */
4666 it->stop_charpos = -1;
4667
4668 /* Set iterator position and end position. */
4669 bzero (&it->current, sizeof it->current);
4670 it->current.overlay_string_index = -1;
4671 it->current.dpvec_index = -1;
4672 xassert (charpos >= 0);
4673
4674 /* If STRING is specified, use its multibyteness, otherwise use the
4675 setting of MULTIBYTE, if specified. */
4676 if (multibyte >= 0)
4677 it->multibyte_p = multibyte > 0;
4678
4679 if (s == NULL)
4680 {
4681 xassert (STRINGP (string));
4682 it->string = string;
4683 it->s = NULL;
4684 it->end_charpos = it->string_nchars = SCHARS (string);
4685 it->method = next_element_from_string;
4686 it->current.string_pos = string_pos (charpos, string);
4687 }
4688 else
4689 {
4690 it->s = s;
4691 it->string = Qnil;
4692
4693 /* Note that we use IT->current.pos, not it->current.string_pos,
4694 for displaying C strings. */
4695 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4696 if (it->multibyte_p)
4697 {
4698 it->current.pos = c_string_pos (charpos, s, 1);
4699 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4700 }
4701 else
4702 {
4703 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4704 it->end_charpos = it->string_nchars = strlen (s);
4705 }
4706
4707 it->method = next_element_from_c_string;
4708 }
4709
4710 /* PRECISION > 0 means don't return more than PRECISION characters
4711 from the string. */
4712 if (precision > 0 && it->end_charpos - charpos > precision)
4713 it->end_charpos = it->string_nchars = charpos + precision;
4714
4715 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4716 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4717 FIELD_WIDTH < 0 means infinite field width. This is useful for
4718 padding with `-' at the end of a mode line. */
4719 if (field_width < 0)
4720 field_width = INFINITY;
4721 if (field_width > it->end_charpos - charpos)
4722 it->end_charpos = charpos + field_width;
4723
4724 /* Use the standard display table for displaying strings. */
4725 if (DISP_TABLE_P (Vstandard_display_table))
4726 it->dp = XCHAR_TABLE (Vstandard_display_table);
4727
4728 it->stop_charpos = charpos;
4729 CHECK_IT (it);
4730 }
4731
4732
4733 \f
4734 /***********************************************************************
4735 Iteration
4736 ***********************************************************************/
4737
4738 /* Load IT's display element fields with information about the next
4739 display element from the current position of IT. Value is zero if
4740 end of buffer (or C string) is reached. */
4741
4742 int
4743 get_next_display_element (it)
4744 struct it *it;
4745 {
4746 /* Non-zero means that we found a display element. Zero means that
4747 we hit the end of what we iterate over. Performance note: the
4748 function pointer `method' used here turns out to be faster than
4749 using a sequence of if-statements. */
4750 int success_p = (*it->method) (it);
4751
4752 if (it->what == IT_CHARACTER)
4753 {
4754 /* Map via display table or translate control characters.
4755 IT->c, IT->len etc. have been set to the next character by
4756 the function call above. If we have a display table, and it
4757 contains an entry for IT->c, translate it. Don't do this if
4758 IT->c itself comes from a display table, otherwise we could
4759 end up in an infinite recursion. (An alternative could be to
4760 count the recursion depth of this function and signal an
4761 error when a certain maximum depth is reached.) Is it worth
4762 it? */
4763 if (success_p && it->dpvec == NULL)
4764 {
4765 Lisp_Object dv;
4766
4767 if (it->dp
4768 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
4769 VECTORP (dv)))
4770 {
4771 struct Lisp_Vector *v = XVECTOR (dv);
4772
4773 /* Return the first character from the display table
4774 entry, if not empty. If empty, don't display the
4775 current character. */
4776 if (v->size)
4777 {
4778 it->dpvec_char_len = it->len;
4779 it->dpvec = v->contents;
4780 it->dpend = v->contents + v->size;
4781 it->current.dpvec_index = 0;
4782 it->method = next_element_from_display_vector;
4783 success_p = get_next_display_element (it);
4784 }
4785 else
4786 {
4787 set_iterator_to_next (it, 0);
4788 success_p = get_next_display_element (it);
4789 }
4790 }
4791
4792 /* Translate control characters into `\003' or `^C' form.
4793 Control characters coming from a display table entry are
4794 currently not translated because we use IT->dpvec to hold
4795 the translation. This could easily be changed but I
4796 don't believe that it is worth doing.
4797
4798 If it->multibyte_p is nonzero, eight-bit characters and
4799 non-printable multibyte characters are also translated to
4800 octal form.
4801
4802 If it->multibyte_p is zero, eight-bit characters that
4803 don't have corresponding multibyte char code are also
4804 translated to octal form. */
4805 else if ((it->c < ' '
4806 && (it->area != TEXT_AREA
4807 || (it->c != '\n' && it->c != '\t')))
4808 || (it->multibyte_p
4809 ? ((it->c >= 127
4810 && it->len == 1)
4811 || !CHAR_PRINTABLE_P (it->c))
4812 : (it->c >= 127
4813 && it->c == unibyte_char_to_multibyte (it->c))))
4814 {
4815 /* IT->c is a control character which must be displayed
4816 either as '\003' or as `^C' where the '\\' and '^'
4817 can be defined in the display table. Fill
4818 IT->ctl_chars with glyphs for what we have to
4819 display. Then, set IT->dpvec to these glyphs. */
4820 GLYPH g;
4821
4822 if (it->c < 128 && it->ctl_arrow_p)
4823 {
4824 /* Set IT->ctl_chars[0] to the glyph for `^'. */
4825 if (it->dp
4826 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
4827 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
4828 g = XINT (DISP_CTRL_GLYPH (it->dp));
4829 else
4830 g = FAST_MAKE_GLYPH ('^', 0);
4831 XSETINT (it->ctl_chars[0], g);
4832
4833 g = FAST_MAKE_GLYPH (it->c ^ 0100, 0);
4834 XSETINT (it->ctl_chars[1], g);
4835
4836 /* Set up IT->dpvec and return first character from it. */
4837 it->dpvec_char_len = it->len;
4838 it->dpvec = it->ctl_chars;
4839 it->dpend = it->dpvec + 2;
4840 it->current.dpvec_index = 0;
4841 it->method = next_element_from_display_vector;
4842 get_next_display_element (it);
4843 }
4844 else
4845 {
4846 unsigned char str[MAX_MULTIBYTE_LENGTH];
4847 int len;
4848 int i;
4849 GLYPH escape_glyph;
4850
4851 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
4852 if (it->dp
4853 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
4854 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
4855 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
4856 else
4857 escape_glyph = FAST_MAKE_GLYPH ('\\', 0);
4858
4859 if (SINGLE_BYTE_CHAR_P (it->c))
4860 str[0] = it->c, len = 1;
4861 else
4862 {
4863 len = CHAR_STRING_NO_SIGNAL (it->c, str);
4864 if (len < 0)
4865 {
4866 /* It's an invalid character, which
4867 shouldn't happen actually, but due to
4868 bugs it may happen. Let's print the char
4869 as is, there's not much meaningful we can
4870 do with it. */
4871 str[0] = it->c;
4872 str[1] = it->c >> 8;
4873 str[2] = it->c >> 16;
4874 str[3] = it->c >> 24;
4875 len = 4;
4876 }
4877 }
4878
4879 for (i = 0; i < len; i++)
4880 {
4881 XSETINT (it->ctl_chars[i * 4], escape_glyph);
4882 /* Insert three more glyphs into IT->ctl_chars for
4883 the octal display of the character. */
4884 g = FAST_MAKE_GLYPH (((str[i] >> 6) & 7) + '0', 0);
4885 XSETINT (it->ctl_chars[i * 4 + 1], g);
4886 g = FAST_MAKE_GLYPH (((str[i] >> 3) & 7) + '0', 0);
4887 XSETINT (it->ctl_chars[i * 4 + 2], g);
4888 g = FAST_MAKE_GLYPH ((str[i] & 7) + '0', 0);
4889 XSETINT (it->ctl_chars[i * 4 + 3], g);
4890 }
4891
4892 /* Set up IT->dpvec and return the first character
4893 from it. */
4894 it->dpvec_char_len = it->len;
4895 it->dpvec = it->ctl_chars;
4896 it->dpend = it->dpvec + len * 4;
4897 it->current.dpvec_index = 0;
4898 it->method = next_element_from_display_vector;
4899 get_next_display_element (it);
4900 }
4901 }
4902 }
4903
4904 /* Adjust face id for a multibyte character. There are no
4905 multibyte character in unibyte text. */
4906 if (it->multibyte_p
4907 && success_p
4908 && FRAME_WINDOW_P (it->f))
4909 {
4910 struct face *face = FACE_FROM_ID (it->f, it->face_id);
4911 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
4912 }
4913 }
4914
4915 /* Is this character the last one of a run of characters with
4916 box? If yes, set IT->end_of_box_run_p to 1. */
4917 if (it->face_box_p
4918 && it->s == NULL)
4919 {
4920 int face_id;
4921 struct face *face;
4922
4923 it->end_of_box_run_p
4924 = ((face_id = face_after_it_pos (it),
4925 face_id != it->face_id)
4926 && (face = FACE_FROM_ID (it->f, face_id),
4927 face->box == FACE_NO_BOX));
4928 }
4929
4930 /* Value is 0 if end of buffer or string reached. */
4931 return success_p;
4932 }
4933
4934
4935 /* Move IT to the next display element.
4936
4937 RESEAT_P non-zero means if called on a newline in buffer text,
4938 skip to the next visible line start.
4939
4940 Functions get_next_display_element and set_iterator_to_next are
4941 separate because I find this arrangement easier to handle than a
4942 get_next_display_element function that also increments IT's
4943 position. The way it is we can first look at an iterator's current
4944 display element, decide whether it fits on a line, and if it does,
4945 increment the iterator position. The other way around we probably
4946 would either need a flag indicating whether the iterator has to be
4947 incremented the next time, or we would have to implement a
4948 decrement position function which would not be easy to write. */
4949
4950 void
4951 set_iterator_to_next (it, reseat_p)
4952 struct it *it;
4953 int reseat_p;
4954 {
4955 /* Reset flags indicating start and end of a sequence of characters
4956 with box. Reset them at the start of this function because
4957 moving the iterator to a new position might set them. */
4958 it->start_of_box_run_p = it->end_of_box_run_p = 0;
4959
4960 if (it->method == next_element_from_buffer)
4961 {
4962 /* The current display element of IT is a character from
4963 current_buffer. Advance in the buffer, and maybe skip over
4964 invisible lines that are so because of selective display. */
4965 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
4966 reseat_at_next_visible_line_start (it, 0);
4967 else
4968 {
4969 xassert (it->len != 0);
4970 IT_BYTEPOS (*it) += it->len;
4971 IT_CHARPOS (*it) += 1;
4972 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
4973 }
4974 }
4975 else if (it->method == next_element_from_composition)
4976 {
4977 xassert (it->cmp_id >= 0 && it ->cmp_id < n_compositions);
4978 if (STRINGP (it->string))
4979 {
4980 IT_STRING_BYTEPOS (*it) += it->len;
4981 IT_STRING_CHARPOS (*it) += it->cmp_len;
4982 it->method = next_element_from_string;
4983 goto consider_string_end;
4984 }
4985 else
4986 {
4987 IT_BYTEPOS (*it) += it->len;
4988 IT_CHARPOS (*it) += it->cmp_len;
4989 it->method = next_element_from_buffer;
4990 }
4991 }
4992 else if (it->method == next_element_from_c_string)
4993 {
4994 /* Current display element of IT is from a C string. */
4995 IT_BYTEPOS (*it) += it->len;
4996 IT_CHARPOS (*it) += 1;
4997 }
4998 else if (it->method == next_element_from_display_vector)
4999 {
5000 /* Current display element of IT is from a display table entry.
5001 Advance in the display table definition. Reset it to null if
5002 end reached, and continue with characters from buffers/
5003 strings. */
5004 ++it->current.dpvec_index;
5005
5006 /* Restore face of the iterator to what they were before the
5007 display vector entry (these entries may contain faces). */
5008 it->face_id = it->saved_face_id;
5009
5010 if (it->dpvec + it->current.dpvec_index == it->dpend)
5011 {
5012 if (it->s)
5013 it->method = next_element_from_c_string;
5014 else if (STRINGP (it->string))
5015 it->method = next_element_from_string;
5016 else
5017 it->method = next_element_from_buffer;
5018
5019 it->dpvec = NULL;
5020 it->current.dpvec_index = -1;
5021
5022 /* Skip over characters which were displayed via IT->dpvec. */
5023 if (it->dpvec_char_len < 0)
5024 reseat_at_next_visible_line_start (it, 1);
5025 else if (it->dpvec_char_len > 0)
5026 {
5027 it->len = it->dpvec_char_len;
5028 set_iterator_to_next (it, reseat_p);
5029 }
5030 }
5031 }
5032 else if (it->method == next_element_from_string)
5033 {
5034 /* Current display element is a character from a Lisp string. */
5035 xassert (it->s == NULL && STRINGP (it->string));
5036 IT_STRING_BYTEPOS (*it) += it->len;
5037 IT_STRING_CHARPOS (*it) += 1;
5038
5039 consider_string_end:
5040
5041 if (it->current.overlay_string_index >= 0)
5042 {
5043 /* IT->string is an overlay string. Advance to the
5044 next, if there is one. */
5045 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5046 next_overlay_string (it);
5047 }
5048 else
5049 {
5050 /* IT->string is not an overlay string. If we reached
5051 its end, and there is something on IT->stack, proceed
5052 with what is on the stack. This can be either another
5053 string, this time an overlay string, or a buffer. */
5054 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5055 && it->sp > 0)
5056 {
5057 pop_it (it);
5058 if (!STRINGP (it->string))
5059 it->method = next_element_from_buffer;
5060 else
5061 goto consider_string_end;
5062 }
5063 }
5064 }
5065 else if (it->method == next_element_from_image
5066 || it->method == next_element_from_stretch)
5067 {
5068 /* The position etc with which we have to proceed are on
5069 the stack. The position may be at the end of a string,
5070 if the `display' property takes up the whole string. */
5071 pop_it (it);
5072 it->image_id = 0;
5073 if (STRINGP (it->string))
5074 {
5075 it->method = next_element_from_string;
5076 goto consider_string_end;
5077 }
5078 else
5079 it->method = next_element_from_buffer;
5080 }
5081 else
5082 /* There are no other methods defined, so this should be a bug. */
5083 abort ();
5084
5085 xassert (it->method != next_element_from_string
5086 || (STRINGP (it->string)
5087 && IT_STRING_CHARPOS (*it) >= 0));
5088 }
5089
5090
5091 /* Load IT's display element fields with information about the next
5092 display element which comes from a display table entry or from the
5093 result of translating a control character to one of the forms `^C'
5094 or `\003'. IT->dpvec holds the glyphs to return as characters. */
5095
5096 static int
5097 next_element_from_display_vector (it)
5098 struct it *it;
5099 {
5100 /* Precondition. */
5101 xassert (it->dpvec && it->current.dpvec_index >= 0);
5102
5103 /* Remember the current face id in case glyphs specify faces.
5104 IT's face is restored in set_iterator_to_next. */
5105 it->saved_face_id = it->face_id;
5106
5107 if (INTEGERP (*it->dpvec)
5108 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5109 {
5110 int lface_id;
5111 GLYPH g;
5112
5113 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5114 it->c = FAST_GLYPH_CHAR (g);
5115 it->len = CHAR_BYTES (it->c);
5116
5117 /* The entry may contain a face id to use. Such a face id is
5118 the id of a Lisp face, not a realized face. A face id of
5119 zero means no face is specified. */
5120 lface_id = FAST_GLYPH_FACE (g);
5121 if (lface_id)
5122 {
5123 /* The function returns -1 if lface_id is invalid. */
5124 int face_id = ascii_face_of_lisp_face (it->f, lface_id);
5125 if (face_id >= 0)
5126 it->face_id = face_id;
5127 }
5128 }
5129 else
5130 /* Display table entry is invalid. Return a space. */
5131 it->c = ' ', it->len = 1;
5132
5133 /* Don't change position and object of the iterator here. They are
5134 still the values of the character that had this display table
5135 entry or was translated, and that's what we want. */
5136 it->what = IT_CHARACTER;
5137 return 1;
5138 }
5139
5140
5141 /* Load IT with the next display element from Lisp string IT->string.
5142 IT->current.string_pos is the current position within the string.
5143 If IT->current.overlay_string_index >= 0, the Lisp string is an
5144 overlay string. */
5145
5146 static int
5147 next_element_from_string (it)
5148 struct it *it;
5149 {
5150 struct text_pos position;
5151
5152 xassert (STRINGP (it->string));
5153 xassert (IT_STRING_CHARPOS (*it) >= 0);
5154 position = it->current.string_pos;
5155
5156 /* Time to check for invisible text? */
5157 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5158 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5159 {
5160 handle_stop (it);
5161
5162 /* Since a handler may have changed IT->method, we must
5163 recurse here. */
5164 return get_next_display_element (it);
5165 }
5166
5167 if (it->current.overlay_string_index >= 0)
5168 {
5169 /* Get the next character from an overlay string. In overlay
5170 strings, There is no field width or padding with spaces to
5171 do. */
5172 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5173 {
5174 it->what = IT_EOB;
5175 return 0;
5176 }
5177 else if (STRING_MULTIBYTE (it->string))
5178 {
5179 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5180 const unsigned char *s = (SDATA (it->string)
5181 + IT_STRING_BYTEPOS (*it));
5182 it->c = string_char_and_length (s, remaining, &it->len);
5183 }
5184 else
5185 {
5186 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5187 it->len = 1;
5188 }
5189 }
5190 else
5191 {
5192 /* Get the next character from a Lisp string that is not an
5193 overlay string. Such strings come from the mode line, for
5194 example. We may have to pad with spaces, or truncate the
5195 string. See also next_element_from_c_string. */
5196 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5197 {
5198 it->what = IT_EOB;
5199 return 0;
5200 }
5201 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5202 {
5203 /* Pad with spaces. */
5204 it->c = ' ', it->len = 1;
5205 CHARPOS (position) = BYTEPOS (position) = -1;
5206 }
5207 else if (STRING_MULTIBYTE (it->string))
5208 {
5209 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5210 const unsigned char *s = (SDATA (it->string)
5211 + IT_STRING_BYTEPOS (*it));
5212 it->c = string_char_and_length (s, maxlen, &it->len);
5213 }
5214 else
5215 {
5216 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5217 it->len = 1;
5218 }
5219 }
5220
5221 /* Record what we have and where it came from. Note that we store a
5222 buffer position in IT->position although it could arguably be a
5223 string position. */
5224 it->what = IT_CHARACTER;
5225 it->object = it->string;
5226 it->position = position;
5227 return 1;
5228 }
5229
5230
5231 /* Load IT with next display element from C string IT->s.
5232 IT->string_nchars is the maximum number of characters to return
5233 from the string. IT->end_charpos may be greater than
5234 IT->string_nchars when this function is called, in which case we
5235 may have to return padding spaces. Value is zero if end of string
5236 reached, including padding spaces. */
5237
5238 static int
5239 next_element_from_c_string (it)
5240 struct it *it;
5241 {
5242 int success_p = 1;
5243
5244 xassert (it->s);
5245 it->what = IT_CHARACTER;
5246 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5247 it->object = Qnil;
5248
5249 /* IT's position can be greater IT->string_nchars in case a field
5250 width or precision has been specified when the iterator was
5251 initialized. */
5252 if (IT_CHARPOS (*it) >= it->end_charpos)
5253 {
5254 /* End of the game. */
5255 it->what = IT_EOB;
5256 success_p = 0;
5257 }
5258 else if (IT_CHARPOS (*it) >= it->string_nchars)
5259 {
5260 /* Pad with spaces. */
5261 it->c = ' ', it->len = 1;
5262 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5263 }
5264 else if (it->multibyte_p)
5265 {
5266 /* Implementation note: The calls to strlen apparently aren't a
5267 performance problem because there is no noticeable performance
5268 difference between Emacs running in unibyte or multibyte mode. */
5269 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5270 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5271 maxlen, &it->len);
5272 }
5273 else
5274 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5275
5276 return success_p;
5277 }
5278
5279
5280 /* Set up IT to return characters from an ellipsis, if appropriate.
5281 The definition of the ellipsis glyphs may come from a display table
5282 entry. This function Fills IT with the first glyph from the
5283 ellipsis if an ellipsis is to be displayed. */
5284
5285 static int
5286 next_element_from_ellipsis (it)
5287 struct it *it;
5288 {
5289 if (it->selective_display_ellipsis_p)
5290 {
5291 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
5292 {
5293 /* Use the display table definition for `...'. Invalid glyphs
5294 will be handled by the method returning elements from dpvec. */
5295 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
5296 it->dpvec_char_len = it->len;
5297 it->dpvec = v->contents;
5298 it->dpend = v->contents + v->size;
5299 it->current.dpvec_index = 0;
5300 it->method = next_element_from_display_vector;
5301 }
5302 else
5303 {
5304 /* Use default `...' which is stored in default_invis_vector. */
5305 it->dpvec_char_len = it->len;
5306 it->dpvec = default_invis_vector;
5307 it->dpend = default_invis_vector + 3;
5308 it->current.dpvec_index = 0;
5309 it->method = next_element_from_display_vector;
5310 }
5311 }
5312 else
5313 {
5314 /* The face at the current position may be different from the
5315 face we find after the invisible text. Remember what it
5316 was in IT->saved_face_id, and signal that it's there by
5317 setting face_before_selective_p. */
5318 it->saved_face_id = it->face_id;
5319 it->method = next_element_from_buffer;
5320 reseat_at_next_visible_line_start (it, 1);
5321 it->face_before_selective_p = 1;
5322 }
5323
5324 return get_next_display_element (it);
5325 }
5326
5327
5328 /* Deliver an image display element. The iterator IT is already
5329 filled with image information (done in handle_display_prop). Value
5330 is always 1. */
5331
5332
5333 static int
5334 next_element_from_image (it)
5335 struct it *it;
5336 {
5337 it->what = IT_IMAGE;
5338 return 1;
5339 }
5340
5341
5342 /* Fill iterator IT with next display element from a stretch glyph
5343 property. IT->object is the value of the text property. Value is
5344 always 1. */
5345
5346 static int
5347 next_element_from_stretch (it)
5348 struct it *it;
5349 {
5350 it->what = IT_STRETCH;
5351 return 1;
5352 }
5353
5354
5355 /* Load IT with the next display element from current_buffer. Value
5356 is zero if end of buffer reached. IT->stop_charpos is the next
5357 position at which to stop and check for text properties or buffer
5358 end. */
5359
5360 static int
5361 next_element_from_buffer (it)
5362 struct it *it;
5363 {
5364 int success_p = 1;
5365
5366 /* Check this assumption, otherwise, we would never enter the
5367 if-statement, below. */
5368 xassert (IT_CHARPOS (*it) >= BEGV
5369 && IT_CHARPOS (*it) <= it->stop_charpos);
5370
5371 if (IT_CHARPOS (*it) >= it->stop_charpos)
5372 {
5373 if (IT_CHARPOS (*it) >= it->end_charpos)
5374 {
5375 int overlay_strings_follow_p;
5376
5377 /* End of the game, except when overlay strings follow that
5378 haven't been returned yet. */
5379 if (it->overlay_strings_at_end_processed_p)
5380 overlay_strings_follow_p = 0;
5381 else
5382 {
5383 it->overlay_strings_at_end_processed_p = 1;
5384 overlay_strings_follow_p = get_overlay_strings (it, 0);
5385 }
5386
5387 if (overlay_strings_follow_p)
5388 success_p = get_next_display_element (it);
5389 else
5390 {
5391 it->what = IT_EOB;
5392 it->position = it->current.pos;
5393 success_p = 0;
5394 }
5395 }
5396 else
5397 {
5398 handle_stop (it);
5399 return get_next_display_element (it);
5400 }
5401 }
5402 else
5403 {
5404 /* No face changes, overlays etc. in sight, so just return a
5405 character from current_buffer. */
5406 unsigned char *p;
5407
5408 /* Maybe run the redisplay end trigger hook. Performance note:
5409 This doesn't seem to cost measurable time. */
5410 if (it->redisplay_end_trigger_charpos
5411 && it->glyph_row
5412 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5413 run_redisplay_end_trigger_hook (it);
5414
5415 /* Get the next character, maybe multibyte. */
5416 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5417 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5418 {
5419 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5420 - IT_BYTEPOS (*it));
5421 it->c = string_char_and_length (p, maxlen, &it->len);
5422 }
5423 else
5424 it->c = *p, it->len = 1;
5425
5426 /* Record what we have and where it came from. */
5427 it->what = IT_CHARACTER;;
5428 it->object = it->w->buffer;
5429 it->position = it->current.pos;
5430
5431 /* Normally we return the character found above, except when we
5432 really want to return an ellipsis for selective display. */
5433 if (it->selective)
5434 {
5435 if (it->c == '\n')
5436 {
5437 /* A value of selective > 0 means hide lines indented more
5438 than that number of columns. */
5439 if (it->selective > 0
5440 && IT_CHARPOS (*it) + 1 < ZV
5441 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5442 IT_BYTEPOS (*it) + 1,
5443 (double) it->selective)) /* iftc */
5444 {
5445 success_p = next_element_from_ellipsis (it);
5446 it->dpvec_char_len = -1;
5447 }
5448 }
5449 else if (it->c == '\r' && it->selective == -1)
5450 {
5451 /* A value of selective == -1 means that everything from the
5452 CR to the end of the line is invisible, with maybe an
5453 ellipsis displayed for it. */
5454 success_p = next_element_from_ellipsis (it);
5455 it->dpvec_char_len = -1;
5456 }
5457 }
5458 }
5459
5460 /* Value is zero if end of buffer reached. */
5461 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5462 return success_p;
5463 }
5464
5465
5466 /* Run the redisplay end trigger hook for IT. */
5467
5468 static void
5469 run_redisplay_end_trigger_hook (it)
5470 struct it *it;
5471 {
5472 Lisp_Object args[3];
5473
5474 /* IT->glyph_row should be non-null, i.e. we should be actually
5475 displaying something, or otherwise we should not run the hook. */
5476 xassert (it->glyph_row);
5477
5478 /* Set up hook arguments. */
5479 args[0] = Qredisplay_end_trigger_functions;
5480 args[1] = it->window;
5481 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5482 it->redisplay_end_trigger_charpos = 0;
5483
5484 /* Since we are *trying* to run these functions, don't try to run
5485 them again, even if they get an error. */
5486 it->w->redisplay_end_trigger = Qnil;
5487 Frun_hook_with_args (3, args);
5488
5489 /* Notice if it changed the face of the character we are on. */
5490 handle_face_prop (it);
5491 }
5492
5493
5494 /* Deliver a composition display element. The iterator IT is already
5495 filled with composition information (done in
5496 handle_composition_prop). Value is always 1. */
5497
5498 static int
5499 next_element_from_composition (it)
5500 struct it *it;
5501 {
5502 it->what = IT_COMPOSITION;
5503 it->position = (STRINGP (it->string)
5504 ? it->current.string_pos
5505 : it->current.pos);
5506 return 1;
5507 }
5508
5509
5510 \f
5511 /***********************************************************************
5512 Moving an iterator without producing glyphs
5513 ***********************************************************************/
5514
5515 /* Move iterator IT to a specified buffer or X position within one
5516 line on the display without producing glyphs.
5517
5518 OP should be a bit mask including some or all of these bits:
5519 MOVE_TO_X: Stop on reaching x-position TO_X.
5520 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5521 Regardless of OP's value, stop in reaching the end of the display line.
5522
5523 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5524 This means, in particular, that TO_X includes window's horizontal
5525 scroll amount.
5526
5527 The return value has several possible values that
5528 say what condition caused the scan to stop:
5529
5530 MOVE_POS_MATCH_OR_ZV
5531 - when TO_POS or ZV was reached.
5532
5533 MOVE_X_REACHED
5534 -when TO_X was reached before TO_POS or ZV were reached.
5535
5536 MOVE_LINE_CONTINUED
5537 - when we reached the end of the display area and the line must
5538 be continued.
5539
5540 MOVE_LINE_TRUNCATED
5541 - when we reached the end of the display area and the line is
5542 truncated.
5543
5544 MOVE_NEWLINE_OR_CR
5545 - when we stopped at a line end, i.e. a newline or a CR and selective
5546 display is on. */
5547
5548 static enum move_it_result
5549 move_it_in_display_line_to (it, to_charpos, to_x, op)
5550 struct it *it;
5551 int to_charpos, to_x, op;
5552 {
5553 enum move_it_result result = MOVE_UNDEFINED;
5554 struct glyph_row *saved_glyph_row;
5555
5556 /* Don't produce glyphs in produce_glyphs. */
5557 saved_glyph_row = it->glyph_row;
5558 it->glyph_row = NULL;
5559
5560 while (1)
5561 {
5562 int x, i, ascent = 0, descent = 0;
5563
5564 /* Stop when ZV or TO_CHARPOS reached. */
5565 if (!get_next_display_element (it)
5566 || ((op & MOVE_TO_POS) != 0
5567 && BUFFERP (it->object)
5568 && IT_CHARPOS (*it) >= to_charpos))
5569 {
5570 result = MOVE_POS_MATCH_OR_ZV;
5571 break;
5572 }
5573
5574 /* The call to produce_glyphs will get the metrics of the
5575 display element IT is loaded with. We record in x the
5576 x-position before this display element in case it does not
5577 fit on the line. */
5578 x = it->current_x;
5579
5580 /* Remember the line height so far in case the next element doesn't
5581 fit on the line. */
5582 if (!it->truncate_lines_p)
5583 {
5584 ascent = it->max_ascent;
5585 descent = it->max_descent;
5586 }
5587
5588 PRODUCE_GLYPHS (it);
5589
5590 if (it->area != TEXT_AREA)
5591 {
5592 set_iterator_to_next (it, 1);
5593 continue;
5594 }
5595
5596 /* The number of glyphs we get back in IT->nglyphs will normally
5597 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5598 character on a terminal frame, or (iii) a line end. For the
5599 second case, IT->nglyphs - 1 padding glyphs will be present
5600 (on X frames, there is only one glyph produced for a
5601 composite character.
5602
5603 The behavior implemented below means, for continuation lines,
5604 that as many spaces of a TAB as fit on the current line are
5605 displayed there. For terminal frames, as many glyphs of a
5606 multi-glyph character are displayed in the current line, too.
5607 This is what the old redisplay code did, and we keep it that
5608 way. Under X, the whole shape of a complex character must
5609 fit on the line or it will be completely displayed in the
5610 next line.
5611
5612 Note that both for tabs and padding glyphs, all glyphs have
5613 the same width. */
5614 if (it->nglyphs)
5615 {
5616 /* More than one glyph or glyph doesn't fit on line. All
5617 glyphs have the same width. */
5618 int single_glyph_width = it->pixel_width / it->nglyphs;
5619 int new_x;
5620
5621 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5622 {
5623 new_x = x + single_glyph_width;
5624
5625 /* We want to leave anything reaching TO_X to the caller. */
5626 if ((op & MOVE_TO_X) && new_x > to_x)
5627 {
5628 it->current_x = x;
5629 result = MOVE_X_REACHED;
5630 break;
5631 }
5632 else if (/* Lines are continued. */
5633 !it->truncate_lines_p
5634 && (/* And glyph doesn't fit on the line. */
5635 new_x > it->last_visible_x
5636 /* Or it fits exactly and we're on a window
5637 system frame. */
5638 || (new_x == it->last_visible_x
5639 && FRAME_WINDOW_P (it->f))))
5640 {
5641 if (/* IT->hpos == 0 means the very first glyph
5642 doesn't fit on the line, e.g. a wide image. */
5643 it->hpos == 0
5644 || (new_x == it->last_visible_x
5645 && FRAME_WINDOW_P (it->f)))
5646 {
5647 ++it->hpos;
5648 it->current_x = new_x;
5649 if (i == it->nglyphs - 1)
5650 {
5651 set_iterator_to_next (it, 1);
5652 #ifdef HAVE_WINDOW_SYSTEM
5653 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5654 {
5655 if (!get_next_display_element (it))
5656 {
5657 result = MOVE_POS_MATCH_OR_ZV;
5658 break;
5659 }
5660 if (ITERATOR_AT_END_OF_LINE_P (it))
5661 {
5662 result = MOVE_NEWLINE_OR_CR;
5663 break;
5664 }
5665 }
5666 #endif /* HAVE_WINDOW_SYSTEM */
5667 }
5668 }
5669 else
5670 {
5671 it->current_x = x;
5672 it->max_ascent = ascent;
5673 it->max_descent = descent;
5674 }
5675
5676 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5677 IT_CHARPOS (*it)));
5678 result = MOVE_LINE_CONTINUED;
5679 break;
5680 }
5681 else if (new_x > it->first_visible_x)
5682 {
5683 /* Glyph is visible. Increment number of glyphs that
5684 would be displayed. */
5685 ++it->hpos;
5686 }
5687 else
5688 {
5689 /* Glyph is completely off the left margin of the display
5690 area. Nothing to do. */
5691 }
5692 }
5693
5694 if (result != MOVE_UNDEFINED)
5695 break;
5696 }
5697 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
5698 {
5699 /* Stop when TO_X specified and reached. This check is
5700 necessary here because of lines consisting of a line end,
5701 only. The line end will not produce any glyphs and we
5702 would never get MOVE_X_REACHED. */
5703 xassert (it->nglyphs == 0);
5704 result = MOVE_X_REACHED;
5705 break;
5706 }
5707
5708 /* Is this a line end? If yes, we're done. */
5709 if (ITERATOR_AT_END_OF_LINE_P (it))
5710 {
5711 result = MOVE_NEWLINE_OR_CR;
5712 break;
5713 }
5714
5715 /* The current display element has been consumed. Advance
5716 to the next. */
5717 set_iterator_to_next (it, 1);
5718
5719 /* Stop if lines are truncated and IT's current x-position is
5720 past the right edge of the window now. */
5721 if (it->truncate_lines_p
5722 && it->current_x >= it->last_visible_x)
5723 {
5724 #ifdef HAVE_WINDOW_SYSTEM
5725 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5726 {
5727 if (!get_next_display_element (it))
5728 {
5729 result = MOVE_POS_MATCH_OR_ZV;
5730 break;
5731 }
5732 if (ITERATOR_AT_END_OF_LINE_P (it))
5733 {
5734 result = MOVE_NEWLINE_OR_CR;
5735 break;
5736 }
5737 }
5738 #endif /* HAVE_WINDOW_SYSTEM */
5739 result = MOVE_LINE_TRUNCATED;
5740 break;
5741 }
5742 }
5743
5744 /* Restore the iterator settings altered at the beginning of this
5745 function. */
5746 it->glyph_row = saved_glyph_row;
5747 return result;
5748 }
5749
5750
5751 /* Move IT forward until it satisfies one or more of the criteria in
5752 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
5753
5754 OP is a bit-mask that specifies where to stop, and in particular,
5755 which of those four position arguments makes a difference. See the
5756 description of enum move_operation_enum.
5757
5758 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
5759 screen line, this function will set IT to the next position >
5760 TO_CHARPOS. */
5761
5762 void
5763 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
5764 struct it *it;
5765 int to_charpos, to_x, to_y, to_vpos;
5766 int op;
5767 {
5768 enum move_it_result skip, skip2 = MOVE_X_REACHED;
5769 int line_height;
5770 int reached = 0;
5771
5772 for (;;)
5773 {
5774 if (op & MOVE_TO_VPOS)
5775 {
5776 /* If no TO_CHARPOS and no TO_X specified, stop at the
5777 start of the line TO_VPOS. */
5778 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
5779 {
5780 if (it->vpos == to_vpos)
5781 {
5782 reached = 1;
5783 break;
5784 }
5785 else
5786 skip = move_it_in_display_line_to (it, -1, -1, 0);
5787 }
5788 else
5789 {
5790 /* TO_VPOS >= 0 means stop at TO_X in the line at
5791 TO_VPOS, or at TO_POS, whichever comes first. */
5792 if (it->vpos == to_vpos)
5793 {
5794 reached = 2;
5795 break;
5796 }
5797
5798 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
5799
5800 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
5801 {
5802 reached = 3;
5803 break;
5804 }
5805 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
5806 {
5807 /* We have reached TO_X but not in the line we want. */
5808 skip = move_it_in_display_line_to (it, to_charpos,
5809 -1, MOVE_TO_POS);
5810 if (skip == MOVE_POS_MATCH_OR_ZV)
5811 {
5812 reached = 4;
5813 break;
5814 }
5815 }
5816 }
5817 }
5818 else if (op & MOVE_TO_Y)
5819 {
5820 struct it it_backup;
5821
5822 /* TO_Y specified means stop at TO_X in the line containing
5823 TO_Y---or at TO_CHARPOS if this is reached first. The
5824 problem is that we can't really tell whether the line
5825 contains TO_Y before we have completely scanned it, and
5826 this may skip past TO_X. What we do is to first scan to
5827 TO_X.
5828
5829 If TO_X is not specified, use a TO_X of zero. The reason
5830 is to make the outcome of this function more predictable.
5831 If we didn't use TO_X == 0, we would stop at the end of
5832 the line which is probably not what a caller would expect
5833 to happen. */
5834 skip = move_it_in_display_line_to (it, to_charpos,
5835 ((op & MOVE_TO_X)
5836 ? to_x : 0),
5837 (MOVE_TO_X
5838 | (op & MOVE_TO_POS)));
5839
5840 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
5841 if (skip == MOVE_POS_MATCH_OR_ZV)
5842 {
5843 reached = 5;
5844 break;
5845 }
5846
5847 /* If TO_X was reached, we would like to know whether TO_Y
5848 is in the line. This can only be said if we know the
5849 total line height which requires us to scan the rest of
5850 the line. */
5851 if (skip == MOVE_X_REACHED)
5852 {
5853 it_backup = *it;
5854 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
5855 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
5856 op & MOVE_TO_POS);
5857 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
5858 }
5859
5860 /* Now, decide whether TO_Y is in this line. */
5861 line_height = it->max_ascent + it->max_descent;
5862 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
5863
5864 if (to_y >= it->current_y
5865 && to_y < it->current_y + line_height)
5866 {
5867 if (skip == MOVE_X_REACHED)
5868 /* If TO_Y is in this line and TO_X was reached above,
5869 we scanned too far. We have to restore IT's settings
5870 to the ones before skipping. */
5871 *it = it_backup;
5872 reached = 6;
5873 }
5874 else if (skip == MOVE_X_REACHED)
5875 {
5876 skip = skip2;
5877 if (skip == MOVE_POS_MATCH_OR_ZV)
5878 reached = 7;
5879 }
5880
5881 if (reached)
5882 break;
5883 }
5884 else
5885 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
5886
5887 switch (skip)
5888 {
5889 case MOVE_POS_MATCH_OR_ZV:
5890 reached = 8;
5891 goto out;
5892
5893 case MOVE_NEWLINE_OR_CR:
5894 set_iterator_to_next (it, 1);
5895 it->continuation_lines_width = 0;
5896 break;
5897
5898 case MOVE_LINE_TRUNCATED:
5899 it->continuation_lines_width = 0;
5900 reseat_at_next_visible_line_start (it, 0);
5901 if ((op & MOVE_TO_POS) != 0
5902 && IT_CHARPOS (*it) > to_charpos)
5903 {
5904 reached = 9;
5905 goto out;
5906 }
5907 break;
5908
5909 case MOVE_LINE_CONTINUED:
5910 it->continuation_lines_width += it->current_x;
5911 break;
5912
5913 default:
5914 abort ();
5915 }
5916
5917 /* Reset/increment for the next run. */
5918 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
5919 it->current_x = it->hpos = 0;
5920 it->current_y += it->max_ascent + it->max_descent;
5921 ++it->vpos;
5922 last_height = it->max_ascent + it->max_descent;
5923 last_max_ascent = it->max_ascent;
5924 it->max_ascent = it->max_descent = 0;
5925 }
5926
5927 out:
5928
5929 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
5930 }
5931
5932
5933 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
5934
5935 If DY > 0, move IT backward at least that many pixels. DY = 0
5936 means move IT backward to the preceding line start or BEGV. This
5937 function may move over more than DY pixels if IT->current_y - DY
5938 ends up in the middle of a line; in this case IT->current_y will be
5939 set to the top of the line moved to. */
5940
5941 void
5942 move_it_vertically_backward (it, dy)
5943 struct it *it;
5944 int dy;
5945 {
5946 int nlines, h;
5947 struct it it2, it3;
5948 int start_pos = IT_CHARPOS (*it);
5949
5950 xassert (dy >= 0);
5951
5952 /* Estimate how many newlines we must move back. */
5953 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
5954
5955 /* Set the iterator's position that many lines back. */
5956 while (nlines-- && IT_CHARPOS (*it) > BEGV)
5957 back_to_previous_visible_line_start (it);
5958
5959 /* Reseat the iterator here. When moving backward, we don't want
5960 reseat to skip forward over invisible text, set up the iterator
5961 to deliver from overlay strings at the new position etc. So,
5962 use reseat_1 here. */
5963 reseat_1 (it, it->current.pos, 1);
5964
5965 /* We are now surely at a line start. */
5966 it->current_x = it->hpos = 0;
5967 it->continuation_lines_width = 0;
5968
5969 /* Move forward and see what y-distance we moved. First move to the
5970 start of the next line so that we get its height. We need this
5971 height to be able to tell whether we reached the specified
5972 y-distance. */
5973 it2 = *it;
5974 it2.max_ascent = it2.max_descent = 0;
5975 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
5976 MOVE_TO_POS | MOVE_TO_VPOS);
5977 xassert (IT_CHARPOS (*it) >= BEGV);
5978 it3 = it2;
5979
5980 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
5981 xassert (IT_CHARPOS (*it) >= BEGV);
5982 /* H is the actual vertical distance from the position in *IT
5983 and the starting position. */
5984 h = it2.current_y - it->current_y;
5985 /* NLINES is the distance in number of lines. */
5986 nlines = it2.vpos - it->vpos;
5987
5988 /* Correct IT's y and vpos position
5989 so that they are relative to the starting point. */
5990 it->vpos -= nlines;
5991 it->current_y -= h;
5992
5993 if (dy == 0)
5994 {
5995 /* DY == 0 means move to the start of the screen line. The
5996 value of nlines is > 0 if continuation lines were involved. */
5997 if (nlines > 0)
5998 move_it_by_lines (it, nlines, 1);
5999 xassert (IT_CHARPOS (*it) <= start_pos);
6000 }
6001 else
6002 {
6003 /* The y-position we try to reach, relative to *IT.
6004 Note that H has been subtracted in front of the if-statement. */
6005 int target_y = it->current_y + h - dy;
6006 int y0 = it3.current_y;
6007 int y1 = line_bottom_y (&it3);
6008 int line_height = y1 - y0;
6009
6010 /* If we did not reach target_y, try to move further backward if
6011 we can. If we moved too far backward, try to move forward. */
6012 if (target_y < it->current_y
6013 /* This is heuristic. In a window that's 3 lines high, with
6014 a line height of 13 pixels each, recentering with point
6015 on the bottom line will try to move -39/2 = 19 pixels
6016 backward. Try to avoid moving into the first line. */
6017 && it->current_y - target_y > line_height / 3 * 2
6018 && IT_CHARPOS (*it) > BEGV)
6019 {
6020 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6021 target_y - it->current_y));
6022 move_it_vertically (it, target_y - it->current_y);
6023 xassert (IT_CHARPOS (*it) >= BEGV);
6024 }
6025 else if (target_y >= it->current_y + line_height
6026 && IT_CHARPOS (*it) < ZV)
6027 {
6028 /* Should move forward by at least one line, maybe more.
6029
6030 Note: Calling move_it_by_lines can be expensive on
6031 terminal frames, where compute_motion is used (via
6032 vmotion) to do the job, when there are very long lines
6033 and truncate-lines is nil. That's the reason for
6034 treating terminal frames specially here. */
6035
6036 if (!FRAME_WINDOW_P (it->f))
6037 move_it_vertically (it, target_y - (it->current_y + line_height));
6038 else
6039 {
6040 do
6041 {
6042 move_it_by_lines (it, 1, 1);
6043 }
6044 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6045 }
6046
6047 xassert (IT_CHARPOS (*it) >= BEGV);
6048 }
6049 }
6050 }
6051
6052
6053 /* Move IT by a specified amount of pixel lines DY. DY negative means
6054 move backwards. DY = 0 means move to start of screen line. At the
6055 end, IT will be on the start of a screen line. */
6056
6057 void
6058 move_it_vertically (it, dy)
6059 struct it *it;
6060 int dy;
6061 {
6062 if (dy <= 0)
6063 move_it_vertically_backward (it, -dy);
6064 else if (dy > 0)
6065 {
6066 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6067 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6068 MOVE_TO_POS | MOVE_TO_Y);
6069 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6070
6071 /* If buffer ends in ZV without a newline, move to the start of
6072 the line to satisfy the post-condition. */
6073 if (IT_CHARPOS (*it) == ZV
6074 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6075 move_it_by_lines (it, 0, 0);
6076 }
6077 }
6078
6079
6080 /* Move iterator IT past the end of the text line it is in. */
6081
6082 void
6083 move_it_past_eol (it)
6084 struct it *it;
6085 {
6086 enum move_it_result rc;
6087
6088 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6089 if (rc == MOVE_NEWLINE_OR_CR)
6090 set_iterator_to_next (it, 0);
6091 }
6092
6093
6094 #if 0 /* Currently not used. */
6095
6096 /* Return non-zero if some text between buffer positions START_CHARPOS
6097 and END_CHARPOS is invisible. IT->window is the window for text
6098 property lookup. */
6099
6100 static int
6101 invisible_text_between_p (it, start_charpos, end_charpos)
6102 struct it *it;
6103 int start_charpos, end_charpos;
6104 {
6105 Lisp_Object prop, limit;
6106 int invisible_found_p;
6107
6108 xassert (it != NULL && start_charpos <= end_charpos);
6109
6110 /* Is text at START invisible? */
6111 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6112 it->window);
6113 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6114 invisible_found_p = 1;
6115 else
6116 {
6117 limit = Fnext_single_char_property_change (make_number (start_charpos),
6118 Qinvisible, Qnil,
6119 make_number (end_charpos));
6120 invisible_found_p = XFASTINT (limit) < end_charpos;
6121 }
6122
6123 return invisible_found_p;
6124 }
6125
6126 #endif /* 0 */
6127
6128
6129 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6130 negative means move up. DVPOS == 0 means move to the start of the
6131 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6132 NEED_Y_P is zero, IT->current_y will be left unchanged.
6133
6134 Further optimization ideas: If we would know that IT->f doesn't use
6135 a face with proportional font, we could be faster for
6136 truncate-lines nil. */
6137
6138 void
6139 move_it_by_lines (it, dvpos, need_y_p)
6140 struct it *it;
6141 int dvpos, need_y_p;
6142 {
6143 struct position pos;
6144
6145 if (!FRAME_WINDOW_P (it->f))
6146 {
6147 struct text_pos textpos;
6148
6149 /* We can use vmotion on frames without proportional fonts. */
6150 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6151 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6152 reseat (it, textpos, 1);
6153 it->vpos += pos.vpos;
6154 it->current_y += pos.vpos;
6155 }
6156 else if (dvpos == 0)
6157 {
6158 /* DVPOS == 0 means move to the start of the screen line. */
6159 move_it_vertically_backward (it, 0);
6160 xassert (it->current_x == 0 && it->hpos == 0);
6161 }
6162 else if (dvpos > 0)
6163 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6164 else
6165 {
6166 struct it it2;
6167 int start_charpos, i;
6168
6169 /* Start at the beginning of the screen line containing IT's
6170 position. */
6171 move_it_vertically_backward (it, 0);
6172
6173 /* Go back -DVPOS visible lines and reseat the iterator there. */
6174 start_charpos = IT_CHARPOS (*it);
6175 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6176 back_to_previous_visible_line_start (it);
6177 reseat (it, it->current.pos, 1);
6178 it->current_x = it->hpos = 0;
6179
6180 /* Above call may have moved too far if continuation lines
6181 are involved. Scan forward and see if it did. */
6182 it2 = *it;
6183 it2.vpos = it2.current_y = 0;
6184 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6185 it->vpos -= it2.vpos;
6186 it->current_y -= it2.current_y;
6187 it->current_x = it->hpos = 0;
6188
6189 /* If we moved too far, move IT some lines forward. */
6190 if (it2.vpos > -dvpos)
6191 {
6192 int delta = it2.vpos + dvpos;
6193 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6194 }
6195 }
6196 }
6197
6198 /* Return 1 if IT points into the middle of a display vector. */
6199
6200 int
6201 in_display_vector_p (it)
6202 struct it *it;
6203 {
6204 return (it->method == next_element_from_display_vector
6205 && it->current.dpvec_index > 0
6206 && it->dpvec + it->current.dpvec_index != it->dpend);
6207 }
6208
6209 \f
6210 /***********************************************************************
6211 Messages
6212 ***********************************************************************/
6213
6214
6215 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6216 to *Messages*. */
6217
6218 void
6219 add_to_log (format, arg1, arg2)
6220 char *format;
6221 Lisp_Object arg1, arg2;
6222 {
6223 Lisp_Object args[3];
6224 Lisp_Object msg, fmt;
6225 char *buffer;
6226 int len;
6227 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6228
6229 /* Do nothing if called asynchronously. Inserting text into
6230 a buffer may call after-change-functions and alike and
6231 that would means running Lisp asynchronously. */
6232 if (handling_signal)
6233 return;
6234
6235 fmt = msg = Qnil;
6236 GCPRO4 (fmt, msg, arg1, arg2);
6237
6238 args[0] = fmt = build_string (format);
6239 args[1] = arg1;
6240 args[2] = arg2;
6241 msg = Fformat (3, args);
6242
6243 len = SBYTES (msg) + 1;
6244 buffer = (char *) alloca (len);
6245 bcopy (SDATA (msg), buffer, len);
6246
6247 message_dolog (buffer, len - 1, 1, 0);
6248 UNGCPRO;
6249 }
6250
6251
6252 /* Output a newline in the *Messages* buffer if "needs" one. */
6253
6254 void
6255 message_log_maybe_newline ()
6256 {
6257 if (message_log_need_newline)
6258 message_dolog ("", 0, 1, 0);
6259 }
6260
6261
6262 /* Add a string M of length NBYTES to the message log, optionally
6263 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6264 nonzero, means interpret the contents of M as multibyte. This
6265 function calls low-level routines in order to bypass text property
6266 hooks, etc. which might not be safe to run. */
6267
6268 void
6269 message_dolog (m, nbytes, nlflag, multibyte)
6270 const char *m;
6271 int nbytes, nlflag, multibyte;
6272 {
6273 if (!NILP (Vmemory_full))
6274 return;
6275
6276 if (!NILP (Vmessage_log_max))
6277 {
6278 struct buffer *oldbuf;
6279 Lisp_Object oldpoint, oldbegv, oldzv;
6280 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6281 int point_at_end = 0;
6282 int zv_at_end = 0;
6283 Lisp_Object old_deactivate_mark, tem;
6284 struct gcpro gcpro1;
6285
6286 old_deactivate_mark = Vdeactivate_mark;
6287 oldbuf = current_buffer;
6288 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6289 current_buffer->undo_list = Qt;
6290
6291 oldpoint = message_dolog_marker1;
6292 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6293 oldbegv = message_dolog_marker2;
6294 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6295 oldzv = message_dolog_marker3;
6296 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6297 GCPRO1 (old_deactivate_mark);
6298
6299 if (PT == Z)
6300 point_at_end = 1;
6301 if (ZV == Z)
6302 zv_at_end = 1;
6303
6304 BEGV = BEG;
6305 BEGV_BYTE = BEG_BYTE;
6306 ZV = Z;
6307 ZV_BYTE = Z_BYTE;
6308 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6309
6310 /* Insert the string--maybe converting multibyte to single byte
6311 or vice versa, so that all the text fits the buffer. */
6312 if (multibyte
6313 && NILP (current_buffer->enable_multibyte_characters))
6314 {
6315 int i, c, char_bytes;
6316 unsigned char work[1];
6317
6318 /* Convert a multibyte string to single-byte
6319 for the *Message* buffer. */
6320 for (i = 0; i < nbytes; i += char_bytes)
6321 {
6322 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6323 work[0] = (SINGLE_BYTE_CHAR_P (c)
6324 ? c
6325 : multibyte_char_to_unibyte (c, Qnil));
6326 insert_1_both (work, 1, 1, 1, 0, 0);
6327 }
6328 }
6329 else if (! multibyte
6330 && ! NILP (current_buffer->enable_multibyte_characters))
6331 {
6332 int i, c, char_bytes;
6333 unsigned char *msg = (unsigned char *) m;
6334 unsigned char str[MAX_MULTIBYTE_LENGTH];
6335 /* Convert a single-byte string to multibyte
6336 for the *Message* buffer. */
6337 for (i = 0; i < nbytes; i++)
6338 {
6339 c = unibyte_char_to_multibyte (msg[i]);
6340 char_bytes = CHAR_STRING (c, str);
6341 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6342 }
6343 }
6344 else if (nbytes)
6345 insert_1 (m, nbytes, 1, 0, 0);
6346
6347 if (nlflag)
6348 {
6349 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6350 insert_1 ("\n", 1, 1, 0, 0);
6351
6352 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6353 this_bol = PT;
6354 this_bol_byte = PT_BYTE;
6355
6356 /* See if this line duplicates the previous one.
6357 If so, combine duplicates. */
6358 if (this_bol > BEG)
6359 {
6360 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6361 prev_bol = PT;
6362 prev_bol_byte = PT_BYTE;
6363
6364 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6365 this_bol, this_bol_byte);
6366 if (dup)
6367 {
6368 del_range_both (prev_bol, prev_bol_byte,
6369 this_bol, this_bol_byte, 0);
6370 if (dup > 1)
6371 {
6372 char dupstr[40];
6373 int duplen;
6374
6375 /* If you change this format, don't forget to also
6376 change message_log_check_duplicate. */
6377 sprintf (dupstr, " [%d times]", dup);
6378 duplen = strlen (dupstr);
6379 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6380 insert_1 (dupstr, duplen, 1, 0, 1);
6381 }
6382 }
6383 }
6384
6385 /* If we have more than the desired maximum number of lines
6386 in the *Messages* buffer now, delete the oldest ones.
6387 This is safe because we don't have undo in this buffer. */
6388
6389 if (NATNUMP (Vmessage_log_max))
6390 {
6391 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6392 -XFASTINT (Vmessage_log_max) - 1, 0);
6393 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6394 }
6395 }
6396 BEGV = XMARKER (oldbegv)->charpos;
6397 BEGV_BYTE = marker_byte_position (oldbegv);
6398
6399 if (zv_at_end)
6400 {
6401 ZV = Z;
6402 ZV_BYTE = Z_BYTE;
6403 }
6404 else
6405 {
6406 ZV = XMARKER (oldzv)->charpos;
6407 ZV_BYTE = marker_byte_position (oldzv);
6408 }
6409
6410 if (point_at_end)
6411 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6412 else
6413 /* We can't do Fgoto_char (oldpoint) because it will run some
6414 Lisp code. */
6415 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6416 XMARKER (oldpoint)->bytepos);
6417
6418 UNGCPRO;
6419 unchain_marker (XMARKER (oldpoint));
6420 unchain_marker (XMARKER (oldbegv));
6421 unchain_marker (XMARKER (oldzv));
6422
6423 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6424 set_buffer_internal (oldbuf);
6425 if (NILP (tem))
6426 windows_or_buffers_changed = old_windows_or_buffers_changed;
6427 message_log_need_newline = !nlflag;
6428 Vdeactivate_mark = old_deactivate_mark;
6429 }
6430 }
6431
6432
6433 /* We are at the end of the buffer after just having inserted a newline.
6434 (Note: We depend on the fact we won't be crossing the gap.)
6435 Check to see if the most recent message looks a lot like the previous one.
6436 Return 0 if different, 1 if the new one should just replace it, or a
6437 value N > 1 if we should also append " [N times]". */
6438
6439 static int
6440 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6441 int prev_bol, this_bol;
6442 int prev_bol_byte, this_bol_byte;
6443 {
6444 int i;
6445 int len = Z_BYTE - 1 - this_bol_byte;
6446 int seen_dots = 0;
6447 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6448 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6449
6450 for (i = 0; i < len; i++)
6451 {
6452 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6453 seen_dots = 1;
6454 if (p1[i] != p2[i])
6455 return seen_dots;
6456 }
6457 p1 += len;
6458 if (*p1 == '\n')
6459 return 2;
6460 if (*p1++ == ' ' && *p1++ == '[')
6461 {
6462 int n = 0;
6463 while (*p1 >= '0' && *p1 <= '9')
6464 n = n * 10 + *p1++ - '0';
6465 if (strncmp (p1, " times]\n", 8) == 0)
6466 return n+1;
6467 }
6468 return 0;
6469 }
6470
6471
6472 /* Display an echo area message M with a specified length of NBYTES
6473 bytes. The string may include null characters. If M is 0, clear
6474 out any existing message, and let the mini-buffer text show
6475 through.
6476
6477 The buffer M must continue to exist until after the echo area gets
6478 cleared or some other message gets displayed there. This means do
6479 not pass text that is stored in a Lisp string; do not pass text in
6480 a buffer that was alloca'd. */
6481
6482 void
6483 message2 (m, nbytes, multibyte)
6484 const char *m;
6485 int nbytes;
6486 int multibyte;
6487 {
6488 /* First flush out any partial line written with print. */
6489 message_log_maybe_newline ();
6490 if (m)
6491 message_dolog (m, nbytes, 1, multibyte);
6492 message2_nolog (m, nbytes, multibyte);
6493 }
6494
6495
6496 /* The non-logging counterpart of message2. */
6497
6498 void
6499 message2_nolog (m, nbytes, multibyte)
6500 const char *m;
6501 int nbytes, multibyte;
6502 {
6503 struct frame *sf = SELECTED_FRAME ();
6504 message_enable_multibyte = multibyte;
6505
6506 if (noninteractive)
6507 {
6508 if (noninteractive_need_newline)
6509 putc ('\n', stderr);
6510 noninteractive_need_newline = 0;
6511 if (m)
6512 fwrite (m, nbytes, 1, stderr);
6513 if (cursor_in_echo_area == 0)
6514 fprintf (stderr, "\n");
6515 fflush (stderr);
6516 }
6517 /* A null message buffer means that the frame hasn't really been
6518 initialized yet. Error messages get reported properly by
6519 cmd_error, so this must be just an informative message; toss it. */
6520 else if (INTERACTIVE
6521 && sf->glyphs_initialized_p
6522 && FRAME_MESSAGE_BUF (sf))
6523 {
6524 Lisp_Object mini_window;
6525 struct frame *f;
6526
6527 /* Get the frame containing the mini-buffer
6528 that the selected frame is using. */
6529 mini_window = FRAME_MINIBUF_WINDOW (sf);
6530 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6531
6532 FRAME_SAMPLE_VISIBILITY (f);
6533 if (FRAME_VISIBLE_P (sf)
6534 && ! FRAME_VISIBLE_P (f))
6535 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6536
6537 if (m)
6538 {
6539 set_message (m, Qnil, nbytes, multibyte);
6540 if (minibuffer_auto_raise)
6541 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6542 }
6543 else
6544 clear_message (1, 1);
6545
6546 do_pending_window_change (0);
6547 echo_area_display (1);
6548 do_pending_window_change (0);
6549 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6550 (*frame_up_to_date_hook) (f);
6551 }
6552 }
6553
6554
6555 /* Display an echo area message M with a specified length of NBYTES
6556 bytes. The string may include null characters. If M is not a
6557 string, clear out any existing message, and let the mini-buffer
6558 text show through. */
6559
6560 void
6561 message3 (m, nbytes, multibyte)
6562 Lisp_Object m;
6563 int nbytes;
6564 int multibyte;
6565 {
6566 struct gcpro gcpro1;
6567
6568 GCPRO1 (m);
6569
6570 /* First flush out any partial line written with print. */
6571 message_log_maybe_newline ();
6572 if (STRINGP (m))
6573 message_dolog (SDATA (m), nbytes, 1, multibyte);
6574 message3_nolog (m, nbytes, multibyte);
6575
6576 UNGCPRO;
6577 }
6578
6579
6580 /* The non-logging version of message3. */
6581
6582 void
6583 message3_nolog (m, nbytes, multibyte)
6584 Lisp_Object m;
6585 int nbytes, multibyte;
6586 {
6587 struct frame *sf = SELECTED_FRAME ();
6588 message_enable_multibyte = multibyte;
6589
6590 if (noninteractive)
6591 {
6592 if (noninteractive_need_newline)
6593 putc ('\n', stderr);
6594 noninteractive_need_newline = 0;
6595 if (STRINGP (m))
6596 fwrite (SDATA (m), nbytes, 1, stderr);
6597 if (cursor_in_echo_area == 0)
6598 fprintf (stderr, "\n");
6599 fflush (stderr);
6600 }
6601 /* A null message buffer means that the frame hasn't really been
6602 initialized yet. Error messages get reported properly by
6603 cmd_error, so this must be just an informative message; toss it. */
6604 else if (INTERACTIVE
6605 && sf->glyphs_initialized_p
6606 && FRAME_MESSAGE_BUF (sf))
6607 {
6608 Lisp_Object mini_window;
6609 Lisp_Object frame;
6610 struct frame *f;
6611
6612 /* Get the frame containing the mini-buffer
6613 that the selected frame is using. */
6614 mini_window = FRAME_MINIBUF_WINDOW (sf);
6615 frame = XWINDOW (mini_window)->frame;
6616 f = XFRAME (frame);
6617
6618 FRAME_SAMPLE_VISIBILITY (f);
6619 if (FRAME_VISIBLE_P (sf)
6620 && !FRAME_VISIBLE_P (f))
6621 Fmake_frame_visible (frame);
6622
6623 if (STRINGP (m) && SCHARS (m) > 0)
6624 {
6625 set_message (NULL, m, nbytes, multibyte);
6626 if (minibuffer_auto_raise)
6627 Fraise_frame (frame);
6628 }
6629 else
6630 clear_message (1, 1);
6631
6632 do_pending_window_change (0);
6633 echo_area_display (1);
6634 do_pending_window_change (0);
6635 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6636 (*frame_up_to_date_hook) (f);
6637 }
6638 }
6639
6640
6641 /* Display a null-terminated echo area message M. If M is 0, clear
6642 out any existing message, and let the mini-buffer text show through.
6643
6644 The buffer M must continue to exist until after the echo area gets
6645 cleared or some other message gets displayed there. Do not pass
6646 text that is stored in a Lisp string. Do not pass text in a buffer
6647 that was alloca'd. */
6648
6649 void
6650 message1 (m)
6651 char *m;
6652 {
6653 message2 (m, (m ? strlen (m) : 0), 0);
6654 }
6655
6656
6657 /* The non-logging counterpart of message1. */
6658
6659 void
6660 message1_nolog (m)
6661 char *m;
6662 {
6663 message2_nolog (m, (m ? strlen (m) : 0), 0);
6664 }
6665
6666 /* Display a message M which contains a single %s
6667 which gets replaced with STRING. */
6668
6669 void
6670 message_with_string (m, string, log)
6671 char *m;
6672 Lisp_Object string;
6673 int log;
6674 {
6675 CHECK_STRING (string);
6676
6677 if (noninteractive)
6678 {
6679 if (m)
6680 {
6681 if (noninteractive_need_newline)
6682 putc ('\n', stderr);
6683 noninteractive_need_newline = 0;
6684 fprintf (stderr, m, SDATA (string));
6685 if (cursor_in_echo_area == 0)
6686 fprintf (stderr, "\n");
6687 fflush (stderr);
6688 }
6689 }
6690 else if (INTERACTIVE)
6691 {
6692 /* The frame whose minibuffer we're going to display the message on.
6693 It may be larger than the selected frame, so we need
6694 to use its buffer, not the selected frame's buffer. */
6695 Lisp_Object mini_window;
6696 struct frame *f, *sf = SELECTED_FRAME ();
6697
6698 /* Get the frame containing the minibuffer
6699 that the selected frame is using. */
6700 mini_window = FRAME_MINIBUF_WINDOW (sf);
6701 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6702
6703 /* A null message buffer means that the frame hasn't really been
6704 initialized yet. Error messages get reported properly by
6705 cmd_error, so this must be just an informative message; toss it. */
6706 if (FRAME_MESSAGE_BUF (f))
6707 {
6708 Lisp_Object args[2], message;
6709 struct gcpro gcpro1, gcpro2;
6710
6711 args[0] = build_string (m);
6712 args[1] = message = string;
6713 GCPRO2 (args[0], message);
6714 gcpro1.nvars = 2;
6715
6716 message = Fformat (2, args);
6717
6718 if (log)
6719 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
6720 else
6721 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
6722
6723 UNGCPRO;
6724
6725 /* Print should start at the beginning of the message
6726 buffer next time. */
6727 message_buf_print = 0;
6728 }
6729 }
6730 }
6731
6732
6733 /* Dump an informative message to the minibuf. If M is 0, clear out
6734 any existing message, and let the mini-buffer text show through. */
6735
6736 /* VARARGS 1 */
6737 void
6738 message (m, a1, a2, a3)
6739 char *m;
6740 EMACS_INT a1, a2, a3;
6741 {
6742 if (noninteractive)
6743 {
6744 if (m)
6745 {
6746 if (noninteractive_need_newline)
6747 putc ('\n', stderr);
6748 noninteractive_need_newline = 0;
6749 fprintf (stderr, m, a1, a2, a3);
6750 if (cursor_in_echo_area == 0)
6751 fprintf (stderr, "\n");
6752 fflush (stderr);
6753 }
6754 }
6755 else if (INTERACTIVE)
6756 {
6757 /* The frame whose mini-buffer we're going to display the message
6758 on. It may be larger than the selected frame, so we need to
6759 use its buffer, not the selected frame's buffer. */
6760 Lisp_Object mini_window;
6761 struct frame *f, *sf = SELECTED_FRAME ();
6762
6763 /* Get the frame containing the mini-buffer
6764 that the selected frame is using. */
6765 mini_window = FRAME_MINIBUF_WINDOW (sf);
6766 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6767
6768 /* A null message buffer means that the frame hasn't really been
6769 initialized yet. Error messages get reported properly by
6770 cmd_error, so this must be just an informative message; toss
6771 it. */
6772 if (FRAME_MESSAGE_BUF (f))
6773 {
6774 if (m)
6775 {
6776 int len;
6777 #ifdef NO_ARG_ARRAY
6778 char *a[3];
6779 a[0] = (char *) a1;
6780 a[1] = (char *) a2;
6781 a[2] = (char *) a3;
6782
6783 len = doprnt (FRAME_MESSAGE_BUF (f),
6784 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
6785 #else
6786 len = doprnt (FRAME_MESSAGE_BUF (f),
6787 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
6788 (char **) &a1);
6789 #endif /* NO_ARG_ARRAY */
6790
6791 message2 (FRAME_MESSAGE_BUF (f), len, 0);
6792 }
6793 else
6794 message1 (0);
6795
6796 /* Print should start at the beginning of the message
6797 buffer next time. */
6798 message_buf_print = 0;
6799 }
6800 }
6801 }
6802
6803
6804 /* The non-logging version of message. */
6805
6806 void
6807 message_nolog (m, a1, a2, a3)
6808 char *m;
6809 EMACS_INT a1, a2, a3;
6810 {
6811 Lisp_Object old_log_max;
6812 old_log_max = Vmessage_log_max;
6813 Vmessage_log_max = Qnil;
6814 message (m, a1, a2, a3);
6815 Vmessage_log_max = old_log_max;
6816 }
6817
6818
6819 /* Display the current message in the current mini-buffer. This is
6820 only called from error handlers in process.c, and is not time
6821 critical. */
6822
6823 void
6824 update_echo_area ()
6825 {
6826 if (!NILP (echo_area_buffer[0]))
6827 {
6828 Lisp_Object string;
6829 string = Fcurrent_message ();
6830 message3 (string, SBYTES (string),
6831 !NILP (current_buffer->enable_multibyte_characters));
6832 }
6833 }
6834
6835
6836 /* Make sure echo area buffers in `echo_buffers' are live.
6837 If they aren't, make new ones. */
6838
6839 static void
6840 ensure_echo_area_buffers ()
6841 {
6842 int i;
6843
6844 for (i = 0; i < 2; ++i)
6845 if (!BUFFERP (echo_buffer[i])
6846 || NILP (XBUFFER (echo_buffer[i])->name))
6847 {
6848 char name[30];
6849 Lisp_Object old_buffer;
6850 int j;
6851
6852 old_buffer = echo_buffer[i];
6853 sprintf (name, " *Echo Area %d*", i);
6854 echo_buffer[i] = Fget_buffer_create (build_string (name));
6855 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
6856
6857 for (j = 0; j < 2; ++j)
6858 if (EQ (old_buffer, echo_area_buffer[j]))
6859 echo_area_buffer[j] = echo_buffer[i];
6860 }
6861 }
6862
6863
6864 /* Call FN with args A1..A4 with either the current or last displayed
6865 echo_area_buffer as current buffer.
6866
6867 WHICH zero means use the current message buffer
6868 echo_area_buffer[0]. If that is nil, choose a suitable buffer
6869 from echo_buffer[] and clear it.
6870
6871 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
6872 suitable buffer from echo_buffer[] and clear it.
6873
6874 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
6875 that the current message becomes the last displayed one, make
6876 choose a suitable buffer for echo_area_buffer[0], and clear it.
6877
6878 Value is what FN returns. */
6879
6880 static int
6881 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
6882 struct window *w;
6883 int which;
6884 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
6885 EMACS_INT a1;
6886 Lisp_Object a2;
6887 EMACS_INT a3, a4;
6888 {
6889 Lisp_Object buffer;
6890 int this_one, the_other, clear_buffer_p, rc;
6891 int count = SPECPDL_INDEX ();
6892
6893 /* If buffers aren't live, make new ones. */
6894 ensure_echo_area_buffers ();
6895
6896 clear_buffer_p = 0;
6897
6898 if (which == 0)
6899 this_one = 0, the_other = 1;
6900 else if (which > 0)
6901 this_one = 1, the_other = 0;
6902 else
6903 {
6904 this_one = 0, the_other = 1;
6905 clear_buffer_p = 1;
6906
6907 /* We need a fresh one in case the current echo buffer equals
6908 the one containing the last displayed echo area message. */
6909 if (!NILP (echo_area_buffer[this_one])
6910 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
6911 echo_area_buffer[this_one] = Qnil;
6912 }
6913
6914 /* Choose a suitable buffer from echo_buffer[] is we don't
6915 have one. */
6916 if (NILP (echo_area_buffer[this_one]))
6917 {
6918 echo_area_buffer[this_one]
6919 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
6920 ? echo_buffer[the_other]
6921 : echo_buffer[this_one]);
6922 clear_buffer_p = 1;
6923 }
6924
6925 buffer = echo_area_buffer[this_one];
6926
6927 /* Don't get confused by reusing the buffer used for echoing
6928 for a different purpose. */
6929 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
6930 cancel_echoing ();
6931
6932 record_unwind_protect (unwind_with_echo_area_buffer,
6933 with_echo_area_buffer_unwind_data (w));
6934
6935 /* Make the echo area buffer current. Note that for display
6936 purposes, it is not necessary that the displayed window's buffer
6937 == current_buffer, except for text property lookup. So, let's
6938 only set that buffer temporarily here without doing a full
6939 Fset_window_buffer. We must also change w->pointm, though,
6940 because otherwise an assertions in unshow_buffer fails, and Emacs
6941 aborts. */
6942 set_buffer_internal_1 (XBUFFER (buffer));
6943 if (w)
6944 {
6945 w->buffer = buffer;
6946 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
6947 }
6948
6949 current_buffer->undo_list = Qt;
6950 current_buffer->read_only = Qnil;
6951 specbind (Qinhibit_read_only, Qt);
6952 specbind (Qinhibit_modification_hooks, Qt);
6953
6954 if (clear_buffer_p && Z > BEG)
6955 del_range (BEG, Z);
6956
6957 xassert (BEGV >= BEG);
6958 xassert (ZV <= Z && ZV >= BEGV);
6959
6960 rc = fn (a1, a2, a3, a4);
6961
6962 xassert (BEGV >= BEG);
6963 xassert (ZV <= Z && ZV >= BEGV);
6964
6965 unbind_to (count, Qnil);
6966 return rc;
6967 }
6968
6969
6970 /* Save state that should be preserved around the call to the function
6971 FN called in with_echo_area_buffer. */
6972
6973 static Lisp_Object
6974 with_echo_area_buffer_unwind_data (w)
6975 struct window *w;
6976 {
6977 int i = 0;
6978 Lisp_Object vector;
6979
6980 /* Reduce consing by keeping one vector in
6981 Vwith_echo_area_save_vector. */
6982 vector = Vwith_echo_area_save_vector;
6983 Vwith_echo_area_save_vector = Qnil;
6984
6985 if (NILP (vector))
6986 vector = Fmake_vector (make_number (7), Qnil);
6987
6988 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
6989 AREF (vector, i) = Vdeactivate_mark, ++i;
6990 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
6991
6992 if (w)
6993 {
6994 XSETWINDOW (AREF (vector, i), w); ++i;
6995 AREF (vector, i) = w->buffer; ++i;
6996 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
6997 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
6998 }
6999 else
7000 {
7001 int end = i + 4;
7002 for (; i < end; ++i)
7003 AREF (vector, i) = Qnil;
7004 }
7005
7006 xassert (i == ASIZE (vector));
7007 return vector;
7008 }
7009
7010
7011 /* Restore global state from VECTOR which was created by
7012 with_echo_area_buffer_unwind_data. */
7013
7014 static Lisp_Object
7015 unwind_with_echo_area_buffer (vector)
7016 Lisp_Object vector;
7017 {
7018 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7019 Vdeactivate_mark = AREF (vector, 1);
7020 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7021
7022 if (WINDOWP (AREF (vector, 3)))
7023 {
7024 struct window *w;
7025 Lisp_Object buffer, charpos, bytepos;
7026
7027 w = XWINDOW (AREF (vector, 3));
7028 buffer = AREF (vector, 4);
7029 charpos = AREF (vector, 5);
7030 bytepos = AREF (vector, 6);
7031
7032 w->buffer = buffer;
7033 set_marker_both (w->pointm, buffer,
7034 XFASTINT (charpos), XFASTINT (bytepos));
7035 }
7036
7037 Vwith_echo_area_save_vector = vector;
7038 return Qnil;
7039 }
7040
7041
7042 /* Set up the echo area for use by print functions. MULTIBYTE_P
7043 non-zero means we will print multibyte. */
7044
7045 void
7046 setup_echo_area_for_printing (multibyte_p)
7047 int multibyte_p;
7048 {
7049 /* If we can't find an echo area any more, exit. */
7050 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7051 Fkill_emacs (Qnil);
7052
7053 ensure_echo_area_buffers ();
7054
7055 if (!message_buf_print)
7056 {
7057 /* A message has been output since the last time we printed.
7058 Choose a fresh echo area buffer. */
7059 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7060 echo_area_buffer[0] = echo_buffer[1];
7061 else
7062 echo_area_buffer[0] = echo_buffer[0];
7063
7064 /* Switch to that buffer and clear it. */
7065 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7066 current_buffer->truncate_lines = Qnil;
7067
7068 if (Z > BEG)
7069 {
7070 int count = SPECPDL_INDEX ();
7071 specbind (Qinhibit_read_only, Qt);
7072 /* Note that undo recording is always disabled. */
7073 del_range (BEG, Z);
7074 unbind_to (count, Qnil);
7075 }
7076 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7077
7078 /* Set up the buffer for the multibyteness we need. */
7079 if (multibyte_p
7080 != !NILP (current_buffer->enable_multibyte_characters))
7081 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7082
7083 /* Raise the frame containing the echo area. */
7084 if (minibuffer_auto_raise)
7085 {
7086 struct frame *sf = SELECTED_FRAME ();
7087 Lisp_Object mini_window;
7088 mini_window = FRAME_MINIBUF_WINDOW (sf);
7089 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7090 }
7091
7092 message_log_maybe_newline ();
7093 message_buf_print = 1;
7094 }
7095 else
7096 {
7097 if (NILP (echo_area_buffer[0]))
7098 {
7099 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7100 echo_area_buffer[0] = echo_buffer[1];
7101 else
7102 echo_area_buffer[0] = echo_buffer[0];
7103 }
7104
7105 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7106 {
7107 /* Someone switched buffers between print requests. */
7108 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7109 current_buffer->truncate_lines = Qnil;
7110 }
7111 }
7112 }
7113
7114
7115 /* Display an echo area message in window W. Value is non-zero if W's
7116 height is changed. If display_last_displayed_message_p is
7117 non-zero, display the message that was last displayed, otherwise
7118 display the current message. */
7119
7120 static int
7121 display_echo_area (w)
7122 struct window *w;
7123 {
7124 int i, no_message_p, window_height_changed_p, count;
7125
7126 /* Temporarily disable garbage collections while displaying the echo
7127 area. This is done because a GC can print a message itself.
7128 That message would modify the echo area buffer's contents while a
7129 redisplay of the buffer is going on, and seriously confuse
7130 redisplay. */
7131 count = inhibit_garbage_collection ();
7132
7133 /* If there is no message, we must call display_echo_area_1
7134 nevertheless because it resizes the window. But we will have to
7135 reset the echo_area_buffer in question to nil at the end because
7136 with_echo_area_buffer will sets it to an empty buffer. */
7137 i = display_last_displayed_message_p ? 1 : 0;
7138 no_message_p = NILP (echo_area_buffer[i]);
7139
7140 window_height_changed_p
7141 = with_echo_area_buffer (w, display_last_displayed_message_p,
7142 display_echo_area_1,
7143 (EMACS_INT) w, Qnil, 0, 0);
7144
7145 if (no_message_p)
7146 echo_area_buffer[i] = Qnil;
7147
7148 unbind_to (count, Qnil);
7149 return window_height_changed_p;
7150 }
7151
7152
7153 /* Helper for display_echo_area. Display the current buffer which
7154 contains the current echo area message in window W, a mini-window,
7155 a pointer to which is passed in A1. A2..A4 are currently not used.
7156 Change the height of W so that all of the message is displayed.
7157 Value is non-zero if height of W was changed. */
7158
7159 static int
7160 display_echo_area_1 (a1, a2, a3, a4)
7161 EMACS_INT a1;
7162 Lisp_Object a2;
7163 EMACS_INT a3, a4;
7164 {
7165 struct window *w = (struct window *) a1;
7166 Lisp_Object window;
7167 struct text_pos start;
7168 int window_height_changed_p = 0;
7169
7170 /* Do this before displaying, so that we have a large enough glyph
7171 matrix for the display. */
7172 window_height_changed_p = resize_mini_window (w, 0);
7173
7174 /* Display. */
7175 clear_glyph_matrix (w->desired_matrix);
7176 XSETWINDOW (window, w);
7177 SET_TEXT_POS (start, BEG, BEG_BYTE);
7178 try_window (window, start);
7179
7180 return window_height_changed_p;
7181 }
7182
7183
7184 /* Resize the echo area window to exactly the size needed for the
7185 currently displayed message, if there is one. If a mini-buffer
7186 is active, don't shrink it. */
7187
7188 void
7189 resize_echo_area_exactly ()
7190 {
7191 if (BUFFERP (echo_area_buffer[0])
7192 && WINDOWP (echo_area_window))
7193 {
7194 struct window *w = XWINDOW (echo_area_window);
7195 int resized_p;
7196 Lisp_Object resize_exactly;
7197
7198 if (minibuf_level == 0)
7199 resize_exactly = Qt;
7200 else
7201 resize_exactly = Qnil;
7202
7203 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7204 (EMACS_INT) w, resize_exactly, 0, 0);
7205 if (resized_p)
7206 {
7207 ++windows_or_buffers_changed;
7208 ++update_mode_lines;
7209 redisplay_internal (0);
7210 }
7211 }
7212 }
7213
7214
7215 /* Callback function for with_echo_area_buffer, when used from
7216 resize_echo_area_exactly. A1 contains a pointer to the window to
7217 resize, EXACTLY non-nil means resize the mini-window exactly to the
7218 size of the text displayed. A3 and A4 are not used. Value is what
7219 resize_mini_window returns. */
7220
7221 static int
7222 resize_mini_window_1 (a1, exactly, a3, a4)
7223 EMACS_INT a1;
7224 Lisp_Object exactly;
7225 EMACS_INT a3, a4;
7226 {
7227 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7228 }
7229
7230
7231 /* Resize mini-window W to fit the size of its contents. EXACT:P
7232 means size the window exactly to the size needed. Otherwise, it's
7233 only enlarged until W's buffer is empty. Value is non-zero if
7234 the window height has been changed. */
7235
7236 int
7237 resize_mini_window (w, exact_p)
7238 struct window *w;
7239 int exact_p;
7240 {
7241 struct frame *f = XFRAME (w->frame);
7242 int window_height_changed_p = 0;
7243
7244 xassert (MINI_WINDOW_P (w));
7245
7246 /* Don't resize windows while redisplaying a window; it would
7247 confuse redisplay functions when the size of the window they are
7248 displaying changes from under them. Such a resizing can happen,
7249 for instance, when which-func prints a long message while
7250 we are running fontification-functions. We're running these
7251 functions with safe_call which binds inhibit-redisplay to t. */
7252 if (!NILP (Vinhibit_redisplay))
7253 return 0;
7254
7255 /* Nil means don't try to resize. */
7256 if (NILP (Vresize_mini_windows)
7257 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7258 return 0;
7259
7260 if (!FRAME_MINIBUF_ONLY_P (f))
7261 {
7262 struct it it;
7263 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7264 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7265 int height, max_height;
7266 int unit = FRAME_LINE_HEIGHT (f);
7267 struct text_pos start;
7268 struct buffer *old_current_buffer = NULL;
7269
7270 if (current_buffer != XBUFFER (w->buffer))
7271 {
7272 old_current_buffer = current_buffer;
7273 set_buffer_internal (XBUFFER (w->buffer));
7274 }
7275
7276 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7277
7278 /* Compute the max. number of lines specified by the user. */
7279 if (FLOATP (Vmax_mini_window_height))
7280 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7281 else if (INTEGERP (Vmax_mini_window_height))
7282 max_height = XINT (Vmax_mini_window_height);
7283 else
7284 max_height = total_height / 4;
7285
7286 /* Correct that max. height if it's bogus. */
7287 max_height = max (1, max_height);
7288 max_height = min (total_height, max_height);
7289
7290 /* Find out the height of the text in the window. */
7291 if (it.truncate_lines_p)
7292 height = 1;
7293 else
7294 {
7295 last_height = 0;
7296 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7297 if (it.max_ascent == 0 && it.max_descent == 0)
7298 height = it.current_y + last_height;
7299 else
7300 height = it.current_y + it.max_ascent + it.max_descent;
7301 height -= it.extra_line_spacing;
7302 height = (height + unit - 1) / unit;
7303 }
7304
7305 /* Compute a suitable window start. */
7306 if (height > max_height)
7307 {
7308 height = max_height;
7309 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7310 move_it_vertically_backward (&it, (height - 1) * unit);
7311 start = it.current.pos;
7312 }
7313 else
7314 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7315 SET_MARKER_FROM_TEXT_POS (w->start, start);
7316
7317 if (EQ (Vresize_mini_windows, Qgrow_only))
7318 {
7319 /* Let it grow only, until we display an empty message, in which
7320 case the window shrinks again. */
7321 if (height > WINDOW_TOTAL_LINES (w))
7322 {
7323 int old_height = WINDOW_TOTAL_LINES (w);
7324 freeze_window_starts (f, 1);
7325 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7326 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7327 }
7328 else if (height < WINDOW_TOTAL_LINES (w)
7329 && (exact_p || BEGV == ZV))
7330 {
7331 int old_height = WINDOW_TOTAL_LINES (w);
7332 freeze_window_starts (f, 0);
7333 shrink_mini_window (w);
7334 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7335 }
7336 }
7337 else
7338 {
7339 /* Always resize to exact size needed. */
7340 if (height > WINDOW_TOTAL_LINES (w))
7341 {
7342 int old_height = WINDOW_TOTAL_LINES (w);
7343 freeze_window_starts (f, 1);
7344 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7345 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7346 }
7347 else if (height < WINDOW_TOTAL_LINES (w))
7348 {
7349 int old_height = WINDOW_TOTAL_LINES (w);
7350 freeze_window_starts (f, 0);
7351 shrink_mini_window (w);
7352
7353 if (height)
7354 {
7355 freeze_window_starts (f, 1);
7356 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7357 }
7358
7359 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7360 }
7361 }
7362
7363 if (old_current_buffer)
7364 set_buffer_internal (old_current_buffer);
7365 }
7366
7367 return window_height_changed_p;
7368 }
7369
7370
7371 /* Value is the current message, a string, or nil if there is no
7372 current message. */
7373
7374 Lisp_Object
7375 current_message ()
7376 {
7377 Lisp_Object msg;
7378
7379 if (NILP (echo_area_buffer[0]))
7380 msg = Qnil;
7381 else
7382 {
7383 with_echo_area_buffer (0, 0, current_message_1,
7384 (EMACS_INT) &msg, Qnil, 0, 0);
7385 if (NILP (msg))
7386 echo_area_buffer[0] = Qnil;
7387 }
7388
7389 return msg;
7390 }
7391
7392
7393 static int
7394 current_message_1 (a1, a2, a3, a4)
7395 EMACS_INT a1;
7396 Lisp_Object a2;
7397 EMACS_INT a3, a4;
7398 {
7399 Lisp_Object *msg = (Lisp_Object *) a1;
7400
7401 if (Z > BEG)
7402 *msg = make_buffer_string (BEG, Z, 1);
7403 else
7404 *msg = Qnil;
7405 return 0;
7406 }
7407
7408
7409 /* Push the current message on Vmessage_stack for later restauration
7410 by restore_message. Value is non-zero if the current message isn't
7411 empty. This is a relatively infrequent operation, so it's not
7412 worth optimizing. */
7413
7414 int
7415 push_message ()
7416 {
7417 Lisp_Object msg;
7418 msg = current_message ();
7419 Vmessage_stack = Fcons (msg, Vmessage_stack);
7420 return STRINGP (msg);
7421 }
7422
7423
7424 /* Restore message display from the top of Vmessage_stack. */
7425
7426 void
7427 restore_message ()
7428 {
7429 Lisp_Object msg;
7430
7431 xassert (CONSP (Vmessage_stack));
7432 msg = XCAR (Vmessage_stack);
7433 if (STRINGP (msg))
7434 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7435 else
7436 message3_nolog (msg, 0, 0);
7437 }
7438
7439
7440 /* Handler for record_unwind_protect calling pop_message. */
7441
7442 Lisp_Object
7443 pop_message_unwind (dummy)
7444 Lisp_Object dummy;
7445 {
7446 pop_message ();
7447 return Qnil;
7448 }
7449
7450 /* Pop the top-most entry off Vmessage_stack. */
7451
7452 void
7453 pop_message ()
7454 {
7455 xassert (CONSP (Vmessage_stack));
7456 Vmessage_stack = XCDR (Vmessage_stack);
7457 }
7458
7459
7460 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7461 exits. If the stack is not empty, we have a missing pop_message
7462 somewhere. */
7463
7464 void
7465 check_message_stack ()
7466 {
7467 if (!NILP (Vmessage_stack))
7468 abort ();
7469 }
7470
7471
7472 /* Truncate to NCHARS what will be displayed in the echo area the next
7473 time we display it---but don't redisplay it now. */
7474
7475 void
7476 truncate_echo_area (nchars)
7477 int nchars;
7478 {
7479 if (nchars == 0)
7480 echo_area_buffer[0] = Qnil;
7481 /* A null message buffer means that the frame hasn't really been
7482 initialized yet. Error messages get reported properly by
7483 cmd_error, so this must be just an informative message; toss it. */
7484 else if (!noninteractive
7485 && INTERACTIVE
7486 && !NILP (echo_area_buffer[0]))
7487 {
7488 struct frame *sf = SELECTED_FRAME ();
7489 if (FRAME_MESSAGE_BUF (sf))
7490 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7491 }
7492 }
7493
7494
7495 /* Helper function for truncate_echo_area. Truncate the current
7496 message to at most NCHARS characters. */
7497
7498 static int
7499 truncate_message_1 (nchars, a2, a3, a4)
7500 EMACS_INT nchars;
7501 Lisp_Object a2;
7502 EMACS_INT a3, a4;
7503 {
7504 if (BEG + nchars < Z)
7505 del_range (BEG + nchars, Z);
7506 if (Z == BEG)
7507 echo_area_buffer[0] = Qnil;
7508 return 0;
7509 }
7510
7511
7512 /* Set the current message to a substring of S or STRING.
7513
7514 If STRING is a Lisp string, set the message to the first NBYTES
7515 bytes from STRING. NBYTES zero means use the whole string. If
7516 STRING is multibyte, the message will be displayed multibyte.
7517
7518 If S is not null, set the message to the first LEN bytes of S. LEN
7519 zero means use the whole string. MULTIBYTE_P non-zero means S is
7520 multibyte. Display the message multibyte in that case. */
7521
7522 void
7523 set_message (s, string, nbytes, multibyte_p)
7524 const char *s;
7525 Lisp_Object string;
7526 int nbytes, multibyte_p;
7527 {
7528 message_enable_multibyte
7529 = ((s && multibyte_p)
7530 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7531
7532 with_echo_area_buffer (0, -1, set_message_1,
7533 (EMACS_INT) s, string, nbytes, multibyte_p);
7534 message_buf_print = 0;
7535 help_echo_showing_p = 0;
7536 }
7537
7538
7539 /* Helper function for set_message. Arguments have the same meaning
7540 as there, with A1 corresponding to S and A2 corresponding to STRING
7541 This function is called with the echo area buffer being
7542 current. */
7543
7544 static int
7545 set_message_1 (a1, a2, nbytes, multibyte_p)
7546 EMACS_INT a1;
7547 Lisp_Object a2;
7548 EMACS_INT nbytes, multibyte_p;
7549 {
7550 const char *s = (const char *) a1;
7551 Lisp_Object string = a2;
7552
7553 xassert (BEG == Z);
7554
7555 /* Change multibyteness of the echo buffer appropriately. */
7556 if (message_enable_multibyte
7557 != !NILP (current_buffer->enable_multibyte_characters))
7558 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7559
7560 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7561
7562 /* Insert new message at BEG. */
7563 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7564
7565 if (STRINGP (string))
7566 {
7567 int nchars;
7568
7569 if (nbytes == 0)
7570 nbytes = SBYTES (string);
7571 nchars = string_byte_to_char (string, nbytes);
7572
7573 /* This function takes care of single/multibyte conversion. We
7574 just have to ensure that the echo area buffer has the right
7575 setting of enable_multibyte_characters. */
7576 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7577 }
7578 else if (s)
7579 {
7580 if (nbytes == 0)
7581 nbytes = strlen (s);
7582
7583 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7584 {
7585 /* Convert from multi-byte to single-byte. */
7586 int i, c, n;
7587 unsigned char work[1];
7588
7589 /* Convert a multibyte string to single-byte. */
7590 for (i = 0; i < nbytes; i += n)
7591 {
7592 c = string_char_and_length (s + i, nbytes - i, &n);
7593 work[0] = (SINGLE_BYTE_CHAR_P (c)
7594 ? c
7595 : multibyte_char_to_unibyte (c, Qnil));
7596 insert_1_both (work, 1, 1, 1, 0, 0);
7597 }
7598 }
7599 else if (!multibyte_p
7600 && !NILP (current_buffer->enable_multibyte_characters))
7601 {
7602 /* Convert from single-byte to multi-byte. */
7603 int i, c, n;
7604 const unsigned char *msg = (const unsigned char *) s;
7605 unsigned char str[MAX_MULTIBYTE_LENGTH];
7606
7607 /* Convert a single-byte string to multibyte. */
7608 for (i = 0; i < nbytes; i++)
7609 {
7610 c = unibyte_char_to_multibyte (msg[i]);
7611 n = CHAR_STRING (c, str);
7612 insert_1_both (str, 1, n, 1, 0, 0);
7613 }
7614 }
7615 else
7616 insert_1 (s, nbytes, 1, 0, 0);
7617 }
7618
7619 return 0;
7620 }
7621
7622
7623 /* Clear messages. CURRENT_P non-zero means clear the current
7624 message. LAST_DISPLAYED_P non-zero means clear the message
7625 last displayed. */
7626
7627 void
7628 clear_message (current_p, last_displayed_p)
7629 int current_p, last_displayed_p;
7630 {
7631 if (current_p)
7632 {
7633 echo_area_buffer[0] = Qnil;
7634 message_cleared_p = 1;
7635 }
7636
7637 if (last_displayed_p)
7638 echo_area_buffer[1] = Qnil;
7639
7640 message_buf_print = 0;
7641 }
7642
7643 /* Clear garbaged frames.
7644
7645 This function is used where the old redisplay called
7646 redraw_garbaged_frames which in turn called redraw_frame which in
7647 turn called clear_frame. The call to clear_frame was a source of
7648 flickering. I believe a clear_frame is not necessary. It should
7649 suffice in the new redisplay to invalidate all current matrices,
7650 and ensure a complete redisplay of all windows. */
7651
7652 static void
7653 clear_garbaged_frames ()
7654 {
7655 if (frame_garbaged)
7656 {
7657 Lisp_Object tail, frame;
7658 int changed_count = 0;
7659
7660 FOR_EACH_FRAME (tail, frame)
7661 {
7662 struct frame *f = XFRAME (frame);
7663
7664 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
7665 {
7666 if (f->resized_p)
7667 {
7668 Fredraw_frame (frame);
7669 f->force_flush_display_p = 1;
7670 }
7671 clear_current_matrices (f);
7672 changed_count++;
7673 f->garbaged = 0;
7674 f->resized_p = 0;
7675 }
7676 }
7677
7678 frame_garbaged = 0;
7679 if (changed_count)
7680 ++windows_or_buffers_changed;
7681 }
7682 }
7683
7684
7685 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
7686 is non-zero update selected_frame. Value is non-zero if the
7687 mini-windows height has been changed. */
7688
7689 static int
7690 echo_area_display (update_frame_p)
7691 int update_frame_p;
7692 {
7693 Lisp_Object mini_window;
7694 struct window *w;
7695 struct frame *f;
7696 int window_height_changed_p = 0;
7697 struct frame *sf = SELECTED_FRAME ();
7698
7699 mini_window = FRAME_MINIBUF_WINDOW (sf);
7700 w = XWINDOW (mini_window);
7701 f = XFRAME (WINDOW_FRAME (w));
7702
7703 /* Don't display if frame is invisible or not yet initialized. */
7704 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
7705 return 0;
7706
7707 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
7708 #ifndef MAC_OS8
7709 #ifdef HAVE_WINDOW_SYSTEM
7710 /* When Emacs starts, selected_frame may be a visible terminal
7711 frame, even if we run under a window system. If we let this
7712 through, a message would be displayed on the terminal. */
7713 if (EQ (selected_frame, Vterminal_frame)
7714 && !NILP (Vwindow_system))
7715 return 0;
7716 #endif /* HAVE_WINDOW_SYSTEM */
7717 #endif
7718
7719 /* Redraw garbaged frames. */
7720 if (frame_garbaged)
7721 clear_garbaged_frames ();
7722
7723 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
7724 {
7725 echo_area_window = mini_window;
7726 window_height_changed_p = display_echo_area (w);
7727 w->must_be_updated_p = 1;
7728
7729 /* Update the display, unless called from redisplay_internal.
7730 Also don't update the screen during redisplay itself. The
7731 update will happen at the end of redisplay, and an update
7732 here could cause confusion. */
7733 if (update_frame_p && !redisplaying_p)
7734 {
7735 int n = 0;
7736
7737 /* If the display update has been interrupted by pending
7738 input, update mode lines in the frame. Due to the
7739 pending input, it might have been that redisplay hasn't
7740 been called, so that mode lines above the echo area are
7741 garbaged. This looks odd, so we prevent it here. */
7742 if (!display_completed)
7743 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
7744
7745 if (window_height_changed_p
7746 /* Don't do this if Emacs is shutting down. Redisplay
7747 needs to run hooks. */
7748 && !NILP (Vrun_hooks))
7749 {
7750 /* Must update other windows. Likewise as in other
7751 cases, don't let this update be interrupted by
7752 pending input. */
7753 int count = SPECPDL_INDEX ();
7754 specbind (Qredisplay_dont_pause, Qt);
7755 windows_or_buffers_changed = 1;
7756 redisplay_internal (0);
7757 unbind_to (count, Qnil);
7758 }
7759 else if (FRAME_WINDOW_P (f) && n == 0)
7760 {
7761 /* Window configuration is the same as before.
7762 Can do with a display update of the echo area,
7763 unless we displayed some mode lines. */
7764 update_single_window (w, 1);
7765 rif->flush_display (f);
7766 }
7767 else
7768 update_frame (f, 1, 1);
7769
7770 /* If cursor is in the echo area, make sure that the next
7771 redisplay displays the minibuffer, so that the cursor will
7772 be replaced with what the minibuffer wants. */
7773 if (cursor_in_echo_area)
7774 ++windows_or_buffers_changed;
7775 }
7776 }
7777 else if (!EQ (mini_window, selected_window))
7778 windows_or_buffers_changed++;
7779
7780 /* Last displayed message is now the current message. */
7781 echo_area_buffer[1] = echo_area_buffer[0];
7782
7783 /* Prevent redisplay optimization in redisplay_internal by resetting
7784 this_line_start_pos. This is done because the mini-buffer now
7785 displays the message instead of its buffer text. */
7786 if (EQ (mini_window, selected_window))
7787 CHARPOS (this_line_start_pos) = 0;
7788
7789 return window_height_changed_p;
7790 }
7791
7792
7793 \f
7794 /***********************************************************************
7795 Frame Titles
7796 ***********************************************************************/
7797
7798
7799 /* The frame title buffering code is also used by Fformat_mode_line.
7800 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
7801
7802 /* A buffer for constructing frame titles in it; allocated from the
7803 heap in init_xdisp and resized as needed in store_frame_title_char. */
7804
7805 static char *frame_title_buf;
7806
7807 /* The buffer's end, and a current output position in it. */
7808
7809 static char *frame_title_buf_end;
7810 static char *frame_title_ptr;
7811
7812
7813 /* Store a single character C for the frame title in frame_title_buf.
7814 Re-allocate frame_title_buf if necessary. */
7815
7816 static void
7817 #ifdef PROTOTYPES
7818 store_frame_title_char (char c)
7819 #else
7820 store_frame_title_char (c)
7821 char c;
7822 #endif
7823 {
7824 /* If output position has reached the end of the allocated buffer,
7825 double the buffer's size. */
7826 if (frame_title_ptr == frame_title_buf_end)
7827 {
7828 int len = frame_title_ptr - frame_title_buf;
7829 int new_size = 2 * len * sizeof *frame_title_buf;
7830 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
7831 frame_title_buf_end = frame_title_buf + new_size;
7832 frame_title_ptr = frame_title_buf + len;
7833 }
7834
7835 *frame_title_ptr++ = c;
7836 }
7837
7838
7839 /* Store part of a frame title in frame_title_buf, beginning at
7840 frame_title_ptr. STR is the string to store. Do not copy
7841 characters that yield more columns than PRECISION; PRECISION <= 0
7842 means copy the whole string. Pad with spaces until FIELD_WIDTH
7843 number of characters have been copied; FIELD_WIDTH <= 0 means don't
7844 pad. Called from display_mode_element when it is used to build a
7845 frame title. */
7846
7847 static int
7848 store_frame_title (str, field_width, precision)
7849 const unsigned char *str;
7850 int field_width, precision;
7851 {
7852 int n = 0;
7853 int dummy, nbytes;
7854
7855 /* Copy at most PRECISION chars from STR. */
7856 nbytes = strlen (str);
7857 n+= c_string_width (str, nbytes, precision, &dummy, &nbytes);
7858 while (nbytes--)
7859 store_frame_title_char (*str++);
7860
7861 /* Fill up with spaces until FIELD_WIDTH reached. */
7862 while (field_width > 0
7863 && n < field_width)
7864 {
7865 store_frame_title_char (' ');
7866 ++n;
7867 }
7868
7869 return n;
7870 }
7871
7872 #ifdef HAVE_WINDOW_SYSTEM
7873
7874 /* Set the title of FRAME, if it has changed. The title format is
7875 Vicon_title_format if FRAME is iconified, otherwise it is
7876 frame_title_format. */
7877
7878 static void
7879 x_consider_frame_title (frame)
7880 Lisp_Object frame;
7881 {
7882 struct frame *f = XFRAME (frame);
7883
7884 if (FRAME_WINDOW_P (f)
7885 || FRAME_MINIBUF_ONLY_P (f)
7886 || f->explicit_name)
7887 {
7888 /* Do we have more than one visible frame on this X display? */
7889 Lisp_Object tail;
7890 Lisp_Object fmt;
7891 struct buffer *obuf;
7892 int len;
7893 struct it it;
7894
7895 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
7896 {
7897 Lisp_Object other_frame = XCAR (tail);
7898 struct frame *tf = XFRAME (other_frame);
7899
7900 if (tf != f
7901 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
7902 && !FRAME_MINIBUF_ONLY_P (tf)
7903 && !EQ (other_frame, tip_frame)
7904 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
7905 break;
7906 }
7907
7908 /* Set global variable indicating that multiple frames exist. */
7909 multiple_frames = CONSP (tail);
7910
7911 /* Switch to the buffer of selected window of the frame. Set up
7912 frame_title_ptr so that display_mode_element will output into it;
7913 then display the title. */
7914 obuf = current_buffer;
7915 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
7916 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
7917 frame_title_ptr = frame_title_buf;
7918 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
7919 NULL, DEFAULT_FACE_ID);
7920 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
7921 len = frame_title_ptr - frame_title_buf;
7922 frame_title_ptr = NULL;
7923 set_buffer_internal_1 (obuf);
7924
7925 /* Set the title only if it's changed. This avoids consing in
7926 the common case where it hasn't. (If it turns out that we've
7927 already wasted too much time by walking through the list with
7928 display_mode_element, then we might need to optimize at a
7929 higher level than this.) */
7930 if (! STRINGP (f->name)
7931 || SBYTES (f->name) != len
7932 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
7933 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
7934 }
7935 }
7936
7937 #endif /* not HAVE_WINDOW_SYSTEM */
7938
7939
7940
7941 \f
7942 /***********************************************************************
7943 Menu Bars
7944 ***********************************************************************/
7945
7946
7947 /* Prepare for redisplay by updating menu-bar item lists when
7948 appropriate. This can call eval. */
7949
7950 void
7951 prepare_menu_bars ()
7952 {
7953 int all_windows;
7954 struct gcpro gcpro1, gcpro2;
7955 struct frame *f;
7956 Lisp_Object tooltip_frame;
7957
7958 #ifdef HAVE_WINDOW_SYSTEM
7959 tooltip_frame = tip_frame;
7960 #else
7961 tooltip_frame = Qnil;
7962 #endif
7963
7964 /* Update all frame titles based on their buffer names, etc. We do
7965 this before the menu bars so that the buffer-menu will show the
7966 up-to-date frame titles. */
7967 #ifdef HAVE_WINDOW_SYSTEM
7968 if (windows_or_buffers_changed || update_mode_lines)
7969 {
7970 Lisp_Object tail, frame;
7971
7972 FOR_EACH_FRAME (tail, frame)
7973 {
7974 f = XFRAME (frame);
7975 if (!EQ (frame, tooltip_frame)
7976 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
7977 x_consider_frame_title (frame);
7978 }
7979 }
7980 #endif /* HAVE_WINDOW_SYSTEM */
7981
7982 /* Update the menu bar item lists, if appropriate. This has to be
7983 done before any actual redisplay or generation of display lines. */
7984 all_windows = (update_mode_lines
7985 || buffer_shared > 1
7986 || windows_or_buffers_changed);
7987 if (all_windows)
7988 {
7989 Lisp_Object tail, frame;
7990 int count = SPECPDL_INDEX ();
7991
7992 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
7993
7994 FOR_EACH_FRAME (tail, frame)
7995 {
7996 f = XFRAME (frame);
7997
7998 /* Ignore tooltip frame. */
7999 if (EQ (frame, tooltip_frame))
8000 continue;
8001
8002 /* If a window on this frame changed size, report that to
8003 the user and clear the size-change flag. */
8004 if (FRAME_WINDOW_SIZES_CHANGED (f))
8005 {
8006 Lisp_Object functions;
8007
8008 /* Clear flag first in case we get an error below. */
8009 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8010 functions = Vwindow_size_change_functions;
8011 GCPRO2 (tail, functions);
8012
8013 while (CONSP (functions))
8014 {
8015 call1 (XCAR (functions), frame);
8016 functions = XCDR (functions);
8017 }
8018 UNGCPRO;
8019 }
8020
8021 GCPRO1 (tail);
8022 update_menu_bar (f, 0);
8023 #ifdef HAVE_WINDOW_SYSTEM
8024 update_tool_bar (f, 0);
8025 #endif
8026 UNGCPRO;
8027 }
8028
8029 unbind_to (count, Qnil);
8030 }
8031 else
8032 {
8033 struct frame *sf = SELECTED_FRAME ();
8034 update_menu_bar (sf, 1);
8035 #ifdef HAVE_WINDOW_SYSTEM
8036 update_tool_bar (sf, 1);
8037 #endif
8038 }
8039
8040 /* Motif needs this. See comment in xmenu.c. Turn it off when
8041 pending_menu_activation is not defined. */
8042 #ifdef USE_X_TOOLKIT
8043 pending_menu_activation = 0;
8044 #endif
8045 }
8046
8047
8048 /* Update the menu bar item list for frame F. This has to be done
8049 before we start to fill in any display lines, because it can call
8050 eval.
8051
8052 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8053
8054 static void
8055 update_menu_bar (f, save_match_data)
8056 struct frame *f;
8057 int save_match_data;
8058 {
8059 Lisp_Object window;
8060 register struct window *w;
8061
8062 /* If called recursively during a menu update, do nothing. This can
8063 happen when, for instance, an activate-menubar-hook causes a
8064 redisplay. */
8065 if (inhibit_menubar_update)
8066 return;
8067
8068 window = FRAME_SELECTED_WINDOW (f);
8069 w = XWINDOW (window);
8070
8071 #if 0 /* The if statement below this if statement used to include the
8072 condition !NILP (w->update_mode_line), rather than using
8073 update_mode_lines directly, and this if statement may have
8074 been added to make that condition work. Now the if
8075 statement below matches its comment, this isn't needed. */
8076 if (update_mode_lines)
8077 w->update_mode_line = Qt;
8078 #endif
8079
8080 if (FRAME_WINDOW_P (f)
8081 ?
8082 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8083 || defined (USE_GTK)
8084 FRAME_EXTERNAL_MENU_BAR (f)
8085 #else
8086 FRAME_MENU_BAR_LINES (f) > 0
8087 #endif
8088 : FRAME_MENU_BAR_LINES (f) > 0)
8089 {
8090 /* If the user has switched buffers or windows, we need to
8091 recompute to reflect the new bindings. But we'll
8092 recompute when update_mode_lines is set too; that means
8093 that people can use force-mode-line-update to request
8094 that the menu bar be recomputed. The adverse effect on
8095 the rest of the redisplay algorithm is about the same as
8096 windows_or_buffers_changed anyway. */
8097 if (windows_or_buffers_changed
8098 /* This used to test w->update_mode_line, but we believe
8099 there is no need to recompute the menu in that case. */
8100 || update_mode_lines
8101 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8102 < BUF_MODIFF (XBUFFER (w->buffer)))
8103 != !NILP (w->last_had_star))
8104 || ((!NILP (Vtransient_mark_mode)
8105 && !NILP (XBUFFER (w->buffer)->mark_active))
8106 != !NILP (w->region_showing)))
8107 {
8108 struct buffer *prev = current_buffer;
8109 int count = SPECPDL_INDEX ();
8110
8111 specbind (Qinhibit_menubar_update, Qt);
8112
8113 set_buffer_internal_1 (XBUFFER (w->buffer));
8114 if (save_match_data)
8115 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8116 if (NILP (Voverriding_local_map_menu_flag))
8117 {
8118 specbind (Qoverriding_terminal_local_map, Qnil);
8119 specbind (Qoverriding_local_map, Qnil);
8120 }
8121
8122 /* Run the Lucid hook. */
8123 safe_run_hooks (Qactivate_menubar_hook);
8124
8125 /* If it has changed current-menubar from previous value,
8126 really recompute the menu-bar from the value. */
8127 if (! NILP (Vlucid_menu_bar_dirty_flag))
8128 call0 (Qrecompute_lucid_menubar);
8129
8130 safe_run_hooks (Qmenu_bar_update_hook);
8131 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8132
8133 /* Redisplay the menu bar in case we changed it. */
8134 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8135 || defined (USE_GTK)
8136 if (FRAME_WINDOW_P (f)
8137 #if defined (MAC_OS)
8138 /* All frames on Mac OS share the same menubar. So only the
8139 selected frame should be allowed to set it. */
8140 && f == SELECTED_FRAME ()
8141 #endif
8142 )
8143 set_frame_menubar (f, 0, 0);
8144 else
8145 /* On a terminal screen, the menu bar is an ordinary screen
8146 line, and this makes it get updated. */
8147 w->update_mode_line = Qt;
8148 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8149 /* In the non-toolkit version, the menu bar is an ordinary screen
8150 line, and this makes it get updated. */
8151 w->update_mode_line = Qt;
8152 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8153
8154 unbind_to (count, Qnil);
8155 set_buffer_internal_1 (prev);
8156 }
8157 }
8158 }
8159
8160
8161 \f
8162 /***********************************************************************
8163 Output Cursor
8164 ***********************************************************************/
8165
8166 #ifdef HAVE_WINDOW_SYSTEM
8167
8168 /* EXPORT:
8169 Nominal cursor position -- where to draw output.
8170 HPOS and VPOS are window relative glyph matrix coordinates.
8171 X and Y are window relative pixel coordinates. */
8172
8173 struct cursor_pos output_cursor;
8174
8175
8176 /* EXPORT:
8177 Set the global variable output_cursor to CURSOR. All cursor
8178 positions are relative to updated_window. */
8179
8180 void
8181 set_output_cursor (cursor)
8182 struct cursor_pos *cursor;
8183 {
8184 output_cursor.hpos = cursor->hpos;
8185 output_cursor.vpos = cursor->vpos;
8186 output_cursor.x = cursor->x;
8187 output_cursor.y = cursor->y;
8188 }
8189
8190
8191 /* EXPORT for RIF:
8192 Set a nominal cursor position.
8193
8194 HPOS and VPOS are column/row positions in a window glyph matrix. X
8195 and Y are window text area relative pixel positions.
8196
8197 If this is done during an update, updated_window will contain the
8198 window that is being updated and the position is the future output
8199 cursor position for that window. If updated_window is null, use
8200 selected_window and display the cursor at the given position. */
8201
8202 void
8203 x_cursor_to (vpos, hpos, y, x)
8204 int vpos, hpos, y, x;
8205 {
8206 struct window *w;
8207
8208 /* If updated_window is not set, work on selected_window. */
8209 if (updated_window)
8210 w = updated_window;
8211 else
8212 w = XWINDOW (selected_window);
8213
8214 /* Set the output cursor. */
8215 output_cursor.hpos = hpos;
8216 output_cursor.vpos = vpos;
8217 output_cursor.x = x;
8218 output_cursor.y = y;
8219
8220 /* If not called as part of an update, really display the cursor.
8221 This will also set the cursor position of W. */
8222 if (updated_window == NULL)
8223 {
8224 BLOCK_INPUT;
8225 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8226 if (rif->flush_display_optional)
8227 rif->flush_display_optional (SELECTED_FRAME ());
8228 UNBLOCK_INPUT;
8229 }
8230 }
8231
8232 #endif /* HAVE_WINDOW_SYSTEM */
8233
8234 \f
8235 /***********************************************************************
8236 Tool-bars
8237 ***********************************************************************/
8238
8239 #ifdef HAVE_WINDOW_SYSTEM
8240
8241 /* Where the mouse was last time we reported a mouse event. */
8242
8243 FRAME_PTR last_mouse_frame;
8244
8245 /* Tool-bar item index of the item on which a mouse button was pressed
8246 or -1. */
8247
8248 int last_tool_bar_item;
8249
8250
8251 /* Update the tool-bar item list for frame F. This has to be done
8252 before we start to fill in any display lines. Called from
8253 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8254 and restore it here. */
8255
8256 static void
8257 update_tool_bar (f, save_match_data)
8258 struct frame *f;
8259 int save_match_data;
8260 {
8261 #ifdef USE_GTK
8262 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8263 #else
8264 int do_update = WINDOWP (f->tool_bar_window)
8265 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8266 #endif
8267
8268 if (do_update)
8269 {
8270 Lisp_Object window;
8271 struct window *w;
8272
8273 window = FRAME_SELECTED_WINDOW (f);
8274 w = XWINDOW (window);
8275
8276 /* If the user has switched buffers or windows, we need to
8277 recompute to reflect the new bindings. But we'll
8278 recompute when update_mode_lines is set too; that means
8279 that people can use force-mode-line-update to request
8280 that the menu bar be recomputed. The adverse effect on
8281 the rest of the redisplay algorithm is about the same as
8282 windows_or_buffers_changed anyway. */
8283 if (windows_or_buffers_changed
8284 || !NILP (w->update_mode_line)
8285 || update_mode_lines
8286 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8287 < BUF_MODIFF (XBUFFER (w->buffer)))
8288 != !NILP (w->last_had_star))
8289 || ((!NILP (Vtransient_mark_mode)
8290 && !NILP (XBUFFER (w->buffer)->mark_active))
8291 != !NILP (w->region_showing)))
8292 {
8293 struct buffer *prev = current_buffer;
8294 int count = SPECPDL_INDEX ();
8295 Lisp_Object old_tool_bar;
8296 struct gcpro gcpro1;
8297
8298 /* Set current_buffer to the buffer of the selected
8299 window of the frame, so that we get the right local
8300 keymaps. */
8301 set_buffer_internal_1 (XBUFFER (w->buffer));
8302
8303 /* Save match data, if we must. */
8304 if (save_match_data)
8305 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8306
8307 /* Make sure that we don't accidentally use bogus keymaps. */
8308 if (NILP (Voverriding_local_map_menu_flag))
8309 {
8310 specbind (Qoverriding_terminal_local_map, Qnil);
8311 specbind (Qoverriding_local_map, Qnil);
8312 }
8313
8314 old_tool_bar = f->tool_bar_items;
8315 GCPRO1 (old_tool_bar);
8316
8317 /* Build desired tool-bar items from keymaps. */
8318 BLOCK_INPUT;
8319 f->tool_bar_items
8320 = tool_bar_items (f->tool_bar_items, &f->n_tool_bar_items);
8321 UNBLOCK_INPUT;
8322
8323 /* Redisplay the tool-bar if we changed it. */
8324 if (! NILP (Fequal (old_tool_bar, f->tool_bar_items)))
8325 w->update_mode_line = Qt;
8326
8327 UNGCPRO;
8328
8329 unbind_to (count, Qnil);
8330 set_buffer_internal_1 (prev);
8331 }
8332 }
8333 }
8334
8335
8336 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8337 F's desired tool-bar contents. F->tool_bar_items must have
8338 been set up previously by calling prepare_menu_bars. */
8339
8340 static void
8341 build_desired_tool_bar_string (f)
8342 struct frame *f;
8343 {
8344 int i, size, size_needed;
8345 struct gcpro gcpro1, gcpro2, gcpro3;
8346 Lisp_Object image, plist, props;
8347
8348 image = plist = props = Qnil;
8349 GCPRO3 (image, plist, props);
8350
8351 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8352 Otherwise, make a new string. */
8353
8354 /* The size of the string we might be able to reuse. */
8355 size = (STRINGP (f->desired_tool_bar_string)
8356 ? SCHARS (f->desired_tool_bar_string)
8357 : 0);
8358
8359 /* We need one space in the string for each image. */
8360 size_needed = f->n_tool_bar_items;
8361
8362 /* Reuse f->desired_tool_bar_string, if possible. */
8363 if (size < size_needed || NILP (f->desired_tool_bar_string))
8364 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8365 make_number (' '));
8366 else
8367 {
8368 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8369 Fremove_text_properties (make_number (0), make_number (size),
8370 props, f->desired_tool_bar_string);
8371 }
8372
8373 /* Put a `display' property on the string for the images to display,
8374 put a `menu_item' property on tool-bar items with a value that
8375 is the index of the item in F's tool-bar item vector. */
8376 for (i = 0; i < f->n_tool_bar_items; ++i)
8377 {
8378 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8379
8380 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8381 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8382 int hmargin, vmargin, relief, idx, end;
8383 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8384
8385 /* If image is a vector, choose the image according to the
8386 button state. */
8387 image = PROP (TOOL_BAR_ITEM_IMAGES);
8388 if (VECTORP (image))
8389 {
8390 if (enabled_p)
8391 idx = (selected_p
8392 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8393 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8394 else
8395 idx = (selected_p
8396 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8397 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8398
8399 xassert (ASIZE (image) >= idx);
8400 image = AREF (image, idx);
8401 }
8402 else
8403 idx = -1;
8404
8405 /* Ignore invalid image specifications. */
8406 if (!valid_image_p (image))
8407 continue;
8408
8409 /* Display the tool-bar button pressed, or depressed. */
8410 plist = Fcopy_sequence (XCDR (image));
8411
8412 /* Compute margin and relief to draw. */
8413 relief = (tool_bar_button_relief >= 0
8414 ? tool_bar_button_relief
8415 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8416 hmargin = vmargin = relief;
8417
8418 if (INTEGERP (Vtool_bar_button_margin)
8419 && XINT (Vtool_bar_button_margin) > 0)
8420 {
8421 hmargin += XFASTINT (Vtool_bar_button_margin);
8422 vmargin += XFASTINT (Vtool_bar_button_margin);
8423 }
8424 else if (CONSP (Vtool_bar_button_margin))
8425 {
8426 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8427 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8428 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8429
8430 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8431 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8432 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8433 }
8434
8435 if (auto_raise_tool_bar_buttons_p)
8436 {
8437 /* Add a `:relief' property to the image spec if the item is
8438 selected. */
8439 if (selected_p)
8440 {
8441 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8442 hmargin -= relief;
8443 vmargin -= relief;
8444 }
8445 }
8446 else
8447 {
8448 /* If image is selected, display it pressed, i.e. with a
8449 negative relief. If it's not selected, display it with a
8450 raised relief. */
8451 plist = Fplist_put (plist, QCrelief,
8452 (selected_p
8453 ? make_number (-relief)
8454 : make_number (relief)));
8455 hmargin -= relief;
8456 vmargin -= relief;
8457 }
8458
8459 /* Put a margin around the image. */
8460 if (hmargin || vmargin)
8461 {
8462 if (hmargin == vmargin)
8463 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8464 else
8465 plist = Fplist_put (plist, QCmargin,
8466 Fcons (make_number (hmargin),
8467 make_number (vmargin)));
8468 }
8469
8470 /* If button is not enabled, and we don't have special images
8471 for the disabled state, make the image appear disabled by
8472 applying an appropriate algorithm to it. */
8473 if (!enabled_p && idx < 0)
8474 plist = Fplist_put (plist, QCconversion, Qdisabled);
8475
8476 /* Put a `display' text property on the string for the image to
8477 display. Put a `menu-item' property on the string that gives
8478 the start of this item's properties in the tool-bar items
8479 vector. */
8480 image = Fcons (Qimage, plist);
8481 props = list4 (Qdisplay, image,
8482 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8483
8484 /* Let the last image hide all remaining spaces in the tool bar
8485 string. The string can be longer than needed when we reuse a
8486 previous string. */
8487 if (i + 1 == f->n_tool_bar_items)
8488 end = SCHARS (f->desired_tool_bar_string);
8489 else
8490 end = i + 1;
8491 Fadd_text_properties (make_number (i), make_number (end),
8492 props, f->desired_tool_bar_string);
8493 #undef PROP
8494 }
8495
8496 UNGCPRO;
8497 }
8498
8499
8500 /* Display one line of the tool-bar of frame IT->f. */
8501
8502 static void
8503 display_tool_bar_line (it)
8504 struct it *it;
8505 {
8506 struct glyph_row *row = it->glyph_row;
8507 int max_x = it->last_visible_x;
8508 struct glyph *last;
8509
8510 prepare_desired_row (row);
8511 row->y = it->current_y;
8512
8513 /* Note that this isn't made use of if the face hasn't a box,
8514 so there's no need to check the face here. */
8515 it->start_of_box_run_p = 1;
8516
8517 while (it->current_x < max_x)
8518 {
8519 int x_before, x, n_glyphs_before, i, nglyphs;
8520
8521 /* Get the next display element. */
8522 if (!get_next_display_element (it))
8523 break;
8524
8525 /* Produce glyphs. */
8526 x_before = it->current_x;
8527 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8528 PRODUCE_GLYPHS (it);
8529
8530 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8531 i = 0;
8532 x = x_before;
8533 while (i < nglyphs)
8534 {
8535 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8536
8537 if (x + glyph->pixel_width > max_x)
8538 {
8539 /* Glyph doesn't fit on line. */
8540 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8541 it->current_x = x;
8542 goto out;
8543 }
8544
8545 ++it->hpos;
8546 x += glyph->pixel_width;
8547 ++i;
8548 }
8549
8550 /* Stop at line ends. */
8551 if (ITERATOR_AT_END_OF_LINE_P (it))
8552 break;
8553
8554 set_iterator_to_next (it, 1);
8555 }
8556
8557 out:;
8558
8559 row->displays_text_p = row->used[TEXT_AREA] != 0;
8560 extend_face_to_end_of_line (it);
8561 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8562 last->right_box_line_p = 1;
8563 if (last == row->glyphs[TEXT_AREA])
8564 last->left_box_line_p = 1;
8565 compute_line_metrics (it);
8566
8567 /* If line is empty, make it occupy the rest of the tool-bar. */
8568 if (!row->displays_text_p)
8569 {
8570 row->height = row->phys_height = it->last_visible_y - row->y;
8571 row->ascent = row->phys_ascent = 0;
8572 }
8573
8574 row->full_width_p = 1;
8575 row->continued_p = 0;
8576 row->truncated_on_left_p = 0;
8577 row->truncated_on_right_p = 0;
8578
8579 it->current_x = it->hpos = 0;
8580 it->current_y += row->height;
8581 ++it->vpos;
8582 ++it->glyph_row;
8583 }
8584
8585
8586 /* Value is the number of screen lines needed to make all tool-bar
8587 items of frame F visible. */
8588
8589 static int
8590 tool_bar_lines_needed (f)
8591 struct frame *f;
8592 {
8593 struct window *w = XWINDOW (f->tool_bar_window);
8594 struct it it;
8595
8596 /* Initialize an iterator for iteration over
8597 F->desired_tool_bar_string in the tool-bar window of frame F. */
8598 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8599 it.first_visible_x = 0;
8600 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8601 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8602
8603 while (!ITERATOR_AT_END_P (&it))
8604 {
8605 it.glyph_row = w->desired_matrix->rows;
8606 clear_glyph_row (it.glyph_row);
8607 display_tool_bar_line (&it);
8608 }
8609
8610 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8611 }
8612
8613
8614 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8615 0, 1, 0,
8616 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8617 (frame)
8618 Lisp_Object frame;
8619 {
8620 struct frame *f;
8621 struct window *w;
8622 int nlines = 0;
8623
8624 if (NILP (frame))
8625 frame = selected_frame;
8626 else
8627 CHECK_FRAME (frame);
8628 f = XFRAME (frame);
8629
8630 if (WINDOWP (f->tool_bar_window)
8631 || (w = XWINDOW (f->tool_bar_window),
8632 WINDOW_TOTAL_LINES (w) > 0))
8633 {
8634 update_tool_bar (f, 1);
8635 if (f->n_tool_bar_items)
8636 {
8637 build_desired_tool_bar_string (f);
8638 nlines = tool_bar_lines_needed (f);
8639 }
8640 }
8641
8642 return make_number (nlines);
8643 }
8644
8645
8646 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
8647 height should be changed. */
8648
8649 static int
8650 redisplay_tool_bar (f)
8651 struct frame *f;
8652 {
8653 struct window *w;
8654 struct it it;
8655 struct glyph_row *row;
8656 int change_height_p = 0;
8657
8658 #ifdef USE_GTK
8659 if (FRAME_EXTERNAL_TOOL_BAR (f))
8660 update_frame_tool_bar (f);
8661 return 0;
8662 #endif
8663
8664 /* If frame hasn't a tool-bar window or if it is zero-height, don't
8665 do anything. This means you must start with tool-bar-lines
8666 non-zero to get the auto-sizing effect. Or in other words, you
8667 can turn off tool-bars by specifying tool-bar-lines zero. */
8668 if (!WINDOWP (f->tool_bar_window)
8669 || (w = XWINDOW (f->tool_bar_window),
8670 WINDOW_TOTAL_LINES (w) == 0))
8671 return 0;
8672
8673 /* Set up an iterator for the tool-bar window. */
8674 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8675 it.first_visible_x = 0;
8676 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8677 row = it.glyph_row;
8678
8679 /* Build a string that represents the contents of the tool-bar. */
8680 build_desired_tool_bar_string (f);
8681 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8682
8683 /* Display as many lines as needed to display all tool-bar items. */
8684 while (it.current_y < it.last_visible_y)
8685 display_tool_bar_line (&it);
8686
8687 /* It doesn't make much sense to try scrolling in the tool-bar
8688 window, so don't do it. */
8689 w->desired_matrix->no_scrolling_p = 1;
8690 w->must_be_updated_p = 1;
8691
8692 if (auto_resize_tool_bars_p)
8693 {
8694 int nlines;
8695
8696 /* If we couldn't display everything, change the tool-bar's
8697 height. */
8698 if (IT_STRING_CHARPOS (it) < it.end_charpos)
8699 change_height_p = 1;
8700
8701 /* If there are blank lines at the end, except for a partially
8702 visible blank line at the end that is smaller than
8703 FRAME_LINE_HEIGHT, change the tool-bar's height. */
8704 row = it.glyph_row - 1;
8705 if (!row->displays_text_p
8706 && row->height >= FRAME_LINE_HEIGHT (f))
8707 change_height_p = 1;
8708
8709 /* If row displays tool-bar items, but is partially visible,
8710 change the tool-bar's height. */
8711 if (row->displays_text_p
8712 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
8713 change_height_p = 1;
8714
8715 /* Resize windows as needed by changing the `tool-bar-lines'
8716 frame parameter. */
8717 if (change_height_p
8718 && (nlines = tool_bar_lines_needed (f),
8719 nlines != WINDOW_TOTAL_LINES (w)))
8720 {
8721 extern Lisp_Object Qtool_bar_lines;
8722 Lisp_Object frame;
8723 int old_height = WINDOW_TOTAL_LINES (w);
8724
8725 XSETFRAME (frame, f);
8726 clear_glyph_matrix (w->desired_matrix);
8727 Fmodify_frame_parameters (frame,
8728 Fcons (Fcons (Qtool_bar_lines,
8729 make_number (nlines)),
8730 Qnil));
8731 if (WINDOW_TOTAL_LINES (w) != old_height)
8732 fonts_changed_p = 1;
8733 }
8734 }
8735
8736 return change_height_p;
8737 }
8738
8739
8740 /* Get information about the tool-bar item which is displayed in GLYPH
8741 on frame F. Return in *PROP_IDX the index where tool-bar item
8742 properties start in F->tool_bar_items. Value is zero if
8743 GLYPH doesn't display a tool-bar item. */
8744
8745 static int
8746 tool_bar_item_info (f, glyph, prop_idx)
8747 struct frame *f;
8748 struct glyph *glyph;
8749 int *prop_idx;
8750 {
8751 Lisp_Object prop;
8752 int success_p;
8753 int charpos;
8754
8755 /* This function can be called asynchronously, which means we must
8756 exclude any possibility that Fget_text_property signals an
8757 error. */
8758 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
8759 charpos = max (0, charpos);
8760
8761 /* Get the text property `menu-item' at pos. The value of that
8762 property is the start index of this item's properties in
8763 F->tool_bar_items. */
8764 prop = Fget_text_property (make_number (charpos),
8765 Qmenu_item, f->current_tool_bar_string);
8766 if (INTEGERP (prop))
8767 {
8768 *prop_idx = XINT (prop);
8769 success_p = 1;
8770 }
8771 else
8772 success_p = 0;
8773
8774 return success_p;
8775 }
8776
8777 \f
8778 /* Get information about the tool-bar item at position X/Y on frame F.
8779 Return in *GLYPH a pointer to the glyph of the tool-bar item in
8780 the current matrix of the tool-bar window of F, or NULL if not
8781 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
8782 item in F->tool_bar_items. Value is
8783
8784 -1 if X/Y is not on a tool-bar item
8785 0 if X/Y is on the same item that was highlighted before.
8786 1 otherwise. */
8787
8788 static int
8789 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
8790 struct frame *f;
8791 int x, y;
8792 struct glyph **glyph;
8793 int *hpos, *vpos, *prop_idx;
8794 {
8795 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8796 struct window *w = XWINDOW (f->tool_bar_window);
8797 int area;
8798
8799 /* Find the glyph under X/Y. */
8800 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
8801 if (*glyph == NULL)
8802 return -1;
8803
8804 /* Get the start of this tool-bar item's properties in
8805 f->tool_bar_items. */
8806 if (!tool_bar_item_info (f, *glyph, prop_idx))
8807 return -1;
8808
8809 /* Is mouse on the highlighted item? */
8810 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
8811 && *vpos >= dpyinfo->mouse_face_beg_row
8812 && *vpos <= dpyinfo->mouse_face_end_row
8813 && (*vpos > dpyinfo->mouse_face_beg_row
8814 || *hpos >= dpyinfo->mouse_face_beg_col)
8815 && (*vpos < dpyinfo->mouse_face_end_row
8816 || *hpos < dpyinfo->mouse_face_end_col
8817 || dpyinfo->mouse_face_past_end))
8818 return 0;
8819
8820 return 1;
8821 }
8822
8823
8824 /* EXPORT:
8825 Handle mouse button event on the tool-bar of frame F, at
8826 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
8827 0 for button release. MODIFIERS is event modifiers for button
8828 release. */
8829
8830 void
8831 handle_tool_bar_click (f, x, y, down_p, modifiers)
8832 struct frame *f;
8833 int x, y, down_p;
8834 unsigned int modifiers;
8835 {
8836 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8837 struct window *w = XWINDOW (f->tool_bar_window);
8838 int hpos, vpos, prop_idx;
8839 struct glyph *glyph;
8840 Lisp_Object enabled_p;
8841
8842 /* If not on the highlighted tool-bar item, return. */
8843 frame_to_window_pixel_xy (w, &x, &y);
8844 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
8845 return;
8846
8847 /* If item is disabled, do nothing. */
8848 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8849 if (NILP (enabled_p))
8850 return;
8851
8852 if (down_p)
8853 {
8854 /* Show item in pressed state. */
8855 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
8856 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
8857 last_tool_bar_item = prop_idx;
8858 }
8859 else
8860 {
8861 Lisp_Object key, frame;
8862 struct input_event event;
8863 EVENT_INIT (event);
8864
8865 /* Show item in released state. */
8866 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
8867 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
8868
8869 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
8870
8871 XSETFRAME (frame, f);
8872 event.kind = TOOL_BAR_EVENT;
8873 event.frame_or_window = frame;
8874 event.arg = frame;
8875 kbd_buffer_store_event (&event);
8876
8877 event.kind = TOOL_BAR_EVENT;
8878 event.frame_or_window = frame;
8879 event.arg = key;
8880 event.modifiers = modifiers;
8881 kbd_buffer_store_event (&event);
8882 last_tool_bar_item = -1;
8883 }
8884 }
8885
8886
8887 /* Possibly highlight a tool-bar item on frame F when mouse moves to
8888 tool-bar window-relative coordinates X/Y. Called from
8889 note_mouse_highlight. */
8890
8891 static void
8892 note_tool_bar_highlight (f, x, y)
8893 struct frame *f;
8894 int x, y;
8895 {
8896 Lisp_Object window = f->tool_bar_window;
8897 struct window *w = XWINDOW (window);
8898 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
8899 int hpos, vpos;
8900 struct glyph *glyph;
8901 struct glyph_row *row;
8902 int i;
8903 Lisp_Object enabled_p;
8904 int prop_idx;
8905 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
8906 int mouse_down_p, rc;
8907
8908 /* Function note_mouse_highlight is called with negative x(y
8909 values when mouse moves outside of the frame. */
8910 if (x <= 0 || y <= 0)
8911 {
8912 clear_mouse_face (dpyinfo);
8913 return;
8914 }
8915
8916 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
8917 if (rc < 0)
8918 {
8919 /* Not on tool-bar item. */
8920 clear_mouse_face (dpyinfo);
8921 return;
8922 }
8923 else if (rc == 0)
8924 /* On same tool-bar item as before. */
8925 goto set_help_echo;
8926
8927 clear_mouse_face (dpyinfo);
8928
8929 /* Mouse is down, but on different tool-bar item? */
8930 mouse_down_p = (dpyinfo->grabbed
8931 && f == last_mouse_frame
8932 && FRAME_LIVE_P (f));
8933 if (mouse_down_p
8934 && last_tool_bar_item != prop_idx)
8935 return;
8936
8937 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
8938 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
8939
8940 /* If tool-bar item is not enabled, don't highlight it. */
8941 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
8942 if (!NILP (enabled_p))
8943 {
8944 /* Compute the x-position of the glyph. In front and past the
8945 image is a space. We include this in the highlighted area. */
8946 row = MATRIX_ROW (w->current_matrix, vpos);
8947 for (i = x = 0; i < hpos; ++i)
8948 x += row->glyphs[TEXT_AREA][i].pixel_width;
8949
8950 /* Record this as the current active region. */
8951 dpyinfo->mouse_face_beg_col = hpos;
8952 dpyinfo->mouse_face_beg_row = vpos;
8953 dpyinfo->mouse_face_beg_x = x;
8954 dpyinfo->mouse_face_beg_y = row->y;
8955 dpyinfo->mouse_face_past_end = 0;
8956
8957 dpyinfo->mouse_face_end_col = hpos + 1;
8958 dpyinfo->mouse_face_end_row = vpos;
8959 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
8960 dpyinfo->mouse_face_end_y = row->y;
8961 dpyinfo->mouse_face_window = window;
8962 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
8963
8964 /* Display it as active. */
8965 show_mouse_face (dpyinfo, draw);
8966 dpyinfo->mouse_face_image_state = draw;
8967 }
8968
8969 set_help_echo:
8970
8971 /* Set help_echo_string to a help string to display for this tool-bar item.
8972 XTread_socket does the rest. */
8973 help_echo_object = help_echo_window = Qnil;
8974 help_echo_pos = -1;
8975 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
8976 if (NILP (help_echo_string))
8977 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
8978 }
8979
8980 #endif /* HAVE_WINDOW_SYSTEM */
8981
8982
8983 \f
8984 /************************************************************************
8985 Horizontal scrolling
8986 ************************************************************************/
8987
8988 static int hscroll_window_tree P_ ((Lisp_Object));
8989 static int hscroll_windows P_ ((Lisp_Object));
8990
8991 /* For all leaf windows in the window tree rooted at WINDOW, set their
8992 hscroll value so that PT is (i) visible in the window, and (ii) so
8993 that it is not within a certain margin at the window's left and
8994 right border. Value is non-zero if any window's hscroll has been
8995 changed. */
8996
8997 static int
8998 hscroll_window_tree (window)
8999 Lisp_Object window;
9000 {
9001 int hscrolled_p = 0;
9002 int hscroll_relative_p = FLOATP (Vhscroll_step);
9003 int hscroll_step_abs = 0;
9004 double hscroll_step_rel = 0;
9005
9006 if (hscroll_relative_p)
9007 {
9008 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9009 if (hscroll_step_rel < 0)
9010 {
9011 hscroll_relative_p = 0;
9012 hscroll_step_abs = 0;
9013 }
9014 }
9015 else if (INTEGERP (Vhscroll_step))
9016 {
9017 hscroll_step_abs = XINT (Vhscroll_step);
9018 if (hscroll_step_abs < 0)
9019 hscroll_step_abs = 0;
9020 }
9021 else
9022 hscroll_step_abs = 0;
9023
9024 while (WINDOWP (window))
9025 {
9026 struct window *w = XWINDOW (window);
9027
9028 if (WINDOWP (w->hchild))
9029 hscrolled_p |= hscroll_window_tree (w->hchild);
9030 else if (WINDOWP (w->vchild))
9031 hscrolled_p |= hscroll_window_tree (w->vchild);
9032 else if (w->cursor.vpos >= 0)
9033 {
9034 int h_margin;
9035 int text_area_width;
9036 struct glyph_row *current_cursor_row
9037 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9038 struct glyph_row *desired_cursor_row
9039 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9040 struct glyph_row *cursor_row
9041 = (desired_cursor_row->enabled_p
9042 ? desired_cursor_row
9043 : current_cursor_row);
9044
9045 text_area_width = window_box_width (w, TEXT_AREA);
9046
9047 /* Scroll when cursor is inside this scroll margin. */
9048 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9049
9050 if ((XFASTINT (w->hscroll)
9051 && w->cursor.x <= h_margin)
9052 || (cursor_row->enabled_p
9053 && cursor_row->truncated_on_right_p
9054 && (w->cursor.x >= text_area_width - h_margin)))
9055 {
9056 struct it it;
9057 int hscroll;
9058 struct buffer *saved_current_buffer;
9059 int pt;
9060 int wanted_x;
9061
9062 /* Find point in a display of infinite width. */
9063 saved_current_buffer = current_buffer;
9064 current_buffer = XBUFFER (w->buffer);
9065
9066 if (w == XWINDOW (selected_window))
9067 pt = BUF_PT (current_buffer);
9068 else
9069 {
9070 pt = marker_position (w->pointm);
9071 pt = max (BEGV, pt);
9072 pt = min (ZV, pt);
9073 }
9074
9075 /* Move iterator to pt starting at cursor_row->start in
9076 a line with infinite width. */
9077 init_to_row_start (&it, w, cursor_row);
9078 it.last_visible_x = INFINITY;
9079 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9080 current_buffer = saved_current_buffer;
9081
9082 /* Position cursor in window. */
9083 if (!hscroll_relative_p && hscroll_step_abs == 0)
9084 hscroll = max (0, (it.current_x
9085 - (ITERATOR_AT_END_OF_LINE_P (&it)
9086 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9087 : (text_area_width / 2))))
9088 / FRAME_COLUMN_WIDTH (it.f);
9089 else if (w->cursor.x >= text_area_width - h_margin)
9090 {
9091 if (hscroll_relative_p)
9092 wanted_x = text_area_width * (1 - hscroll_step_rel)
9093 - h_margin;
9094 else
9095 wanted_x = text_area_width
9096 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9097 - h_margin;
9098 hscroll
9099 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9100 }
9101 else
9102 {
9103 if (hscroll_relative_p)
9104 wanted_x = text_area_width * hscroll_step_rel
9105 + h_margin;
9106 else
9107 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9108 + h_margin;
9109 hscroll
9110 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9111 }
9112 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9113
9114 /* Don't call Fset_window_hscroll if value hasn't
9115 changed because it will prevent redisplay
9116 optimizations. */
9117 if (XFASTINT (w->hscroll) != hscroll)
9118 {
9119 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9120 w->hscroll = make_number (hscroll);
9121 hscrolled_p = 1;
9122 }
9123 }
9124 }
9125
9126 window = w->next;
9127 }
9128
9129 /* Value is non-zero if hscroll of any leaf window has been changed. */
9130 return hscrolled_p;
9131 }
9132
9133
9134 /* Set hscroll so that cursor is visible and not inside horizontal
9135 scroll margins for all windows in the tree rooted at WINDOW. See
9136 also hscroll_window_tree above. Value is non-zero if any window's
9137 hscroll has been changed. If it has, desired matrices on the frame
9138 of WINDOW are cleared. */
9139
9140 static int
9141 hscroll_windows (window)
9142 Lisp_Object window;
9143 {
9144 int hscrolled_p;
9145
9146 if (automatic_hscrolling_p)
9147 {
9148 hscrolled_p = hscroll_window_tree (window);
9149 if (hscrolled_p)
9150 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9151 }
9152 else
9153 hscrolled_p = 0;
9154 return hscrolled_p;
9155 }
9156
9157
9158 \f
9159 /************************************************************************
9160 Redisplay
9161 ************************************************************************/
9162
9163 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9164 to a non-zero value. This is sometimes handy to have in a debugger
9165 session. */
9166
9167 #if GLYPH_DEBUG
9168
9169 /* First and last unchanged row for try_window_id. */
9170
9171 int debug_first_unchanged_at_end_vpos;
9172 int debug_last_unchanged_at_beg_vpos;
9173
9174 /* Delta vpos and y. */
9175
9176 int debug_dvpos, debug_dy;
9177
9178 /* Delta in characters and bytes for try_window_id. */
9179
9180 int debug_delta, debug_delta_bytes;
9181
9182 /* Values of window_end_pos and window_end_vpos at the end of
9183 try_window_id. */
9184
9185 EMACS_INT debug_end_pos, debug_end_vpos;
9186
9187 /* Append a string to W->desired_matrix->method. FMT is a printf
9188 format string. A1...A9 are a supplement for a variable-length
9189 argument list. If trace_redisplay_p is non-zero also printf the
9190 resulting string to stderr. */
9191
9192 static void
9193 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9194 struct window *w;
9195 char *fmt;
9196 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9197 {
9198 char buffer[512];
9199 char *method = w->desired_matrix->method;
9200 int len = strlen (method);
9201 int size = sizeof w->desired_matrix->method;
9202 int remaining = size - len - 1;
9203
9204 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9205 if (len && remaining)
9206 {
9207 method[len] = '|';
9208 --remaining, ++len;
9209 }
9210
9211 strncpy (method + len, buffer, remaining);
9212
9213 if (trace_redisplay_p)
9214 fprintf (stderr, "%p (%s): %s\n",
9215 w,
9216 ((BUFFERP (w->buffer)
9217 && STRINGP (XBUFFER (w->buffer)->name))
9218 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9219 : "no buffer"),
9220 buffer);
9221 }
9222
9223 #endif /* GLYPH_DEBUG */
9224
9225
9226 /* Value is non-zero if all changes in window W, which displays
9227 current_buffer, are in the text between START and END. START is a
9228 buffer position, END is given as a distance from Z. Used in
9229 redisplay_internal for display optimization. */
9230
9231 static INLINE int
9232 text_outside_line_unchanged_p (w, start, end)
9233 struct window *w;
9234 int start, end;
9235 {
9236 int unchanged_p = 1;
9237
9238 /* If text or overlays have changed, see where. */
9239 if (XFASTINT (w->last_modified) < MODIFF
9240 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9241 {
9242 /* Gap in the line? */
9243 if (GPT < start || Z - GPT < end)
9244 unchanged_p = 0;
9245
9246 /* Changes start in front of the line, or end after it? */
9247 if (unchanged_p
9248 && (BEG_UNCHANGED < start - 1
9249 || END_UNCHANGED < end))
9250 unchanged_p = 0;
9251
9252 /* If selective display, can't optimize if changes start at the
9253 beginning of the line. */
9254 if (unchanged_p
9255 && INTEGERP (current_buffer->selective_display)
9256 && XINT (current_buffer->selective_display) > 0
9257 && (BEG_UNCHANGED < start || GPT <= start))
9258 unchanged_p = 0;
9259
9260 /* If there are overlays at the start or end of the line, these
9261 may have overlay strings with newlines in them. A change at
9262 START, for instance, may actually concern the display of such
9263 overlay strings as well, and they are displayed on different
9264 lines. So, quickly rule out this case. (For the future, it
9265 might be desirable to implement something more telling than
9266 just BEG/END_UNCHANGED.) */
9267 if (unchanged_p)
9268 {
9269 if (BEG + BEG_UNCHANGED == start
9270 && overlay_touches_p (start))
9271 unchanged_p = 0;
9272 if (END_UNCHANGED == end
9273 && overlay_touches_p (Z - end))
9274 unchanged_p = 0;
9275 }
9276 }
9277
9278 return unchanged_p;
9279 }
9280
9281
9282 /* Do a frame update, taking possible shortcuts into account. This is
9283 the main external entry point for redisplay.
9284
9285 If the last redisplay displayed an echo area message and that message
9286 is no longer requested, we clear the echo area or bring back the
9287 mini-buffer if that is in use. */
9288
9289 void
9290 redisplay ()
9291 {
9292 redisplay_internal (0);
9293 }
9294
9295
9296 /* Return 1 if point moved out of or into a composition. Otherwise
9297 return 0. PREV_BUF and PREV_PT are the last point buffer and
9298 position. BUF and PT are the current point buffer and position. */
9299
9300 int
9301 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9302 struct buffer *prev_buf, *buf;
9303 int prev_pt, pt;
9304 {
9305 int start, end;
9306 Lisp_Object prop;
9307 Lisp_Object buffer;
9308
9309 XSETBUFFER (buffer, buf);
9310 /* Check a composition at the last point if point moved within the
9311 same buffer. */
9312 if (prev_buf == buf)
9313 {
9314 if (prev_pt == pt)
9315 /* Point didn't move. */
9316 return 0;
9317
9318 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9319 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9320 && COMPOSITION_VALID_P (start, end, prop)
9321 && start < prev_pt && end > prev_pt)
9322 /* The last point was within the composition. Return 1 iff
9323 point moved out of the composition. */
9324 return (pt <= start || pt >= end);
9325 }
9326
9327 /* Check a composition at the current point. */
9328 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9329 && find_composition (pt, -1, &start, &end, &prop, buffer)
9330 && COMPOSITION_VALID_P (start, end, prop)
9331 && start < pt && end > pt);
9332 }
9333
9334
9335 /* Reconsider the setting of B->clip_changed which is displayed
9336 in window W. */
9337
9338 static INLINE void
9339 reconsider_clip_changes (w, b)
9340 struct window *w;
9341 struct buffer *b;
9342 {
9343 if (b->clip_changed
9344 && !NILP (w->window_end_valid)
9345 && w->current_matrix->buffer == b
9346 && w->current_matrix->zv == BUF_ZV (b)
9347 && w->current_matrix->begv == BUF_BEGV (b))
9348 b->clip_changed = 0;
9349
9350 /* If display wasn't paused, and W is not a tool bar window, see if
9351 point has been moved into or out of a composition. In that case,
9352 we set b->clip_changed to 1 to force updating the screen. If
9353 b->clip_changed has already been set to 1, we can skip this
9354 check. */
9355 if (!b->clip_changed
9356 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9357 {
9358 int pt;
9359
9360 if (w == XWINDOW (selected_window))
9361 pt = BUF_PT (current_buffer);
9362 else
9363 pt = marker_position (w->pointm);
9364
9365 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9366 || pt != XINT (w->last_point))
9367 && check_point_in_composition (w->current_matrix->buffer,
9368 XINT (w->last_point),
9369 XBUFFER (w->buffer), pt))
9370 b->clip_changed = 1;
9371 }
9372 }
9373 \f
9374
9375 /* Select FRAME to forward the values of frame-local variables into C
9376 variables so that the redisplay routines can access those values
9377 directly. */
9378
9379 static void
9380 select_frame_for_redisplay (frame)
9381 Lisp_Object frame;
9382 {
9383 Lisp_Object tail, sym, val;
9384 Lisp_Object old = selected_frame;
9385
9386 selected_frame = frame;
9387
9388 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9389 if (CONSP (XCAR (tail))
9390 && (sym = XCAR (XCAR (tail)),
9391 SYMBOLP (sym))
9392 && (sym = indirect_variable (sym),
9393 val = SYMBOL_VALUE (sym),
9394 (BUFFER_LOCAL_VALUEP (val)
9395 || SOME_BUFFER_LOCAL_VALUEP (val)))
9396 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9397 Fsymbol_value (sym);
9398
9399 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9400 if (CONSP (XCAR (tail))
9401 && (sym = XCAR (XCAR (tail)),
9402 SYMBOLP (sym))
9403 && (sym = indirect_variable (sym),
9404 val = SYMBOL_VALUE (sym),
9405 (BUFFER_LOCAL_VALUEP (val)
9406 || SOME_BUFFER_LOCAL_VALUEP (val)))
9407 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9408 Fsymbol_value (sym);
9409 }
9410
9411
9412 #define STOP_POLLING \
9413 do { if (! polling_stopped_here) stop_polling (); \
9414 polling_stopped_here = 1; } while (0)
9415
9416 #define RESUME_POLLING \
9417 do { if (polling_stopped_here) start_polling (); \
9418 polling_stopped_here = 0; } while (0)
9419
9420
9421 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9422 response to any user action; therefore, we should preserve the echo
9423 area. (Actually, our caller does that job.) Perhaps in the future
9424 avoid recentering windows if it is not necessary; currently that
9425 causes some problems. */
9426
9427 static void
9428 redisplay_internal (preserve_echo_area)
9429 int preserve_echo_area;
9430 {
9431 struct window *w = XWINDOW (selected_window);
9432 struct frame *f = XFRAME (w->frame);
9433 int pause;
9434 int must_finish = 0;
9435 struct text_pos tlbufpos, tlendpos;
9436 int number_of_visible_frames;
9437 int count;
9438 struct frame *sf = SELECTED_FRAME ();
9439 int polling_stopped_here = 0;
9440
9441 /* Non-zero means redisplay has to consider all windows on all
9442 frames. Zero means, only selected_window is considered. */
9443 int consider_all_windows_p;
9444
9445 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9446
9447 /* No redisplay if running in batch mode or frame is not yet fully
9448 initialized, or redisplay is explicitly turned off by setting
9449 Vinhibit_redisplay. */
9450 if (noninteractive
9451 || !NILP (Vinhibit_redisplay)
9452 || !f->glyphs_initialized_p)
9453 return;
9454
9455 /* The flag redisplay_performed_directly_p is set by
9456 direct_output_for_insert when it already did the whole screen
9457 update necessary. */
9458 if (redisplay_performed_directly_p)
9459 {
9460 redisplay_performed_directly_p = 0;
9461 if (!hscroll_windows (selected_window))
9462 return;
9463 }
9464
9465 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9466 if (popup_activated ())
9467 return;
9468 #endif
9469
9470 /* I don't think this happens but let's be paranoid. */
9471 if (redisplaying_p)
9472 return;
9473
9474 /* Record a function that resets redisplaying_p to its old value
9475 when we leave this function. */
9476 count = SPECPDL_INDEX ();
9477 record_unwind_protect (unwind_redisplay,
9478 Fcons (make_number (redisplaying_p), selected_frame));
9479 ++redisplaying_p;
9480 specbind (Qinhibit_free_realized_faces, Qnil);
9481
9482 retry:
9483 pause = 0;
9484 reconsider_clip_changes (w, current_buffer);
9485
9486 /* If new fonts have been loaded that make a glyph matrix adjustment
9487 necessary, do it. */
9488 if (fonts_changed_p)
9489 {
9490 adjust_glyphs (NULL);
9491 ++windows_or_buffers_changed;
9492 fonts_changed_p = 0;
9493 }
9494
9495 /* If face_change_count is non-zero, init_iterator will free all
9496 realized faces, which includes the faces referenced from current
9497 matrices. So, we can't reuse current matrices in this case. */
9498 if (face_change_count)
9499 ++windows_or_buffers_changed;
9500
9501 if (! FRAME_WINDOW_P (sf)
9502 && previous_terminal_frame != sf)
9503 {
9504 /* Since frames on an ASCII terminal share the same display
9505 area, displaying a different frame means redisplay the whole
9506 thing. */
9507 windows_or_buffers_changed++;
9508 SET_FRAME_GARBAGED (sf);
9509 XSETFRAME (Vterminal_frame, sf);
9510 }
9511 previous_terminal_frame = sf;
9512
9513 /* Set the visible flags for all frames. Do this before checking
9514 for resized or garbaged frames; they want to know if their frames
9515 are visible. See the comment in frame.h for
9516 FRAME_SAMPLE_VISIBILITY. */
9517 {
9518 Lisp_Object tail, frame;
9519
9520 number_of_visible_frames = 0;
9521
9522 FOR_EACH_FRAME (tail, frame)
9523 {
9524 struct frame *f = XFRAME (frame);
9525
9526 FRAME_SAMPLE_VISIBILITY (f);
9527 if (FRAME_VISIBLE_P (f))
9528 ++number_of_visible_frames;
9529 clear_desired_matrices (f);
9530 }
9531 }
9532
9533 /* Notice any pending interrupt request to change frame size. */
9534 do_pending_window_change (1);
9535
9536 /* Clear frames marked as garbaged. */
9537 if (frame_garbaged)
9538 clear_garbaged_frames ();
9539
9540 /* Build menubar and tool-bar items. */
9541 prepare_menu_bars ();
9542
9543 if (windows_or_buffers_changed)
9544 update_mode_lines++;
9545
9546 /* Detect case that we need to write or remove a star in the mode line. */
9547 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
9548 {
9549 w->update_mode_line = Qt;
9550 if (buffer_shared > 1)
9551 update_mode_lines++;
9552 }
9553
9554 /* If %c is in the mode line, update it if needed. */
9555 if (!NILP (w->column_number_displayed)
9556 /* This alternative quickly identifies a common case
9557 where no change is needed. */
9558 && !(PT == XFASTINT (w->last_point)
9559 && XFASTINT (w->last_modified) >= MODIFF
9560 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
9561 && (XFASTINT (w->column_number_displayed)
9562 != (int) current_column ())) /* iftc */
9563 w->update_mode_line = Qt;
9564
9565 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
9566
9567 /* The variable buffer_shared is set in redisplay_window and
9568 indicates that we redisplay a buffer in different windows. See
9569 there. */
9570 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
9571 || cursor_type_changed);
9572
9573 /* If specs for an arrow have changed, do thorough redisplay
9574 to ensure we remove any arrow that should no longer exist. */
9575 if (! EQ (COERCE_MARKER (Voverlay_arrow_position), last_arrow_position)
9576 || ! EQ (Voverlay_arrow_string, last_arrow_string))
9577 consider_all_windows_p = windows_or_buffers_changed = 1;
9578
9579 /* Normally the message* functions will have already displayed and
9580 updated the echo area, but the frame may have been trashed, or
9581 the update may have been preempted, so display the echo area
9582 again here. Checking message_cleared_p captures the case that
9583 the echo area should be cleared. */
9584 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
9585 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
9586 || (message_cleared_p
9587 && minibuf_level == 0
9588 /* If the mini-window is currently selected, this means the
9589 echo-area doesn't show through. */
9590 && !MINI_WINDOW_P (XWINDOW (selected_window))))
9591 {
9592 int window_height_changed_p = echo_area_display (0);
9593 must_finish = 1;
9594
9595 /* If we don't display the current message, don't clear the
9596 message_cleared_p flag, because, if we did, we wouldn't clear
9597 the echo area in the next redisplay which doesn't preserve
9598 the echo area. */
9599 if (!display_last_displayed_message_p)
9600 message_cleared_p = 0;
9601
9602 if (fonts_changed_p)
9603 goto retry;
9604 else if (window_height_changed_p)
9605 {
9606 consider_all_windows_p = 1;
9607 ++update_mode_lines;
9608 ++windows_or_buffers_changed;
9609
9610 /* If window configuration was changed, frames may have been
9611 marked garbaged. Clear them or we will experience
9612 surprises wrt scrolling. */
9613 if (frame_garbaged)
9614 clear_garbaged_frames ();
9615 }
9616 }
9617 else if (EQ (selected_window, minibuf_window)
9618 && (current_buffer->clip_changed
9619 || XFASTINT (w->last_modified) < MODIFF
9620 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9621 && resize_mini_window (w, 0))
9622 {
9623 /* Resized active mini-window to fit the size of what it is
9624 showing if its contents might have changed. */
9625 must_finish = 1;
9626 consider_all_windows_p = 1;
9627 ++windows_or_buffers_changed;
9628 ++update_mode_lines;
9629
9630 /* If window configuration was changed, frames may have been
9631 marked garbaged. Clear them or we will experience
9632 surprises wrt scrolling. */
9633 if (frame_garbaged)
9634 clear_garbaged_frames ();
9635 }
9636
9637
9638 /* If showing the region, and mark has changed, we must redisplay
9639 the whole window. The assignment to this_line_start_pos prevents
9640 the optimization directly below this if-statement. */
9641 if (((!NILP (Vtransient_mark_mode)
9642 && !NILP (XBUFFER (w->buffer)->mark_active))
9643 != !NILP (w->region_showing))
9644 || (!NILP (w->region_showing)
9645 && !EQ (w->region_showing,
9646 Fmarker_position (XBUFFER (w->buffer)->mark))))
9647 CHARPOS (this_line_start_pos) = 0;
9648
9649 /* Optimize the case that only the line containing the cursor in the
9650 selected window has changed. Variables starting with this_ are
9651 set in display_line and record information about the line
9652 containing the cursor. */
9653 tlbufpos = this_line_start_pos;
9654 tlendpos = this_line_end_pos;
9655 if (!consider_all_windows_p
9656 && CHARPOS (tlbufpos) > 0
9657 && NILP (w->update_mode_line)
9658 && !current_buffer->clip_changed
9659 && !current_buffer->prevent_redisplay_optimizations_p
9660 && FRAME_VISIBLE_P (XFRAME (w->frame))
9661 && !FRAME_OBSCURED_P (XFRAME (w->frame))
9662 /* Make sure recorded data applies to current buffer, etc. */
9663 && this_line_buffer == current_buffer
9664 && current_buffer == XBUFFER (w->buffer)
9665 && NILP (w->force_start)
9666 && NILP (w->optional_new_start)
9667 /* Point must be on the line that we have info recorded about. */
9668 && PT >= CHARPOS (tlbufpos)
9669 && PT <= Z - CHARPOS (tlendpos)
9670 /* All text outside that line, including its final newline,
9671 must be unchanged */
9672 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
9673 CHARPOS (tlendpos)))
9674 {
9675 if (CHARPOS (tlbufpos) > BEGV
9676 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
9677 && (CHARPOS (tlbufpos) == ZV
9678 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
9679 /* Former continuation line has disappeared by becoming empty */
9680 goto cancel;
9681 else if (XFASTINT (w->last_modified) < MODIFF
9682 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
9683 || MINI_WINDOW_P (w))
9684 {
9685 /* We have to handle the case of continuation around a
9686 wide-column character (See the comment in indent.c around
9687 line 885).
9688
9689 For instance, in the following case:
9690
9691 -------- Insert --------
9692 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
9693 J_I_ ==> J_I_ `^^' are cursors.
9694 ^^ ^^
9695 -------- --------
9696
9697 As we have to redraw the line above, we should goto cancel. */
9698
9699 struct it it;
9700 int line_height_before = this_line_pixel_height;
9701
9702 /* Note that start_display will handle the case that the
9703 line starting at tlbufpos is a continuation lines. */
9704 start_display (&it, w, tlbufpos);
9705
9706 /* Implementation note: It this still necessary? */
9707 if (it.current_x != this_line_start_x)
9708 goto cancel;
9709
9710 TRACE ((stderr, "trying display optimization 1\n"));
9711 w->cursor.vpos = -1;
9712 overlay_arrow_seen = 0;
9713 it.vpos = this_line_vpos;
9714 it.current_y = this_line_y;
9715 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
9716 display_line (&it);
9717
9718 /* If line contains point, is not continued,
9719 and ends at same distance from eob as before, we win */
9720 if (w->cursor.vpos >= 0
9721 /* Line is not continued, otherwise this_line_start_pos
9722 would have been set to 0 in display_line. */
9723 && CHARPOS (this_line_start_pos)
9724 /* Line ends as before. */
9725 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
9726 /* Line has same height as before. Otherwise other lines
9727 would have to be shifted up or down. */
9728 && this_line_pixel_height == line_height_before)
9729 {
9730 /* If this is not the window's last line, we must adjust
9731 the charstarts of the lines below. */
9732 if (it.current_y < it.last_visible_y)
9733 {
9734 struct glyph_row *row
9735 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
9736 int delta, delta_bytes;
9737
9738 if (Z - CHARPOS (tlendpos) == ZV)
9739 {
9740 /* This line ends at end of (accessible part of)
9741 buffer. There is no newline to count. */
9742 delta = (Z
9743 - CHARPOS (tlendpos)
9744 - MATRIX_ROW_START_CHARPOS (row));
9745 delta_bytes = (Z_BYTE
9746 - BYTEPOS (tlendpos)
9747 - MATRIX_ROW_START_BYTEPOS (row));
9748 }
9749 else
9750 {
9751 /* This line ends in a newline. Must take
9752 account of the newline and the rest of the
9753 text that follows. */
9754 delta = (Z
9755 - CHARPOS (tlendpos)
9756 - MATRIX_ROW_START_CHARPOS (row));
9757 delta_bytes = (Z_BYTE
9758 - BYTEPOS (tlendpos)
9759 - MATRIX_ROW_START_BYTEPOS (row));
9760 }
9761
9762 increment_matrix_positions (w->current_matrix,
9763 this_line_vpos + 1,
9764 w->current_matrix->nrows,
9765 delta, delta_bytes);
9766 }
9767
9768 /* If this row displays text now but previously didn't,
9769 or vice versa, w->window_end_vpos may have to be
9770 adjusted. */
9771 if ((it.glyph_row - 1)->displays_text_p)
9772 {
9773 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
9774 XSETINT (w->window_end_vpos, this_line_vpos);
9775 }
9776 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
9777 && this_line_vpos > 0)
9778 XSETINT (w->window_end_vpos, this_line_vpos - 1);
9779 w->window_end_valid = Qnil;
9780
9781 /* Update hint: No need to try to scroll in update_window. */
9782 w->desired_matrix->no_scrolling_p = 1;
9783
9784 #if GLYPH_DEBUG
9785 *w->desired_matrix->method = 0;
9786 debug_method_add (w, "optimization 1");
9787 #endif
9788 #ifdef HAVE_WINDOW_SYSTEM
9789 update_window_fringes (w, 0);
9790 #endif
9791 goto update;
9792 }
9793 else
9794 goto cancel;
9795 }
9796 else if (/* Cursor position hasn't changed. */
9797 PT == XFASTINT (w->last_point)
9798 /* Make sure the cursor was last displayed
9799 in this window. Otherwise we have to reposition it. */
9800 && 0 <= w->cursor.vpos
9801 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
9802 {
9803 if (!must_finish)
9804 {
9805 do_pending_window_change (1);
9806
9807 /* We used to always goto end_of_redisplay here, but this
9808 isn't enough if we have a blinking cursor. */
9809 if (w->cursor_off_p == w->last_cursor_off_p)
9810 goto end_of_redisplay;
9811 }
9812 goto update;
9813 }
9814 /* If highlighting the region, or if the cursor is in the echo area,
9815 then we can't just move the cursor. */
9816 else if (! (!NILP (Vtransient_mark_mode)
9817 && !NILP (current_buffer->mark_active))
9818 && (EQ (selected_window, current_buffer->last_selected_window)
9819 || highlight_nonselected_windows)
9820 && NILP (w->region_showing)
9821 && NILP (Vshow_trailing_whitespace)
9822 && !cursor_in_echo_area)
9823 {
9824 struct it it;
9825 struct glyph_row *row;
9826
9827 /* Skip from tlbufpos to PT and see where it is. Note that
9828 PT may be in invisible text. If so, we will end at the
9829 next visible position. */
9830 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
9831 NULL, DEFAULT_FACE_ID);
9832 it.current_x = this_line_start_x;
9833 it.current_y = this_line_y;
9834 it.vpos = this_line_vpos;
9835
9836 /* The call to move_it_to stops in front of PT, but
9837 moves over before-strings. */
9838 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
9839
9840 if (it.vpos == this_line_vpos
9841 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
9842 row->enabled_p))
9843 {
9844 xassert (this_line_vpos == it.vpos);
9845 xassert (this_line_y == it.current_y);
9846 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
9847 #if GLYPH_DEBUG
9848 *w->desired_matrix->method = 0;
9849 debug_method_add (w, "optimization 3");
9850 #endif
9851 goto update;
9852 }
9853 else
9854 goto cancel;
9855 }
9856
9857 cancel:
9858 /* Text changed drastically or point moved off of line. */
9859 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
9860 }
9861
9862 CHARPOS (this_line_start_pos) = 0;
9863 consider_all_windows_p |= buffer_shared > 1;
9864 ++clear_face_cache_count;
9865
9866
9867 /* Build desired matrices, and update the display. If
9868 consider_all_windows_p is non-zero, do it for all windows on all
9869 frames. Otherwise do it for selected_window, only. */
9870
9871 if (consider_all_windows_p)
9872 {
9873 Lisp_Object tail, frame;
9874 int i, n = 0, size = 50;
9875 struct frame **updated
9876 = (struct frame **) alloca (size * sizeof *updated);
9877
9878 /* Clear the face cache eventually. */
9879 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
9880 {
9881 clear_face_cache (0);
9882 clear_face_cache_count = 0;
9883 }
9884
9885 /* Recompute # windows showing selected buffer. This will be
9886 incremented each time such a window is displayed. */
9887 buffer_shared = 0;
9888
9889 FOR_EACH_FRAME (tail, frame)
9890 {
9891 struct frame *f = XFRAME (frame);
9892
9893 if (FRAME_WINDOW_P (f) || f == sf)
9894 {
9895 if (! EQ (frame, selected_frame))
9896 /* Select the frame, for the sake of frame-local
9897 variables. */
9898 select_frame_for_redisplay (frame);
9899
9900 #ifdef HAVE_WINDOW_SYSTEM
9901 if (clear_face_cache_count % 50 == 0
9902 && FRAME_WINDOW_P (f))
9903 clear_image_cache (f, 0);
9904 #endif /* HAVE_WINDOW_SYSTEM */
9905
9906 /* Mark all the scroll bars to be removed; we'll redeem
9907 the ones we want when we redisplay their windows. */
9908 if (condemn_scroll_bars_hook)
9909 condemn_scroll_bars_hook (f);
9910
9911 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
9912 redisplay_windows (FRAME_ROOT_WINDOW (f));
9913
9914 /* Any scroll bars which redisplay_windows should have
9915 nuked should now go away. */
9916 if (judge_scroll_bars_hook)
9917 judge_scroll_bars_hook (f);
9918
9919 /* If fonts changed, display again. */
9920 /* ??? rms: I suspect it is a mistake to jump all the way
9921 back to retry here. It should just retry this frame. */
9922 if (fonts_changed_p)
9923 goto retry;
9924
9925 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
9926 {
9927 /* See if we have to hscroll. */
9928 if (hscroll_windows (f->root_window))
9929 goto retry;
9930
9931 /* Prevent various kinds of signals during display
9932 update. stdio is not robust about handling
9933 signals, which can cause an apparent I/O
9934 error. */
9935 if (interrupt_input)
9936 unrequest_sigio ();
9937 STOP_POLLING;
9938
9939 /* Update the display. */
9940 set_window_update_flags (XWINDOW (f->root_window), 1);
9941 pause |= update_frame (f, 0, 0);
9942 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
9943 if (pause)
9944 break;
9945 #endif
9946
9947 if (n == size)
9948 {
9949 int nbytes = size * sizeof *updated;
9950 struct frame **p = (struct frame **) alloca (2 * nbytes);
9951 bcopy (updated, p, nbytes);
9952 size *= 2;
9953 }
9954
9955 updated[n++] = f;
9956 }
9957 }
9958 }
9959
9960 if (!pause)
9961 {
9962 /* Do the mark_window_display_accurate after all windows have
9963 been redisplayed because this call resets flags in buffers
9964 which are needed for proper redisplay. */
9965 for (i = 0; i < n; ++i)
9966 {
9967 struct frame *f = updated[i];
9968 mark_window_display_accurate (f->root_window, 1);
9969 if (frame_up_to_date_hook)
9970 frame_up_to_date_hook (f);
9971 }
9972 }
9973 }
9974 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
9975 {
9976 Lisp_Object mini_window;
9977 struct frame *mini_frame;
9978
9979 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
9980 /* Use list_of_error, not Qerror, so that
9981 we catch only errors and don't run the debugger. */
9982 internal_condition_case_1 (redisplay_window_1, selected_window,
9983 list_of_error,
9984 redisplay_window_error);
9985
9986 /* Compare desired and current matrices, perform output. */
9987
9988 update:
9989 /* If fonts changed, display again. */
9990 if (fonts_changed_p)
9991 goto retry;
9992
9993 /* Prevent various kinds of signals during display update.
9994 stdio is not robust about handling signals,
9995 which can cause an apparent I/O error. */
9996 if (interrupt_input)
9997 unrequest_sigio ();
9998 STOP_POLLING;
9999
10000 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10001 {
10002 if (hscroll_windows (selected_window))
10003 goto retry;
10004
10005 XWINDOW (selected_window)->must_be_updated_p = 1;
10006 pause = update_frame (sf, 0, 0);
10007 }
10008
10009 /* We may have called echo_area_display at the top of this
10010 function. If the echo area is on another frame, that may
10011 have put text on a frame other than the selected one, so the
10012 above call to update_frame would not have caught it. Catch
10013 it here. */
10014 mini_window = FRAME_MINIBUF_WINDOW (sf);
10015 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10016
10017 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10018 {
10019 XWINDOW (mini_window)->must_be_updated_p = 1;
10020 pause |= update_frame (mini_frame, 0, 0);
10021 if (!pause && hscroll_windows (mini_window))
10022 goto retry;
10023 }
10024 }
10025
10026 /* If display was paused because of pending input, make sure we do a
10027 thorough update the next time. */
10028 if (pause)
10029 {
10030 /* Prevent the optimization at the beginning of
10031 redisplay_internal that tries a single-line update of the
10032 line containing the cursor in the selected window. */
10033 CHARPOS (this_line_start_pos) = 0;
10034
10035 /* Let the overlay arrow be updated the next time. */
10036 if (!NILP (last_arrow_position))
10037 {
10038 last_arrow_position = Qt;
10039 last_arrow_string = Qt;
10040 }
10041
10042 /* If we pause after scrolling, some rows in the current
10043 matrices of some windows are not valid. */
10044 if (!WINDOW_FULL_WIDTH_P (w)
10045 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10046 update_mode_lines = 1;
10047 }
10048 else
10049 {
10050 if (!consider_all_windows_p)
10051 {
10052 /* This has already been done above if
10053 consider_all_windows_p is set. */
10054 mark_window_display_accurate_1 (w, 1);
10055
10056 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10057 last_arrow_string = Voverlay_arrow_string;
10058
10059 if (frame_up_to_date_hook != 0)
10060 frame_up_to_date_hook (sf);
10061 }
10062
10063 update_mode_lines = 0;
10064 windows_or_buffers_changed = 0;
10065 cursor_type_changed = 0;
10066 }
10067
10068 /* Start SIGIO interrupts coming again. Having them off during the
10069 code above makes it less likely one will discard output, but not
10070 impossible, since there might be stuff in the system buffer here.
10071 But it is much hairier to try to do anything about that. */
10072 if (interrupt_input)
10073 request_sigio ();
10074 RESUME_POLLING;
10075
10076 /* If a frame has become visible which was not before, redisplay
10077 again, so that we display it. Expose events for such a frame
10078 (which it gets when becoming visible) don't call the parts of
10079 redisplay constructing glyphs, so simply exposing a frame won't
10080 display anything in this case. So, we have to display these
10081 frames here explicitly. */
10082 if (!pause)
10083 {
10084 Lisp_Object tail, frame;
10085 int new_count = 0;
10086
10087 FOR_EACH_FRAME (tail, frame)
10088 {
10089 int this_is_visible = 0;
10090
10091 if (XFRAME (frame)->visible)
10092 this_is_visible = 1;
10093 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10094 if (XFRAME (frame)->visible)
10095 this_is_visible = 1;
10096
10097 if (this_is_visible)
10098 new_count++;
10099 }
10100
10101 if (new_count != number_of_visible_frames)
10102 windows_or_buffers_changed++;
10103 }
10104
10105 /* Change frame size now if a change is pending. */
10106 do_pending_window_change (1);
10107
10108 /* If we just did a pending size change, or have additional
10109 visible frames, redisplay again. */
10110 if (windows_or_buffers_changed && !pause)
10111 goto retry;
10112
10113 end_of_redisplay:
10114 unbind_to (count, Qnil);
10115 RESUME_POLLING;
10116 }
10117
10118
10119 /* Redisplay, but leave alone any recent echo area message unless
10120 another message has been requested in its place.
10121
10122 This is useful in situations where you need to redisplay but no
10123 user action has occurred, making it inappropriate for the message
10124 area to be cleared. See tracking_off and
10125 wait_reading_process_input for examples of these situations.
10126
10127 FROM_WHERE is an integer saying from where this function was
10128 called. This is useful for debugging. */
10129
10130 void
10131 redisplay_preserve_echo_area (from_where)
10132 int from_where;
10133 {
10134 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10135
10136 if (!NILP (echo_area_buffer[1]))
10137 {
10138 /* We have a previously displayed message, but no current
10139 message. Redisplay the previous message. */
10140 display_last_displayed_message_p = 1;
10141 redisplay_internal (1);
10142 display_last_displayed_message_p = 0;
10143 }
10144 else
10145 redisplay_internal (1);
10146 }
10147
10148
10149 /* Function registered with record_unwind_protect in
10150 redisplay_internal. Reset redisplaying_p to the value it had
10151 before redisplay_internal was called, and clear
10152 prevent_freeing_realized_faces_p. It also selects the previously
10153 selected frame. */
10154
10155 static Lisp_Object
10156 unwind_redisplay (val)
10157 Lisp_Object val;
10158 {
10159 Lisp_Object old_redisplaying_p, old_frame;
10160
10161 old_redisplaying_p = XCAR (val);
10162 redisplaying_p = XFASTINT (old_redisplaying_p);
10163 old_frame = XCDR (val);
10164 if (! EQ (old_frame, selected_frame))
10165 select_frame_for_redisplay (old_frame);
10166 return Qnil;
10167 }
10168
10169
10170 /* Mark the display of window W as accurate or inaccurate. If
10171 ACCURATE_P is non-zero mark display of W as accurate. If
10172 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10173 redisplay_internal is called. */
10174
10175 static void
10176 mark_window_display_accurate_1 (w, accurate_p)
10177 struct window *w;
10178 int accurate_p;
10179 {
10180 if (BUFFERP (w->buffer))
10181 {
10182 struct buffer *b = XBUFFER (w->buffer);
10183
10184 w->last_modified
10185 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10186 w->last_overlay_modified
10187 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10188 w->last_had_star
10189 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10190
10191 if (accurate_p)
10192 {
10193 b->clip_changed = 0;
10194 b->prevent_redisplay_optimizations_p = 0;
10195
10196 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10197 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10198 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10199 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10200
10201 w->current_matrix->buffer = b;
10202 w->current_matrix->begv = BUF_BEGV (b);
10203 w->current_matrix->zv = BUF_ZV (b);
10204
10205 w->last_cursor = w->cursor;
10206 w->last_cursor_off_p = w->cursor_off_p;
10207
10208 if (w == XWINDOW (selected_window))
10209 w->last_point = make_number (BUF_PT (b));
10210 else
10211 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10212 }
10213 }
10214
10215 if (accurate_p)
10216 {
10217 w->window_end_valid = w->buffer;
10218 #if 0 /* This is incorrect with variable-height lines. */
10219 xassert (XINT (w->window_end_vpos)
10220 < (WINDOW_TOTAL_LINES (w)
10221 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10222 #endif
10223 w->update_mode_line = Qnil;
10224 }
10225 }
10226
10227
10228 /* Mark the display of windows in the window tree rooted at WINDOW as
10229 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10230 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10231 be redisplayed the next time redisplay_internal is called. */
10232
10233 void
10234 mark_window_display_accurate (window, accurate_p)
10235 Lisp_Object window;
10236 int accurate_p;
10237 {
10238 struct window *w;
10239
10240 for (; !NILP (window); window = w->next)
10241 {
10242 w = XWINDOW (window);
10243 mark_window_display_accurate_1 (w, accurate_p);
10244
10245 if (!NILP (w->vchild))
10246 mark_window_display_accurate (w->vchild, accurate_p);
10247 if (!NILP (w->hchild))
10248 mark_window_display_accurate (w->hchild, accurate_p);
10249 }
10250
10251 if (accurate_p)
10252 {
10253 last_arrow_position = COERCE_MARKER (Voverlay_arrow_position);
10254 last_arrow_string = Voverlay_arrow_string;
10255 }
10256 else
10257 {
10258 /* Force a thorough redisplay the next time by setting
10259 last_arrow_position and last_arrow_string to t, which is
10260 unequal to any useful value of Voverlay_arrow_... */
10261 last_arrow_position = Qt;
10262 last_arrow_string = Qt;
10263 }
10264 }
10265
10266
10267 /* Return value in display table DP (Lisp_Char_Table *) for character
10268 C. Since a display table doesn't have any parent, we don't have to
10269 follow parent. Do not call this function directly but use the
10270 macro DISP_CHAR_VECTOR. */
10271
10272 Lisp_Object
10273 disp_char_vector (dp, c)
10274 struct Lisp_Char_Table *dp;
10275 int c;
10276 {
10277 int code[4], i;
10278 Lisp_Object val;
10279
10280 if (SINGLE_BYTE_CHAR_P (c))
10281 return (dp->contents[c]);
10282
10283 SPLIT_CHAR (c, code[0], code[1], code[2]);
10284 if (code[1] < 32)
10285 code[1] = -1;
10286 else if (code[2] < 32)
10287 code[2] = -1;
10288
10289 /* Here, the possible range of code[0] (== charset ID) is
10290 128..max_charset. Since the top level char table contains data
10291 for multibyte characters after 256th element, we must increment
10292 code[0] by 128 to get a correct index. */
10293 code[0] += 128;
10294 code[3] = -1; /* anchor */
10295
10296 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10297 {
10298 val = dp->contents[code[i]];
10299 if (!SUB_CHAR_TABLE_P (val))
10300 return (NILP (val) ? dp->defalt : val);
10301 }
10302
10303 /* Here, val is a sub char table. We return the default value of
10304 it. */
10305 return (dp->defalt);
10306 }
10307
10308
10309 \f
10310 /***********************************************************************
10311 Window Redisplay
10312 ***********************************************************************/
10313
10314 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10315
10316 static void
10317 redisplay_windows (window)
10318 Lisp_Object window;
10319 {
10320 while (!NILP (window))
10321 {
10322 struct window *w = XWINDOW (window);
10323
10324 if (!NILP (w->hchild))
10325 redisplay_windows (w->hchild);
10326 else if (!NILP (w->vchild))
10327 redisplay_windows (w->vchild);
10328 else
10329 {
10330 displayed_buffer = XBUFFER (w->buffer);
10331 /* Use list_of_error, not Qerror, so that
10332 we catch only errors and don't run the debugger. */
10333 internal_condition_case_1 (redisplay_window_0, window,
10334 list_of_error,
10335 redisplay_window_error);
10336 }
10337
10338 window = w->next;
10339 }
10340 }
10341
10342 static Lisp_Object
10343 redisplay_window_error ()
10344 {
10345 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10346 return Qnil;
10347 }
10348
10349 static Lisp_Object
10350 redisplay_window_0 (window)
10351 Lisp_Object window;
10352 {
10353 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10354 redisplay_window (window, 0);
10355 return Qnil;
10356 }
10357
10358 static Lisp_Object
10359 redisplay_window_1 (window)
10360 Lisp_Object window;
10361 {
10362 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10363 redisplay_window (window, 1);
10364 return Qnil;
10365 }
10366 \f
10367
10368 /* Increment GLYPH until it reaches END or CONDITION fails while
10369 adding (GLYPH)->pixel_width to X. */
10370
10371 #define SKIP_GLYPHS(glyph, end, x, condition) \
10372 do \
10373 { \
10374 (x) += (glyph)->pixel_width; \
10375 ++(glyph); \
10376 } \
10377 while ((glyph) < (end) && (condition))
10378
10379
10380 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10381 DELTA is the number of bytes by which positions recorded in ROW
10382 differ from current buffer positions. */
10383
10384 void
10385 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10386 struct window *w;
10387 struct glyph_row *row;
10388 struct glyph_matrix *matrix;
10389 int delta, delta_bytes, dy, dvpos;
10390 {
10391 struct glyph *glyph = row->glyphs[TEXT_AREA];
10392 struct glyph *end = glyph + row->used[TEXT_AREA];
10393 /* The first glyph that starts a sequence of glyphs from string. */
10394 struct glyph *string_start;
10395 /* The X coordinate of string_start. */
10396 int string_start_x;
10397 /* The last known character position. */
10398 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10399 /* The last known character position before string_start. */
10400 int string_before_pos;
10401 int x = row->x;
10402 int pt_old = PT - delta;
10403
10404 /* Skip over glyphs not having an object at the start of the row.
10405 These are special glyphs like truncation marks on terminal
10406 frames. */
10407 if (row->displays_text_p)
10408 while (glyph < end
10409 && INTEGERP (glyph->object)
10410 && glyph->charpos < 0)
10411 {
10412 x += glyph->pixel_width;
10413 ++glyph;
10414 }
10415
10416 string_start = NULL;
10417 while (glyph < end
10418 && !INTEGERP (glyph->object)
10419 && (!BUFFERP (glyph->object)
10420 || (last_pos = glyph->charpos) < pt_old))
10421 {
10422 if (! STRINGP (glyph->object))
10423 {
10424 string_start = NULL;
10425 x += glyph->pixel_width;
10426 ++glyph;
10427 }
10428 else
10429 {
10430 string_before_pos = last_pos;
10431 string_start = glyph;
10432 string_start_x = x;
10433 /* Skip all glyphs from string. */
10434 SKIP_GLYPHS (glyph, end, x, STRINGP (glyph->object));
10435 }
10436 }
10437
10438 if (string_start
10439 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10440 {
10441 /* We may have skipped over point because the previous glyphs
10442 are from string. As there's no easy way to know the
10443 character position of the current glyph, find the correct
10444 glyph on point by scanning from string_start again. */
10445 Lisp_Object limit;
10446 Lisp_Object string;
10447 int pos;
10448
10449 limit = make_number (pt_old + 1);
10450 end = glyph;
10451 glyph = string_start;
10452 x = string_start_x;
10453 string = glyph->object;
10454 pos = string_buffer_position (w, string, string_before_pos);
10455 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
10456 because we always put cursor after overlay strings. */
10457 while (pos == 0 && glyph < end)
10458 {
10459 string = glyph->object;
10460 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10461 if (glyph < end)
10462 pos = string_buffer_position (w, glyph->object, string_before_pos);
10463 }
10464
10465 while (glyph < end)
10466 {
10467 pos = XINT (Fnext_single_char_property_change
10468 (make_number (pos), Qdisplay, Qnil, limit));
10469 if (pos > pt_old)
10470 break;
10471 /* Skip glyphs from the same string. */
10472 string = glyph->object;
10473 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10474 /* Skip glyphs from an overlay. */
10475 while (glyph < end
10476 && ! string_buffer_position (w, glyph->object, pos))
10477 {
10478 string = glyph->object;
10479 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
10480 }
10481 }
10482 }
10483
10484 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
10485 w->cursor.x = x;
10486 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
10487 w->cursor.y = row->y + dy;
10488
10489 if (w == XWINDOW (selected_window))
10490 {
10491 if (!row->continued_p
10492 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
10493 && row->x == 0)
10494 {
10495 this_line_buffer = XBUFFER (w->buffer);
10496
10497 CHARPOS (this_line_start_pos)
10498 = MATRIX_ROW_START_CHARPOS (row) + delta;
10499 BYTEPOS (this_line_start_pos)
10500 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
10501
10502 CHARPOS (this_line_end_pos)
10503 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
10504 BYTEPOS (this_line_end_pos)
10505 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
10506
10507 this_line_y = w->cursor.y;
10508 this_line_pixel_height = row->height;
10509 this_line_vpos = w->cursor.vpos;
10510 this_line_start_x = row->x;
10511 }
10512 else
10513 CHARPOS (this_line_start_pos) = 0;
10514 }
10515 }
10516
10517
10518 /* Run window scroll functions, if any, for WINDOW with new window
10519 start STARTP. Sets the window start of WINDOW to that position.
10520
10521 We assume that the window's buffer is really current. */
10522
10523 static INLINE struct text_pos
10524 run_window_scroll_functions (window, startp)
10525 Lisp_Object window;
10526 struct text_pos startp;
10527 {
10528 struct window *w = XWINDOW (window);
10529 SET_MARKER_FROM_TEXT_POS (w->start, startp);
10530
10531 if (current_buffer != XBUFFER (w->buffer))
10532 abort ();
10533
10534 if (!NILP (Vwindow_scroll_functions))
10535 {
10536 run_hook_with_args_2 (Qwindow_scroll_functions, window,
10537 make_number (CHARPOS (startp)));
10538 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10539 /* In case the hook functions switch buffers. */
10540 if (current_buffer != XBUFFER (w->buffer))
10541 set_buffer_internal_1 (XBUFFER (w->buffer));
10542 }
10543
10544 return startp;
10545 }
10546
10547
10548 /* Make sure the line containing the cursor is fully visible.
10549 A value of 1 means there is nothing to be done.
10550 (Either the line is fully visible, or it cannot be made so,
10551 or we cannot tell.)
10552 A value of 0 means the caller should do scrolling
10553 as if point had gone off the screen. */
10554
10555 static int
10556 make_cursor_line_fully_visible (w)
10557 struct window *w;
10558 {
10559 struct glyph_matrix *matrix;
10560 struct glyph_row *row;
10561 int window_height;
10562
10563 /* It's not always possible to find the cursor, e.g, when a window
10564 is full of overlay strings. Don't do anything in that case. */
10565 if (w->cursor.vpos < 0)
10566 return 1;
10567
10568 matrix = w->desired_matrix;
10569 row = MATRIX_ROW (matrix, w->cursor.vpos);
10570
10571 /* If the cursor row is not partially visible, there's nothing to do. */
10572 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
10573 return 1;
10574
10575 /* If the row the cursor is in is taller than the window's height,
10576 it's not clear what to do, so do nothing. */
10577 window_height = window_box_height (w);
10578 if (row->height >= window_height)
10579 return 1;
10580
10581 return 0;
10582
10583 #if 0
10584 /* This code used to try to scroll the window just enough to make
10585 the line visible. It returned 0 to say that the caller should
10586 allocate larger glyph matrices. */
10587
10588 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
10589 {
10590 int dy = row->height - row->visible_height;
10591 w->vscroll = 0;
10592 w->cursor.y += dy;
10593 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10594 }
10595 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
10596 {
10597 int dy = - (row->height - row->visible_height);
10598 w->vscroll = dy;
10599 w->cursor.y += dy;
10600 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
10601 }
10602
10603 /* When we change the cursor y-position of the selected window,
10604 change this_line_y as well so that the display optimization for
10605 the cursor line of the selected window in redisplay_internal uses
10606 the correct y-position. */
10607 if (w == XWINDOW (selected_window))
10608 this_line_y = w->cursor.y;
10609
10610 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
10611 redisplay with larger matrices. */
10612 if (matrix->nrows < required_matrix_height (w))
10613 {
10614 fonts_changed_p = 1;
10615 return 0;
10616 }
10617
10618 return 1;
10619 #endif /* 0 */
10620 }
10621
10622
10623 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
10624 non-zero means only WINDOW is redisplayed in redisplay_internal.
10625 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
10626 in redisplay_window to bring a partially visible line into view in
10627 the case that only the cursor has moved.
10628
10629 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
10630 last screen line's vertical height extends past the end of the screen.
10631
10632 Value is
10633
10634 1 if scrolling succeeded
10635
10636 0 if scrolling didn't find point.
10637
10638 -1 if new fonts have been loaded so that we must interrupt
10639 redisplay, adjust glyph matrices, and try again. */
10640
10641 enum
10642 {
10643 SCROLLING_SUCCESS,
10644 SCROLLING_FAILED,
10645 SCROLLING_NEED_LARGER_MATRICES
10646 };
10647
10648 static int
10649 try_scrolling (window, just_this_one_p, scroll_conservatively,
10650 scroll_step, temp_scroll_step, last_line_misfit)
10651 Lisp_Object window;
10652 int just_this_one_p;
10653 EMACS_INT scroll_conservatively, scroll_step;
10654 int temp_scroll_step;
10655 int last_line_misfit;
10656 {
10657 struct window *w = XWINDOW (window);
10658 struct frame *f = XFRAME (w->frame);
10659 struct text_pos scroll_margin_pos;
10660 struct text_pos pos;
10661 struct text_pos startp;
10662 struct it it;
10663 Lisp_Object window_end;
10664 int this_scroll_margin;
10665 int dy = 0;
10666 int scroll_max;
10667 int rc;
10668 int amount_to_scroll = 0;
10669 Lisp_Object aggressive;
10670 int height;
10671 int end_scroll_margin;
10672
10673 #if GLYPH_DEBUG
10674 debug_method_add (w, "try_scrolling");
10675 #endif
10676
10677 SET_TEXT_POS_FROM_MARKER (startp, w->start);
10678
10679 /* Compute scroll margin height in pixels. We scroll when point is
10680 within this distance from the top or bottom of the window. */
10681 if (scroll_margin > 0)
10682 {
10683 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
10684 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
10685 }
10686 else
10687 this_scroll_margin = 0;
10688
10689 /* Compute how much we should try to scroll maximally to bring point
10690 into view. */
10691 if (scroll_step || scroll_conservatively || temp_scroll_step)
10692 scroll_max = max (scroll_step,
10693 max (scroll_conservatively, temp_scroll_step));
10694 else if (NUMBERP (current_buffer->scroll_down_aggressively)
10695 || NUMBERP (current_buffer->scroll_up_aggressively))
10696 /* We're trying to scroll because of aggressive scrolling
10697 but no scroll_step is set. Choose an arbitrary one. Maybe
10698 there should be a variable for this. */
10699 scroll_max = 10;
10700 else
10701 scroll_max = 0;
10702 scroll_max *= FRAME_LINE_HEIGHT (f);
10703
10704 /* Decide whether we have to scroll down. Start at the window end
10705 and move this_scroll_margin up to find the position of the scroll
10706 margin. */
10707 window_end = Fwindow_end (window, Qt);
10708
10709 too_near_end:
10710
10711 CHARPOS (scroll_margin_pos) = XINT (window_end);
10712 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
10713
10714 end_scroll_margin = this_scroll_margin + !!last_line_misfit;
10715 if (end_scroll_margin)
10716 {
10717 start_display (&it, w, scroll_margin_pos);
10718 move_it_vertically (&it, - end_scroll_margin);
10719 scroll_margin_pos = it.current.pos;
10720 }
10721
10722 if (PT >= CHARPOS (scroll_margin_pos))
10723 {
10724 int y0;
10725
10726 /* Point is in the scroll margin at the bottom of the window, or
10727 below. Compute a new window start that makes point visible. */
10728
10729 /* Compute the distance from the scroll margin to PT.
10730 Give up if the distance is greater than scroll_max. */
10731 start_display (&it, w, scroll_margin_pos);
10732 y0 = it.current_y;
10733 move_it_to (&it, PT, 0, it.last_visible_y, -1,
10734 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10735
10736 /* To make point visible, we have to move the window start
10737 down so that the line the cursor is in is visible, which
10738 means we have to add in the height of the cursor line. */
10739 dy = line_bottom_y (&it) - y0;
10740
10741 if (dy > scroll_max)
10742 return SCROLLING_FAILED;
10743
10744 /* Move the window start down. If scrolling conservatively,
10745 move it just enough down to make point visible. If
10746 scroll_step is set, move it down by scroll_step. */
10747 start_display (&it, w, startp);
10748
10749 if (scroll_conservatively)
10750 /* Set AMOUNT_TO_SCROLL to at least one line,
10751 and at most scroll_conservatively lines. */
10752 amount_to_scroll
10753 = min (max (dy, FRAME_LINE_HEIGHT (f)),
10754 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
10755 else if (scroll_step || temp_scroll_step)
10756 amount_to_scroll = scroll_max;
10757 else
10758 {
10759 aggressive = current_buffer->scroll_up_aggressively;
10760 height = WINDOW_BOX_TEXT_HEIGHT (w);
10761 if (NUMBERP (aggressive))
10762 amount_to_scroll = XFLOATINT (aggressive) * height;
10763 }
10764
10765 if (amount_to_scroll <= 0)
10766 return SCROLLING_FAILED;
10767
10768 /* If moving by amount_to_scroll leaves STARTP unchanged,
10769 move it down one screen line. */
10770
10771 move_it_vertically (&it, amount_to_scroll);
10772 if (CHARPOS (it.current.pos) == CHARPOS (startp))
10773 move_it_by_lines (&it, 1, 1);
10774 startp = it.current.pos;
10775 }
10776 else
10777 {
10778 /* See if point is inside the scroll margin at the top of the
10779 window. */
10780 scroll_margin_pos = startp;
10781 if (this_scroll_margin)
10782 {
10783 start_display (&it, w, startp);
10784 move_it_vertically (&it, this_scroll_margin);
10785 scroll_margin_pos = it.current.pos;
10786 }
10787
10788 if (PT < CHARPOS (scroll_margin_pos))
10789 {
10790 /* Point is in the scroll margin at the top of the window or
10791 above what is displayed in the window. */
10792 int y0;
10793
10794 /* Compute the vertical distance from PT to the scroll
10795 margin position. Give up if distance is greater than
10796 scroll_max. */
10797 SET_TEXT_POS (pos, PT, PT_BYTE);
10798 start_display (&it, w, pos);
10799 y0 = it.current_y;
10800 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
10801 it.last_visible_y, -1,
10802 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
10803 dy = it.current_y - y0;
10804 if (dy > scroll_max)
10805 return SCROLLING_FAILED;
10806
10807 /* Compute new window start. */
10808 start_display (&it, w, startp);
10809
10810 if (scroll_conservatively)
10811 amount_to_scroll =
10812 max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
10813 else if (scroll_step || temp_scroll_step)
10814 amount_to_scroll = scroll_max;
10815 else
10816 {
10817 aggressive = current_buffer->scroll_down_aggressively;
10818 height = WINDOW_BOX_TEXT_HEIGHT (w);
10819 if (NUMBERP (aggressive))
10820 amount_to_scroll = XFLOATINT (aggressive) * height;
10821 }
10822
10823 if (amount_to_scroll <= 0)
10824 return SCROLLING_FAILED;
10825
10826 move_it_vertically (&it, - amount_to_scroll);
10827 startp = it.current.pos;
10828 }
10829 }
10830
10831 /* Run window scroll functions. */
10832 startp = run_window_scroll_functions (window, startp);
10833
10834 /* Display the window. Give up if new fonts are loaded, or if point
10835 doesn't appear. */
10836 if (!try_window (window, startp))
10837 rc = SCROLLING_NEED_LARGER_MATRICES;
10838 else if (w->cursor.vpos < 0)
10839 {
10840 clear_glyph_matrix (w->desired_matrix);
10841 rc = SCROLLING_FAILED;
10842 }
10843 else
10844 {
10845 /* Maybe forget recorded base line for line number display. */
10846 if (!just_this_one_p
10847 || current_buffer->clip_changed
10848 || BEG_UNCHANGED < CHARPOS (startp))
10849 w->base_line_number = Qnil;
10850
10851 /* If cursor ends up on a partially visible line,
10852 treat that as being off the bottom of the screen. */
10853 if (! make_cursor_line_fully_visible (w))
10854 {
10855 clear_glyph_matrix (w->desired_matrix);
10856 last_line_misfit = 1;
10857 goto too_near_end;
10858 }
10859 rc = SCROLLING_SUCCESS;
10860 }
10861
10862 return rc;
10863 }
10864
10865
10866 /* Compute a suitable window start for window W if display of W starts
10867 on a continuation line. Value is non-zero if a new window start
10868 was computed.
10869
10870 The new window start will be computed, based on W's width, starting
10871 from the start of the continued line. It is the start of the
10872 screen line with the minimum distance from the old start W->start. */
10873
10874 static int
10875 compute_window_start_on_continuation_line (w)
10876 struct window *w;
10877 {
10878 struct text_pos pos, start_pos;
10879 int window_start_changed_p = 0;
10880
10881 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
10882
10883 /* If window start is on a continuation line... Window start may be
10884 < BEGV in case there's invisible text at the start of the
10885 buffer (M-x rmail, for example). */
10886 if (CHARPOS (start_pos) > BEGV
10887 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
10888 {
10889 struct it it;
10890 struct glyph_row *row;
10891
10892 /* Handle the case that the window start is out of range. */
10893 if (CHARPOS (start_pos) < BEGV)
10894 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
10895 else if (CHARPOS (start_pos) > ZV)
10896 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
10897
10898 /* Find the start of the continued line. This should be fast
10899 because scan_buffer is fast (newline cache). */
10900 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
10901 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
10902 row, DEFAULT_FACE_ID);
10903 reseat_at_previous_visible_line_start (&it);
10904
10905 /* If the line start is "too far" away from the window start,
10906 say it takes too much time to compute a new window start. */
10907 if (CHARPOS (start_pos) - IT_CHARPOS (it)
10908 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
10909 {
10910 int min_distance, distance;
10911
10912 /* Move forward by display lines to find the new window
10913 start. If window width was enlarged, the new start can
10914 be expected to be > the old start. If window width was
10915 decreased, the new window start will be < the old start.
10916 So, we're looking for the display line start with the
10917 minimum distance from the old window start. */
10918 pos = it.current.pos;
10919 min_distance = INFINITY;
10920 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
10921 distance < min_distance)
10922 {
10923 min_distance = distance;
10924 pos = it.current.pos;
10925 move_it_by_lines (&it, 1, 0);
10926 }
10927
10928 /* Set the window start there. */
10929 SET_MARKER_FROM_TEXT_POS (w->start, pos);
10930 window_start_changed_p = 1;
10931 }
10932 }
10933
10934 return window_start_changed_p;
10935 }
10936
10937
10938 /* Try cursor movement in case text has not changed in window WINDOW,
10939 with window start STARTP. Value is
10940
10941 CURSOR_MOVEMENT_SUCCESS if successful
10942
10943 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
10944
10945 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
10946 display. *SCROLL_STEP is set to 1, under certain circumstances, if
10947 we want to scroll as if scroll-step were set to 1. See the code.
10948
10949 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
10950 which case we have to abort this redisplay, and adjust matrices
10951 first. */
10952
10953 enum
10954 {
10955 CURSOR_MOVEMENT_SUCCESS,
10956 CURSOR_MOVEMENT_CANNOT_BE_USED,
10957 CURSOR_MOVEMENT_MUST_SCROLL,
10958 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
10959 };
10960
10961 static int
10962 try_cursor_movement (window, startp, scroll_step)
10963 Lisp_Object window;
10964 struct text_pos startp;
10965 int *scroll_step;
10966 {
10967 struct window *w = XWINDOW (window);
10968 struct frame *f = XFRAME (w->frame);
10969 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
10970
10971 #if GLYPH_DEBUG
10972 if (inhibit_try_cursor_movement)
10973 return rc;
10974 #endif
10975
10976 /* Handle case where text has not changed, only point, and it has
10977 not moved off the frame. */
10978 if (/* Point may be in this window. */
10979 PT >= CHARPOS (startp)
10980 /* Selective display hasn't changed. */
10981 && !current_buffer->clip_changed
10982 /* Function force-mode-line-update is used to force a thorough
10983 redisplay. It sets either windows_or_buffers_changed or
10984 update_mode_lines. So don't take a shortcut here for these
10985 cases. */
10986 && !update_mode_lines
10987 && !windows_or_buffers_changed
10988 && !cursor_type_changed
10989 /* Can't use this case if highlighting a region. When a
10990 region exists, cursor movement has to do more than just
10991 set the cursor. */
10992 && !(!NILP (Vtransient_mark_mode)
10993 && !NILP (current_buffer->mark_active))
10994 && NILP (w->region_showing)
10995 && NILP (Vshow_trailing_whitespace)
10996 /* Right after splitting windows, last_point may be nil. */
10997 && INTEGERP (w->last_point)
10998 /* This code is not used for mini-buffer for the sake of the case
10999 of redisplaying to replace an echo area message; since in
11000 that case the mini-buffer contents per se are usually
11001 unchanged. This code is of no real use in the mini-buffer
11002 since the handling of this_line_start_pos, etc., in redisplay
11003 handles the same cases. */
11004 && !EQ (window, minibuf_window)
11005 /* When splitting windows or for new windows, it happens that
11006 redisplay is called with a nil window_end_vpos or one being
11007 larger than the window. This should really be fixed in
11008 window.c. I don't have this on my list, now, so we do
11009 approximately the same as the old redisplay code. --gerd. */
11010 && INTEGERP (w->window_end_vpos)
11011 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11012 && (FRAME_WINDOW_P (f)
11013 || !MARKERP (Voverlay_arrow_position)
11014 || current_buffer != XMARKER (Voverlay_arrow_position)->buffer))
11015 {
11016 int this_scroll_margin;
11017 struct glyph_row *row = NULL;
11018
11019 #if GLYPH_DEBUG
11020 debug_method_add (w, "cursor movement");
11021 #endif
11022
11023 /* Scroll if point within this distance from the top or bottom
11024 of the window. This is a pixel value. */
11025 this_scroll_margin = max (0, scroll_margin);
11026 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11027 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11028
11029 /* Start with the row the cursor was displayed during the last
11030 not paused redisplay. Give up if that row is not valid. */
11031 if (w->last_cursor.vpos < 0
11032 || w->last_cursor.vpos >= w->current_matrix->nrows)
11033 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11034 else
11035 {
11036 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11037 if (row->mode_line_p)
11038 ++row;
11039 if (!row->enabled_p)
11040 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11041 }
11042
11043 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11044 {
11045 int scroll_p = 0;
11046 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11047
11048 if (PT > XFASTINT (w->last_point))
11049 {
11050 /* Point has moved forward. */
11051 while (MATRIX_ROW_END_CHARPOS (row) < PT
11052 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11053 {
11054 xassert (row->enabled_p);
11055 ++row;
11056 }
11057
11058 /* The end position of a row equals the start position
11059 of the next row. If PT is there, we would rather
11060 display it in the next line. */
11061 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11062 && MATRIX_ROW_END_CHARPOS (row) == PT
11063 && !cursor_row_p (w, row))
11064 ++row;
11065
11066 /* If within the scroll margin, scroll. Note that
11067 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11068 the next line would be drawn, and that
11069 this_scroll_margin can be zero. */
11070 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11071 || PT > MATRIX_ROW_END_CHARPOS (row)
11072 /* Line is completely visible last line in window
11073 and PT is to be set in the next line. */
11074 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11075 && PT == MATRIX_ROW_END_CHARPOS (row)
11076 && !row->ends_at_zv_p
11077 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11078 scroll_p = 1;
11079 }
11080 else if (PT < XFASTINT (w->last_point))
11081 {
11082 /* Cursor has to be moved backward. Note that PT >=
11083 CHARPOS (startp) because of the outer
11084 if-statement. */
11085 while (!row->mode_line_p
11086 && (MATRIX_ROW_START_CHARPOS (row) > PT
11087 || (MATRIX_ROW_START_CHARPOS (row) == PT
11088 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11089 && (row->y > this_scroll_margin
11090 || CHARPOS (startp) == BEGV))
11091 {
11092 xassert (row->enabled_p);
11093 --row;
11094 }
11095
11096 /* Consider the following case: Window starts at BEGV,
11097 there is invisible, intangible text at BEGV, so that
11098 display starts at some point START > BEGV. It can
11099 happen that we are called with PT somewhere between
11100 BEGV and START. Try to handle that case. */
11101 if (row < w->current_matrix->rows
11102 || row->mode_line_p)
11103 {
11104 row = w->current_matrix->rows;
11105 if (row->mode_line_p)
11106 ++row;
11107 }
11108
11109 /* Due to newlines in overlay strings, we may have to
11110 skip forward over overlay strings. */
11111 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11112 && MATRIX_ROW_END_CHARPOS (row) == PT
11113 && !cursor_row_p (w, row))
11114 ++row;
11115
11116 /* If within the scroll margin, scroll. */
11117 if (row->y < this_scroll_margin
11118 && CHARPOS (startp) != BEGV)
11119 scroll_p = 1;
11120 }
11121
11122 if (PT < MATRIX_ROW_START_CHARPOS (row)
11123 || PT > MATRIX_ROW_END_CHARPOS (row))
11124 {
11125 /* if PT is not in the glyph row, give up. */
11126 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11127 }
11128 else if (MATRIX_ROW_PARTIALLY_VISIBLE_P (row))
11129 {
11130 if (PT == MATRIX_ROW_END_CHARPOS (row)
11131 && !row->ends_at_zv_p
11132 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11133 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11134 else if (row->height > window_box_height (w))
11135 {
11136 /* If we end up in a partially visible line, let's
11137 make it fully visible, except when it's taller
11138 than the window, in which case we can't do much
11139 about it. */
11140 *scroll_step = 1;
11141 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11142 }
11143 else
11144 {
11145 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11146 if (!make_cursor_line_fully_visible (w))
11147 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11148 else
11149 rc = CURSOR_MOVEMENT_SUCCESS;
11150 }
11151 }
11152 else if (scroll_p)
11153 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11154 else
11155 {
11156 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11157 rc = CURSOR_MOVEMENT_SUCCESS;
11158 }
11159 }
11160 }
11161
11162 return rc;
11163 }
11164
11165 void
11166 set_vertical_scroll_bar (w)
11167 struct window *w;
11168 {
11169 int start, end, whole;
11170
11171 /* Calculate the start and end positions for the current window.
11172 At some point, it would be nice to choose between scrollbars
11173 which reflect the whole buffer size, with special markers
11174 indicating narrowing, and scrollbars which reflect only the
11175 visible region.
11176
11177 Note that mini-buffers sometimes aren't displaying any text. */
11178 if (!MINI_WINDOW_P (w)
11179 || (w == XWINDOW (minibuf_window)
11180 && NILP (echo_area_buffer[0])))
11181 {
11182 struct buffer *buf = XBUFFER (w->buffer);
11183 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11184 start = marker_position (w->start) - BUF_BEGV (buf);
11185 /* I don't think this is guaranteed to be right. For the
11186 moment, we'll pretend it is. */
11187 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11188
11189 if (end < start)
11190 end = start;
11191 if (whole < (end - start))
11192 whole = end - start;
11193 }
11194 else
11195 start = end = whole = 0;
11196
11197 /* Indicate what this scroll bar ought to be displaying now. */
11198 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11199 }
11200
11201
11202 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11203 selected_window is redisplayed.
11204
11205 We can return without actually redisplaying the window if
11206 fonts_changed_p is nonzero. In that case, redisplay_internal will
11207 retry. */
11208
11209 static void
11210 redisplay_window (window, just_this_one_p)
11211 Lisp_Object window;
11212 int just_this_one_p;
11213 {
11214 struct window *w = XWINDOW (window);
11215 struct frame *f = XFRAME (w->frame);
11216 struct buffer *buffer = XBUFFER (w->buffer);
11217 struct buffer *old = current_buffer;
11218 struct text_pos lpoint, opoint, startp;
11219 int update_mode_line;
11220 int tem;
11221 struct it it;
11222 /* Record it now because it's overwritten. */
11223 int current_matrix_up_to_date_p = 0;
11224 int used_current_matrix_p = 0;
11225 /* This is less strict than current_matrix_up_to_date_p.
11226 It indictes that the buffer contents and narrowing are unchanged. */
11227 int buffer_unchanged_p = 0;
11228 int temp_scroll_step = 0;
11229 int count = SPECPDL_INDEX ();
11230 int rc;
11231 int centering_position;
11232 int last_line_misfit = 0;
11233
11234 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11235 opoint = lpoint;
11236
11237 /* W must be a leaf window here. */
11238 xassert (!NILP (w->buffer));
11239 #if GLYPH_DEBUG
11240 *w->desired_matrix->method = 0;
11241 #endif
11242
11243 specbind (Qinhibit_point_motion_hooks, Qt);
11244
11245 reconsider_clip_changes (w, buffer);
11246
11247 /* Has the mode line to be updated? */
11248 update_mode_line = (!NILP (w->update_mode_line)
11249 || update_mode_lines
11250 || buffer->clip_changed
11251 || buffer->prevent_redisplay_optimizations_p);
11252
11253 if (MINI_WINDOW_P (w))
11254 {
11255 if (w == XWINDOW (echo_area_window)
11256 && !NILP (echo_area_buffer[0]))
11257 {
11258 if (update_mode_line)
11259 /* We may have to update a tty frame's menu bar or a
11260 tool-bar. Example `M-x C-h C-h C-g'. */
11261 goto finish_menu_bars;
11262 else
11263 /* We've already displayed the echo area glyphs in this window. */
11264 goto finish_scroll_bars;
11265 }
11266 else if ((w != XWINDOW (minibuf_window)
11267 || minibuf_level == 0)
11268 /* When buffer is nonempty, redisplay window normally. */
11269 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11270 /* Quail displays non-mini buffers in minibuffer window.
11271 In that case, redisplay the window normally. */
11272 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11273 {
11274 /* W is a mini-buffer window, but it's not active, so clear
11275 it. */
11276 int yb = window_text_bottom_y (w);
11277 struct glyph_row *row;
11278 int y;
11279
11280 for (y = 0, row = w->desired_matrix->rows;
11281 y < yb;
11282 y += row->height, ++row)
11283 blank_row (w, row, y);
11284 goto finish_scroll_bars;
11285 }
11286
11287 clear_glyph_matrix (w->desired_matrix);
11288 }
11289
11290 /* Otherwise set up data on this window; select its buffer and point
11291 value. */
11292 /* Really select the buffer, for the sake of buffer-local
11293 variables. */
11294 set_buffer_internal_1 (XBUFFER (w->buffer));
11295 SET_TEXT_POS (opoint, PT, PT_BYTE);
11296
11297 current_matrix_up_to_date_p
11298 = (!NILP (w->window_end_valid)
11299 && !current_buffer->clip_changed
11300 && !current_buffer->prevent_redisplay_optimizations_p
11301 && XFASTINT (w->last_modified) >= MODIFF
11302 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11303
11304 buffer_unchanged_p
11305 = (!NILP (w->window_end_valid)
11306 && !current_buffer->clip_changed
11307 && XFASTINT (w->last_modified) >= MODIFF
11308 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11309
11310 /* When windows_or_buffers_changed is non-zero, we can't rely on
11311 the window end being valid, so set it to nil there. */
11312 if (windows_or_buffers_changed)
11313 {
11314 /* If window starts on a continuation line, maybe adjust the
11315 window start in case the window's width changed. */
11316 if (XMARKER (w->start)->buffer == current_buffer)
11317 compute_window_start_on_continuation_line (w);
11318
11319 w->window_end_valid = Qnil;
11320 }
11321
11322 /* Some sanity checks. */
11323 CHECK_WINDOW_END (w);
11324 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11325 abort ();
11326 if (BYTEPOS (opoint) < CHARPOS (opoint))
11327 abort ();
11328
11329 /* If %c is in mode line, update it if needed. */
11330 if (!NILP (w->column_number_displayed)
11331 /* This alternative quickly identifies a common case
11332 where no change is needed. */
11333 && !(PT == XFASTINT (w->last_point)
11334 && XFASTINT (w->last_modified) >= MODIFF
11335 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11336 && (XFASTINT (w->column_number_displayed)
11337 != (int) current_column ())) /* iftc */
11338 update_mode_line = 1;
11339
11340 /* Count number of windows showing the selected buffer. An indirect
11341 buffer counts as its base buffer. */
11342 if (!just_this_one_p)
11343 {
11344 struct buffer *current_base, *window_base;
11345 current_base = current_buffer;
11346 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11347 if (current_base->base_buffer)
11348 current_base = current_base->base_buffer;
11349 if (window_base->base_buffer)
11350 window_base = window_base->base_buffer;
11351 if (current_base == window_base)
11352 buffer_shared++;
11353 }
11354
11355 /* Point refers normally to the selected window. For any other
11356 window, set up appropriate value. */
11357 if (!EQ (window, selected_window))
11358 {
11359 int new_pt = XMARKER (w->pointm)->charpos;
11360 int new_pt_byte = marker_byte_position (w->pointm);
11361 if (new_pt < BEGV)
11362 {
11363 new_pt = BEGV;
11364 new_pt_byte = BEGV_BYTE;
11365 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11366 }
11367 else if (new_pt > (ZV - 1))
11368 {
11369 new_pt = ZV;
11370 new_pt_byte = ZV_BYTE;
11371 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11372 }
11373
11374 /* We don't use SET_PT so that the point-motion hooks don't run. */
11375 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11376 }
11377
11378 /* If any of the character widths specified in the display table
11379 have changed, invalidate the width run cache. It's true that
11380 this may be a bit late to catch such changes, but the rest of
11381 redisplay goes (non-fatally) haywire when the display table is
11382 changed, so why should we worry about doing any better? */
11383 if (current_buffer->width_run_cache)
11384 {
11385 struct Lisp_Char_Table *disptab = buffer_display_table ();
11386
11387 if (! disptab_matches_widthtab (disptab,
11388 XVECTOR (current_buffer->width_table)))
11389 {
11390 invalidate_region_cache (current_buffer,
11391 current_buffer->width_run_cache,
11392 BEG, Z);
11393 recompute_width_table (current_buffer, disptab);
11394 }
11395 }
11396
11397 /* If window-start is screwed up, choose a new one. */
11398 if (XMARKER (w->start)->buffer != current_buffer)
11399 goto recenter;
11400
11401 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11402
11403 /* If someone specified a new starting point but did not insist,
11404 check whether it can be used. */
11405 if (!NILP (w->optional_new_start)
11406 && CHARPOS (startp) >= BEGV
11407 && CHARPOS (startp) <= ZV)
11408 {
11409 w->optional_new_start = Qnil;
11410 start_display (&it, w, startp);
11411 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11412 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11413 if (IT_CHARPOS (it) == PT)
11414 w->force_start = Qt;
11415 /* IT may overshoot PT if text at PT is invisible. */
11416 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
11417 w->force_start = Qt;
11418
11419
11420 }
11421
11422 /* Handle case where place to start displaying has been specified,
11423 unless the specified location is outside the accessible range. */
11424 if (!NILP (w->force_start)
11425 || w->frozen_window_start_p)
11426 {
11427 /* We set this later on if we have to adjust point. */
11428 int new_vpos = -1;
11429
11430 w->force_start = Qnil;
11431 w->vscroll = 0;
11432 w->window_end_valid = Qnil;
11433
11434 /* Forget any recorded base line for line number display. */
11435 if (!buffer_unchanged_p)
11436 w->base_line_number = Qnil;
11437
11438 /* Redisplay the mode line. Select the buffer properly for that.
11439 Also, run the hook window-scroll-functions
11440 because we have scrolled. */
11441 /* Note, we do this after clearing force_start because
11442 if there's an error, it is better to forget about force_start
11443 than to get into an infinite loop calling the hook functions
11444 and having them get more errors. */
11445 if (!update_mode_line
11446 || ! NILP (Vwindow_scroll_functions))
11447 {
11448 update_mode_line = 1;
11449 w->update_mode_line = Qt;
11450 startp = run_window_scroll_functions (window, startp);
11451 }
11452
11453 w->last_modified = make_number (0);
11454 w->last_overlay_modified = make_number (0);
11455 if (CHARPOS (startp) < BEGV)
11456 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
11457 else if (CHARPOS (startp) > ZV)
11458 SET_TEXT_POS (startp, ZV, ZV_BYTE);
11459
11460 /* Redisplay, then check if cursor has been set during the
11461 redisplay. Give up if new fonts were loaded. */
11462 if (!try_window (window, startp))
11463 {
11464 w->force_start = Qt;
11465 clear_glyph_matrix (w->desired_matrix);
11466 goto need_larger_matrices;
11467 }
11468
11469 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
11470 {
11471 /* If point does not appear, try to move point so it does
11472 appear. The desired matrix has been built above, so we
11473 can use it here. */
11474 new_vpos = window_box_height (w) / 2;
11475 }
11476
11477 if (!make_cursor_line_fully_visible (w))
11478 {
11479 /* Point does appear, but on a line partly visible at end of window.
11480 Move it back to a fully-visible line. */
11481 new_vpos = window_box_height (w);
11482 }
11483
11484 /* If we need to move point for either of the above reasons,
11485 now actually do it. */
11486 if (new_vpos >= 0)
11487 {
11488 struct glyph_row *row;
11489
11490 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
11491 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
11492 ++row;
11493
11494 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
11495 MATRIX_ROW_START_BYTEPOS (row));
11496
11497 if (w != XWINDOW (selected_window))
11498 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
11499 else if (current_buffer == old)
11500 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11501
11502 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
11503
11504 /* If we are highlighting the region, then we just changed
11505 the region, so redisplay to show it. */
11506 if (!NILP (Vtransient_mark_mode)
11507 && !NILP (current_buffer->mark_active))
11508 {
11509 clear_glyph_matrix (w->desired_matrix);
11510 if (!try_window (window, startp))
11511 goto need_larger_matrices;
11512 }
11513 }
11514
11515 #if GLYPH_DEBUG
11516 debug_method_add (w, "forced window start");
11517 #endif
11518 goto done;
11519 }
11520
11521 /* Handle case where text has not changed, only point, and it has
11522 not moved off the frame, and we are not retrying after hscroll.
11523 (current_matrix_up_to_date_p is nonzero when retrying.) */
11524 if (current_matrix_up_to_date_p
11525 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
11526 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
11527 {
11528 switch (rc)
11529 {
11530 case CURSOR_MOVEMENT_SUCCESS:
11531 used_current_matrix_p = 1;
11532 goto done;
11533
11534 #if 0 /* try_cursor_movement never returns this value. */
11535 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
11536 goto need_larger_matrices;
11537 #endif
11538
11539 case CURSOR_MOVEMENT_MUST_SCROLL:
11540 goto try_to_scroll;
11541
11542 default:
11543 abort ();
11544 }
11545 }
11546 /* If current starting point was originally the beginning of a line
11547 but no longer is, find a new starting point. */
11548 else if (!NILP (w->start_at_line_beg)
11549 && !(CHARPOS (startp) <= BEGV
11550 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
11551 {
11552 #if GLYPH_DEBUG
11553 debug_method_add (w, "recenter 1");
11554 #endif
11555 goto recenter;
11556 }
11557
11558 /* Try scrolling with try_window_id. Value is > 0 if update has
11559 been done, it is -1 if we know that the same window start will
11560 not work. It is 0 if unsuccessful for some other reason. */
11561 else if ((tem = try_window_id (w)) != 0)
11562 {
11563 #if GLYPH_DEBUG
11564 debug_method_add (w, "try_window_id %d", tem);
11565 #endif
11566
11567 if (fonts_changed_p)
11568 goto need_larger_matrices;
11569 if (tem > 0)
11570 goto done;
11571
11572 /* Otherwise try_window_id has returned -1 which means that we
11573 don't want the alternative below this comment to execute. */
11574 }
11575 else if (CHARPOS (startp) >= BEGV
11576 && CHARPOS (startp) <= ZV
11577 && PT >= CHARPOS (startp)
11578 && (CHARPOS (startp) < ZV
11579 /* Avoid starting at end of buffer. */
11580 || CHARPOS (startp) == BEGV
11581 || (XFASTINT (w->last_modified) >= MODIFF
11582 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
11583 {
11584 #if GLYPH_DEBUG
11585 debug_method_add (w, "same window start");
11586 #endif
11587
11588 /* Try to redisplay starting at same place as before.
11589 If point has not moved off frame, accept the results. */
11590 if (!current_matrix_up_to_date_p
11591 /* Don't use try_window_reusing_current_matrix in this case
11592 because a window scroll function can have changed the
11593 buffer. */
11594 || !NILP (Vwindow_scroll_functions)
11595 || MINI_WINDOW_P (w)
11596 || !(used_current_matrix_p =
11597 try_window_reusing_current_matrix (w)))
11598 {
11599 IF_DEBUG (debug_method_add (w, "1"));
11600 try_window (window, startp);
11601 }
11602
11603 if (fonts_changed_p)
11604 goto need_larger_matrices;
11605
11606 if (w->cursor.vpos >= 0)
11607 {
11608 if (!just_this_one_p
11609 || current_buffer->clip_changed
11610 || BEG_UNCHANGED < CHARPOS (startp))
11611 /* Forget any recorded base line for line number display. */
11612 w->base_line_number = Qnil;
11613
11614 if (!make_cursor_line_fully_visible (w))
11615 {
11616 clear_glyph_matrix (w->desired_matrix);
11617 last_line_misfit = 1;
11618 }
11619 /* Drop through and scroll. */
11620 else
11621 goto done;
11622 }
11623 else
11624 clear_glyph_matrix (w->desired_matrix);
11625 }
11626
11627 try_to_scroll:
11628
11629 w->last_modified = make_number (0);
11630 w->last_overlay_modified = make_number (0);
11631
11632 /* Redisplay the mode line. Select the buffer properly for that. */
11633 if (!update_mode_line)
11634 {
11635 update_mode_line = 1;
11636 w->update_mode_line = Qt;
11637 }
11638
11639 /* Try to scroll by specified few lines. */
11640 if ((scroll_conservatively
11641 || scroll_step
11642 || temp_scroll_step
11643 || NUMBERP (current_buffer->scroll_up_aggressively)
11644 || NUMBERP (current_buffer->scroll_down_aggressively))
11645 && !current_buffer->clip_changed
11646 && CHARPOS (startp) >= BEGV
11647 && CHARPOS (startp) <= ZV)
11648 {
11649 /* The function returns -1 if new fonts were loaded, 1 if
11650 successful, 0 if not successful. */
11651 int rc = try_scrolling (window, just_this_one_p,
11652 scroll_conservatively,
11653 scroll_step,
11654 temp_scroll_step, last_line_misfit);
11655 switch (rc)
11656 {
11657 case SCROLLING_SUCCESS:
11658 goto done;
11659
11660 case SCROLLING_NEED_LARGER_MATRICES:
11661 goto need_larger_matrices;
11662
11663 case SCROLLING_FAILED:
11664 break;
11665
11666 default:
11667 abort ();
11668 }
11669 }
11670
11671 /* Finally, just choose place to start which centers point */
11672
11673 recenter:
11674 centering_position = window_box_height (w) / 2;
11675
11676 point_at_top:
11677 /* Jump here with centering_position already set to 0. */
11678
11679 #if GLYPH_DEBUG
11680 debug_method_add (w, "recenter");
11681 #endif
11682
11683 /* w->vscroll = 0; */
11684
11685 /* Forget any previously recorded base line for line number display. */
11686 if (!buffer_unchanged_p)
11687 w->base_line_number = Qnil;
11688
11689 /* Move backward half the height of the window. */
11690 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11691 it.current_y = it.last_visible_y;
11692 move_it_vertically_backward (&it, centering_position);
11693 xassert (IT_CHARPOS (it) >= BEGV);
11694
11695 /* The function move_it_vertically_backward may move over more
11696 than the specified y-distance. If it->w is small, e.g. a
11697 mini-buffer window, we may end up in front of the window's
11698 display area. Start displaying at the start of the line
11699 containing PT in this case. */
11700 if (it.current_y <= 0)
11701 {
11702 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
11703 move_it_vertically (&it, 0);
11704 xassert (IT_CHARPOS (it) <= PT);
11705 it.current_y = 0;
11706 }
11707
11708 it.current_x = it.hpos = 0;
11709
11710 /* Set startp here explicitly in case that helps avoid an infinite loop
11711 in case the window-scroll-functions functions get errors. */
11712 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
11713
11714 /* Run scroll hooks. */
11715 startp = run_window_scroll_functions (window, it.current.pos);
11716
11717 /* Redisplay the window. */
11718 if (!current_matrix_up_to_date_p
11719 || windows_or_buffers_changed
11720 || cursor_type_changed
11721 /* Don't use try_window_reusing_current_matrix in this case
11722 because it can have changed the buffer. */
11723 || !NILP (Vwindow_scroll_functions)
11724 || !just_this_one_p
11725 || MINI_WINDOW_P (w)
11726 || !(used_current_matrix_p =
11727 try_window_reusing_current_matrix (w)))
11728 try_window (window, startp);
11729
11730 /* If new fonts have been loaded (due to fontsets), give up. We
11731 have to start a new redisplay since we need to re-adjust glyph
11732 matrices. */
11733 if (fonts_changed_p)
11734 goto need_larger_matrices;
11735
11736 /* If cursor did not appear assume that the middle of the window is
11737 in the first line of the window. Do it again with the next line.
11738 (Imagine a window of height 100, displaying two lines of height
11739 60. Moving back 50 from it->last_visible_y will end in the first
11740 line.) */
11741 if (w->cursor.vpos < 0)
11742 {
11743 if (!NILP (w->window_end_valid)
11744 && PT >= Z - XFASTINT (w->window_end_pos))
11745 {
11746 clear_glyph_matrix (w->desired_matrix);
11747 move_it_by_lines (&it, 1, 0);
11748 try_window (window, it.current.pos);
11749 }
11750 else if (PT < IT_CHARPOS (it))
11751 {
11752 clear_glyph_matrix (w->desired_matrix);
11753 move_it_by_lines (&it, -1, 0);
11754 try_window (window, it.current.pos);
11755 }
11756 else
11757 {
11758 /* Not much we can do about it. */
11759 }
11760 }
11761
11762 /* Consider the following case: Window starts at BEGV, there is
11763 invisible, intangible text at BEGV, so that display starts at
11764 some point START > BEGV. It can happen that we are called with
11765 PT somewhere between BEGV and START. Try to handle that case. */
11766 if (w->cursor.vpos < 0)
11767 {
11768 struct glyph_row *row = w->current_matrix->rows;
11769 if (row->mode_line_p)
11770 ++row;
11771 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11772 }
11773
11774 if (!make_cursor_line_fully_visible (w))
11775 {
11776 /* If vscroll is enabled, disable it and try again. */
11777 if (w->vscroll)
11778 {
11779 w->vscroll = 0;
11780 clear_glyph_matrix (w->desired_matrix);
11781 goto recenter;
11782 }
11783
11784 /* If centering point failed to make the whole line visible,
11785 put point at the top instead. That has to make the whole line
11786 visible, if it can be done. */
11787 centering_position = 0;
11788 goto point_at_top;
11789 }
11790
11791 done:
11792
11793 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11794 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
11795 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
11796 ? Qt : Qnil);
11797
11798 /* Display the mode line, if we must. */
11799 if ((update_mode_line
11800 /* If window not full width, must redo its mode line
11801 if (a) the window to its side is being redone and
11802 (b) we do a frame-based redisplay. This is a consequence
11803 of how inverted lines are drawn in frame-based redisplay. */
11804 || (!just_this_one_p
11805 && !FRAME_WINDOW_P (f)
11806 && !WINDOW_FULL_WIDTH_P (w))
11807 /* Line number to display. */
11808 || INTEGERP (w->base_line_pos)
11809 /* Column number is displayed and different from the one displayed. */
11810 || (!NILP (w->column_number_displayed)
11811 && (XFASTINT (w->column_number_displayed)
11812 != (int) current_column ()))) /* iftc */
11813 /* This means that the window has a mode line. */
11814 && (WINDOW_WANTS_MODELINE_P (w)
11815 || WINDOW_WANTS_HEADER_LINE_P (w)))
11816 {
11817 display_mode_lines (w);
11818
11819 /* If mode line height has changed, arrange for a thorough
11820 immediate redisplay using the correct mode line height. */
11821 if (WINDOW_WANTS_MODELINE_P (w)
11822 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
11823 {
11824 fonts_changed_p = 1;
11825 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
11826 = DESIRED_MODE_LINE_HEIGHT (w);
11827 }
11828
11829 /* If top line height has changed, arrange for a thorough
11830 immediate redisplay using the correct mode line height. */
11831 if (WINDOW_WANTS_HEADER_LINE_P (w)
11832 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
11833 {
11834 fonts_changed_p = 1;
11835 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
11836 = DESIRED_HEADER_LINE_HEIGHT (w);
11837 }
11838
11839 if (fonts_changed_p)
11840 goto need_larger_matrices;
11841 }
11842
11843 if (!line_number_displayed
11844 && !BUFFERP (w->base_line_pos))
11845 {
11846 w->base_line_pos = Qnil;
11847 w->base_line_number = Qnil;
11848 }
11849
11850 finish_menu_bars:
11851
11852 /* When we reach a frame's selected window, redo the frame's menu bar. */
11853 if (update_mode_line
11854 && EQ (FRAME_SELECTED_WINDOW (f), window))
11855 {
11856 int redisplay_menu_p = 0;
11857 int redisplay_tool_bar_p = 0;
11858
11859 if (FRAME_WINDOW_P (f))
11860 {
11861 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
11862 || defined (USE_GTK)
11863 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
11864 #else
11865 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
11866 #endif
11867 }
11868 else
11869 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
11870
11871 if (redisplay_menu_p)
11872 display_menu_bar (w);
11873
11874 #ifdef HAVE_WINDOW_SYSTEM
11875 #ifdef USE_GTK
11876 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
11877 #else
11878 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
11879 && (FRAME_TOOL_BAR_LINES (f) > 0
11880 || auto_resize_tool_bars_p);
11881
11882 #endif
11883
11884 if (redisplay_tool_bar_p)
11885 redisplay_tool_bar (f);
11886 #endif
11887 }
11888
11889 #ifdef HAVE_WINDOW_SYSTEM
11890 if (update_window_fringes (w, 0)
11891 && !just_this_one_p
11892 && (used_current_matrix_p || overlay_arrow_seen)
11893 && !w->pseudo_window_p)
11894 {
11895 update_begin (f);
11896 BLOCK_INPUT;
11897 draw_window_fringes (w);
11898 UNBLOCK_INPUT;
11899 update_end (f);
11900 }
11901 #endif /* HAVE_WINDOW_SYSTEM */
11902
11903 /* We go to this label, with fonts_changed_p nonzero,
11904 if it is necessary to try again using larger glyph matrices.
11905 We have to redeem the scroll bar even in this case,
11906 because the loop in redisplay_internal expects that. */
11907 need_larger_matrices:
11908 ;
11909 finish_scroll_bars:
11910
11911 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
11912 {
11913 /* Set the thumb's position and size. */
11914 set_vertical_scroll_bar (w);
11915
11916 /* Note that we actually used the scroll bar attached to this
11917 window, so it shouldn't be deleted at the end of redisplay. */
11918 redeem_scroll_bar_hook (w);
11919 }
11920
11921 /* Restore current_buffer and value of point in it. */
11922 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
11923 set_buffer_internal_1 (old);
11924 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
11925
11926 unbind_to (count, Qnil);
11927 }
11928
11929
11930 /* Build the complete desired matrix of WINDOW with a window start
11931 buffer position POS. Value is non-zero if successful. It is zero
11932 if fonts were loaded during redisplay which makes re-adjusting
11933 glyph matrices necessary. */
11934
11935 int
11936 try_window (window, pos)
11937 Lisp_Object window;
11938 struct text_pos pos;
11939 {
11940 struct window *w = XWINDOW (window);
11941 struct it it;
11942 struct glyph_row *last_text_row = NULL;
11943
11944 /* Make POS the new window start. */
11945 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
11946
11947 /* Mark cursor position as unknown. No overlay arrow seen. */
11948 w->cursor.vpos = -1;
11949 overlay_arrow_seen = 0;
11950
11951 /* Initialize iterator and info to start at POS. */
11952 start_display (&it, w, pos);
11953
11954 /* Display all lines of W. */
11955 while (it.current_y < it.last_visible_y)
11956 {
11957 if (display_line (&it))
11958 last_text_row = it.glyph_row - 1;
11959 if (fonts_changed_p)
11960 return 0;
11961 }
11962
11963 /* If bottom moved off end of frame, change mode line percentage. */
11964 if (XFASTINT (w->window_end_pos) <= 0
11965 && Z != IT_CHARPOS (it))
11966 w->update_mode_line = Qt;
11967
11968 /* Set window_end_pos to the offset of the last character displayed
11969 on the window from the end of current_buffer. Set
11970 window_end_vpos to its row number. */
11971 if (last_text_row)
11972 {
11973 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
11974 w->window_end_bytepos
11975 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
11976 w->window_end_pos
11977 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
11978 w->window_end_vpos
11979 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
11980 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
11981 ->displays_text_p);
11982 }
11983 else
11984 {
11985 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
11986 w->window_end_pos = make_number (Z - ZV);
11987 w->window_end_vpos = make_number (0);
11988 }
11989
11990 /* But that is not valid info until redisplay finishes. */
11991 w->window_end_valid = Qnil;
11992 return 1;
11993 }
11994
11995
11996 \f
11997 /************************************************************************
11998 Window redisplay reusing current matrix when buffer has not changed
11999 ************************************************************************/
12000
12001 /* Try redisplay of window W showing an unchanged buffer with a
12002 different window start than the last time it was displayed by
12003 reusing its current matrix. Value is non-zero if successful.
12004 W->start is the new window start. */
12005
12006 static int
12007 try_window_reusing_current_matrix (w)
12008 struct window *w;
12009 {
12010 struct frame *f = XFRAME (w->frame);
12011 struct glyph_row *row, *bottom_row;
12012 struct it it;
12013 struct run run;
12014 struct text_pos start, new_start;
12015 int nrows_scrolled, i;
12016 struct glyph_row *last_text_row;
12017 struct glyph_row *last_reused_text_row;
12018 struct glyph_row *start_row;
12019 int start_vpos, min_y, max_y;
12020
12021 #if GLYPH_DEBUG
12022 if (inhibit_try_window_reusing)
12023 return 0;
12024 #endif
12025
12026 if (/* This function doesn't handle terminal frames. */
12027 !FRAME_WINDOW_P (f)
12028 /* Don't try to reuse the display if windows have been split
12029 or such. */
12030 || windows_or_buffers_changed
12031 || cursor_type_changed)
12032 return 0;
12033
12034 /* Can't do this if region may have changed. */
12035 if ((!NILP (Vtransient_mark_mode)
12036 && !NILP (current_buffer->mark_active))
12037 || !NILP (w->region_showing)
12038 || !NILP (Vshow_trailing_whitespace))
12039 return 0;
12040
12041 /* If top-line visibility has changed, give up. */
12042 if (WINDOW_WANTS_HEADER_LINE_P (w)
12043 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12044 return 0;
12045
12046 /* Give up if old or new display is scrolled vertically. We could
12047 make this function handle this, but right now it doesn't. */
12048 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12049 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (start_row))
12050 return 0;
12051
12052 /* The variable new_start now holds the new window start. The old
12053 start `start' can be determined from the current matrix. */
12054 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12055 start = start_row->start.pos;
12056 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12057
12058 /* Clear the desired matrix for the display below. */
12059 clear_glyph_matrix (w->desired_matrix);
12060
12061 if (CHARPOS (new_start) <= CHARPOS (start))
12062 {
12063 int first_row_y;
12064
12065 /* Don't use this method if the display starts with an ellipsis
12066 displayed for invisible text. It's not easy to handle that case
12067 below, and it's certainly not worth the effort since this is
12068 not a frequent case. */
12069 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12070 return 0;
12071
12072 IF_DEBUG (debug_method_add (w, "twu1"));
12073
12074 /* Display up to a row that can be reused. The variable
12075 last_text_row is set to the last row displayed that displays
12076 text. Note that it.vpos == 0 if or if not there is a
12077 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12078 start_display (&it, w, new_start);
12079 first_row_y = it.current_y;
12080 w->cursor.vpos = -1;
12081 last_text_row = last_reused_text_row = NULL;
12082
12083 while (it.current_y < it.last_visible_y
12084 && IT_CHARPOS (it) < CHARPOS (start)
12085 && !fonts_changed_p)
12086 if (display_line (&it))
12087 last_text_row = it.glyph_row - 1;
12088
12089 /* A value of current_y < last_visible_y means that we stopped
12090 at the previous window start, which in turn means that we
12091 have at least one reusable row. */
12092 if (it.current_y < it.last_visible_y)
12093 {
12094 /* IT.vpos always starts from 0; it counts text lines. */
12095 nrows_scrolled = it.vpos;
12096
12097 /* Find PT if not already found in the lines displayed. */
12098 if (w->cursor.vpos < 0)
12099 {
12100 int dy = it.current_y - first_row_y;
12101
12102 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12103 row = row_containing_pos (w, PT, row, NULL, dy);
12104 if (row)
12105 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12106 dy, nrows_scrolled);
12107 else
12108 {
12109 clear_glyph_matrix (w->desired_matrix);
12110 return 0;
12111 }
12112 }
12113
12114 /* Scroll the display. Do it before the current matrix is
12115 changed. The problem here is that update has not yet
12116 run, i.e. part of the current matrix is not up to date.
12117 scroll_run_hook will clear the cursor, and use the
12118 current matrix to get the height of the row the cursor is
12119 in. */
12120 run.current_y = first_row_y;
12121 run.desired_y = it.current_y;
12122 run.height = it.last_visible_y - it.current_y;
12123
12124 if (run.height > 0 && run.current_y != run.desired_y)
12125 {
12126 update_begin (f);
12127 rif->update_window_begin_hook (w);
12128 rif->clear_window_mouse_face (w);
12129 rif->scroll_run_hook (w, &run);
12130 rif->update_window_end_hook (w, 0, 0);
12131 update_end (f);
12132 }
12133
12134 /* Shift current matrix down by nrows_scrolled lines. */
12135 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12136 rotate_matrix (w->current_matrix,
12137 start_vpos,
12138 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12139 nrows_scrolled);
12140
12141 /* Disable lines that must be updated. */
12142 for (i = 0; i < it.vpos; ++i)
12143 (start_row + i)->enabled_p = 0;
12144
12145 /* Re-compute Y positions. */
12146 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12147 max_y = it.last_visible_y;
12148 for (row = start_row + nrows_scrolled;
12149 row < bottom_row;
12150 ++row)
12151 {
12152 row->y = it.current_y;
12153 row->visible_height = row->height;
12154
12155 if (row->y < min_y)
12156 row->visible_height -= min_y - row->y;
12157 if (row->y + row->height > max_y)
12158 row->visible_height -= row->y + row->height - max_y;
12159 row->redraw_fringe_bitmaps_p = 1;
12160
12161 it.current_y += row->height;
12162
12163 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12164 last_reused_text_row = row;
12165 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12166 break;
12167 }
12168
12169 /* Disable lines in the current matrix which are now
12170 below the window. */
12171 for (++row; row < bottom_row; ++row)
12172 row->enabled_p = 0;
12173 }
12174
12175 /* Update window_end_pos etc.; last_reused_text_row is the last
12176 reused row from the current matrix containing text, if any.
12177 The value of last_text_row is the last displayed line
12178 containing text. */
12179 if (last_reused_text_row)
12180 {
12181 w->window_end_bytepos
12182 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12183 w->window_end_pos
12184 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12185 w->window_end_vpos
12186 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12187 w->current_matrix));
12188 }
12189 else if (last_text_row)
12190 {
12191 w->window_end_bytepos
12192 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12193 w->window_end_pos
12194 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12195 w->window_end_vpos
12196 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12197 }
12198 else
12199 {
12200 /* This window must be completely empty. */
12201 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12202 w->window_end_pos = make_number (Z - ZV);
12203 w->window_end_vpos = make_number (0);
12204 }
12205 w->window_end_valid = Qnil;
12206
12207 /* Update hint: don't try scrolling again in update_window. */
12208 w->desired_matrix->no_scrolling_p = 1;
12209
12210 #if GLYPH_DEBUG
12211 debug_method_add (w, "try_window_reusing_current_matrix 1");
12212 #endif
12213 return 1;
12214 }
12215 else if (CHARPOS (new_start) > CHARPOS (start))
12216 {
12217 struct glyph_row *pt_row, *row;
12218 struct glyph_row *first_reusable_row;
12219 struct glyph_row *first_row_to_display;
12220 int dy;
12221 int yb = window_text_bottom_y (w);
12222
12223 /* Find the row starting at new_start, if there is one. Don't
12224 reuse a partially visible line at the end. */
12225 first_reusable_row = start_row;
12226 while (first_reusable_row->enabled_p
12227 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12228 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12229 < CHARPOS (new_start)))
12230 ++first_reusable_row;
12231
12232 /* Give up if there is no row to reuse. */
12233 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12234 || !first_reusable_row->enabled_p
12235 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12236 != CHARPOS (new_start)))
12237 return 0;
12238
12239 /* We can reuse fully visible rows beginning with
12240 first_reusable_row to the end of the window. Set
12241 first_row_to_display to the first row that cannot be reused.
12242 Set pt_row to the row containing point, if there is any. */
12243 pt_row = NULL;
12244 for (first_row_to_display = first_reusable_row;
12245 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12246 ++first_row_to_display)
12247 {
12248 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12249 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12250 pt_row = first_row_to_display;
12251 }
12252
12253 /* Start displaying at the start of first_row_to_display. */
12254 xassert (first_row_to_display->y < yb);
12255 init_to_row_start (&it, w, first_row_to_display);
12256
12257 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12258 - start_vpos);
12259 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12260 - nrows_scrolled);
12261 it.current_y = (first_row_to_display->y - first_reusable_row->y
12262 + WINDOW_HEADER_LINE_HEIGHT (w));
12263
12264 /* Display lines beginning with first_row_to_display in the
12265 desired matrix. Set last_text_row to the last row displayed
12266 that displays text. */
12267 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12268 if (pt_row == NULL)
12269 w->cursor.vpos = -1;
12270 last_text_row = NULL;
12271 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12272 if (display_line (&it))
12273 last_text_row = it.glyph_row - 1;
12274
12275 /* Give up If point isn't in a row displayed or reused. */
12276 if (w->cursor.vpos < 0)
12277 {
12278 clear_glyph_matrix (w->desired_matrix);
12279 return 0;
12280 }
12281
12282 /* If point is in a reused row, adjust y and vpos of the cursor
12283 position. */
12284 if (pt_row)
12285 {
12286 w->cursor.vpos -= MATRIX_ROW_VPOS (first_reusable_row,
12287 w->current_matrix);
12288 w->cursor.y -= first_reusable_row->y;
12289 }
12290
12291 /* Scroll the display. */
12292 run.current_y = first_reusable_row->y;
12293 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12294 run.height = it.last_visible_y - run.current_y;
12295 dy = run.current_y - run.desired_y;
12296
12297 if (run.height)
12298 {
12299 update_begin (f);
12300 rif->update_window_begin_hook (w);
12301 rif->clear_window_mouse_face (w);
12302 rif->scroll_run_hook (w, &run);
12303 rif->update_window_end_hook (w, 0, 0);
12304 update_end (f);
12305 }
12306
12307 /* Adjust Y positions of reused rows. */
12308 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12309 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12310 max_y = it.last_visible_y;
12311 for (row = first_reusable_row; row < first_row_to_display; ++row)
12312 {
12313 row->y -= dy;
12314 row->visible_height = row->height;
12315 if (row->y < min_y)
12316 row->visible_height -= min_y - row->y;
12317 if (row->y + row->height > max_y)
12318 row->visible_height -= row->y + row->height - max_y;
12319 row->redraw_fringe_bitmaps_p = 1;
12320 }
12321
12322 /* Scroll the current matrix. */
12323 xassert (nrows_scrolled > 0);
12324 rotate_matrix (w->current_matrix,
12325 start_vpos,
12326 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12327 -nrows_scrolled);
12328
12329 /* Disable rows not reused. */
12330 for (row -= nrows_scrolled; row < bottom_row; ++row)
12331 row->enabled_p = 0;
12332
12333 /* Adjust window end. A null value of last_text_row means that
12334 the window end is in reused rows which in turn means that
12335 only its vpos can have changed. */
12336 if (last_text_row)
12337 {
12338 w->window_end_bytepos
12339 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12340 w->window_end_pos
12341 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12342 w->window_end_vpos
12343 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12344 }
12345 else
12346 {
12347 w->window_end_vpos
12348 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
12349 }
12350
12351 w->window_end_valid = Qnil;
12352 w->desired_matrix->no_scrolling_p = 1;
12353
12354 #if GLYPH_DEBUG
12355 debug_method_add (w, "try_window_reusing_current_matrix 2");
12356 #endif
12357 return 1;
12358 }
12359
12360 return 0;
12361 }
12362
12363
12364 \f
12365 /************************************************************************
12366 Window redisplay reusing current matrix when buffer has changed
12367 ************************************************************************/
12368
12369 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
12370 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
12371 int *, int *));
12372 static struct glyph_row *
12373 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
12374 struct glyph_row *));
12375
12376
12377 /* Return the last row in MATRIX displaying text. If row START is
12378 non-null, start searching with that row. IT gives the dimensions
12379 of the display. Value is null if matrix is empty; otherwise it is
12380 a pointer to the row found. */
12381
12382 static struct glyph_row *
12383 find_last_row_displaying_text (matrix, it, start)
12384 struct glyph_matrix *matrix;
12385 struct it *it;
12386 struct glyph_row *start;
12387 {
12388 struct glyph_row *row, *row_found;
12389
12390 /* Set row_found to the last row in IT->w's current matrix
12391 displaying text. The loop looks funny but think of partially
12392 visible lines. */
12393 row_found = NULL;
12394 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
12395 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12396 {
12397 xassert (row->enabled_p);
12398 row_found = row;
12399 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
12400 break;
12401 ++row;
12402 }
12403
12404 return row_found;
12405 }
12406
12407
12408 /* Return the last row in the current matrix of W that is not affected
12409 by changes at the start of current_buffer that occurred since W's
12410 current matrix was built. Value is null if no such row exists.
12411
12412 BEG_UNCHANGED us the number of characters unchanged at the start of
12413 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
12414 first changed character in current_buffer. Characters at positions <
12415 BEG + BEG_UNCHANGED are at the same buffer positions as they were
12416 when the current matrix was built. */
12417
12418 static struct glyph_row *
12419 find_last_unchanged_at_beg_row (w)
12420 struct window *w;
12421 {
12422 int first_changed_pos = BEG + BEG_UNCHANGED;
12423 struct glyph_row *row;
12424 struct glyph_row *row_found = NULL;
12425 int yb = window_text_bottom_y (w);
12426
12427 /* Find the last row displaying unchanged text. */
12428 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12429 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12430 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
12431 {
12432 if (/* If row ends before first_changed_pos, it is unchanged,
12433 except in some case. */
12434 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
12435 /* When row ends in ZV and we write at ZV it is not
12436 unchanged. */
12437 && !row->ends_at_zv_p
12438 /* When first_changed_pos is the end of a continued line,
12439 row is not unchanged because it may be no longer
12440 continued. */
12441 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
12442 && (row->continued_p
12443 || row->exact_window_width_line_p)))
12444 row_found = row;
12445
12446 /* Stop if last visible row. */
12447 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
12448 break;
12449
12450 ++row;
12451 }
12452
12453 return row_found;
12454 }
12455
12456
12457 /* Find the first glyph row in the current matrix of W that is not
12458 affected by changes at the end of current_buffer since the
12459 time W's current matrix was built.
12460
12461 Return in *DELTA the number of chars by which buffer positions in
12462 unchanged text at the end of current_buffer must be adjusted.
12463
12464 Return in *DELTA_BYTES the corresponding number of bytes.
12465
12466 Value is null if no such row exists, i.e. all rows are affected by
12467 changes. */
12468
12469 static struct glyph_row *
12470 find_first_unchanged_at_end_row (w, delta, delta_bytes)
12471 struct window *w;
12472 int *delta, *delta_bytes;
12473 {
12474 struct glyph_row *row;
12475 struct glyph_row *row_found = NULL;
12476
12477 *delta = *delta_bytes = 0;
12478
12479 /* Display must not have been paused, otherwise the current matrix
12480 is not up to date. */
12481 if (NILP (w->window_end_valid))
12482 abort ();
12483
12484 /* A value of window_end_pos >= END_UNCHANGED means that the window
12485 end is in the range of changed text. If so, there is no
12486 unchanged row at the end of W's current matrix. */
12487 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
12488 return NULL;
12489
12490 /* Set row to the last row in W's current matrix displaying text. */
12491 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12492
12493 /* If matrix is entirely empty, no unchanged row exists. */
12494 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12495 {
12496 /* The value of row is the last glyph row in the matrix having a
12497 meaningful buffer position in it. The end position of row
12498 corresponds to window_end_pos. This allows us to translate
12499 buffer positions in the current matrix to current buffer
12500 positions for characters not in changed text. */
12501 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12502 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12503 int last_unchanged_pos, last_unchanged_pos_old;
12504 struct glyph_row *first_text_row
12505 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12506
12507 *delta = Z - Z_old;
12508 *delta_bytes = Z_BYTE - Z_BYTE_old;
12509
12510 /* Set last_unchanged_pos to the buffer position of the last
12511 character in the buffer that has not been changed. Z is the
12512 index + 1 of the last character in current_buffer, i.e. by
12513 subtracting END_UNCHANGED we get the index of the last
12514 unchanged character, and we have to add BEG to get its buffer
12515 position. */
12516 last_unchanged_pos = Z - END_UNCHANGED + BEG;
12517 last_unchanged_pos_old = last_unchanged_pos - *delta;
12518
12519 /* Search backward from ROW for a row displaying a line that
12520 starts at a minimum position >= last_unchanged_pos_old. */
12521 for (; row > first_text_row; --row)
12522 {
12523 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
12524 abort ();
12525
12526 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
12527 row_found = row;
12528 }
12529 }
12530
12531 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
12532 abort ();
12533
12534 return row_found;
12535 }
12536
12537
12538 /* Make sure that glyph rows in the current matrix of window W
12539 reference the same glyph memory as corresponding rows in the
12540 frame's frame matrix. This function is called after scrolling W's
12541 current matrix on a terminal frame in try_window_id and
12542 try_window_reusing_current_matrix. */
12543
12544 static void
12545 sync_frame_with_window_matrix_rows (w)
12546 struct window *w;
12547 {
12548 struct frame *f = XFRAME (w->frame);
12549 struct glyph_row *window_row, *window_row_end, *frame_row;
12550
12551 /* Preconditions: W must be a leaf window and full-width. Its frame
12552 must have a frame matrix. */
12553 xassert (NILP (w->hchild) && NILP (w->vchild));
12554 xassert (WINDOW_FULL_WIDTH_P (w));
12555 xassert (!FRAME_WINDOW_P (f));
12556
12557 /* If W is a full-width window, glyph pointers in W's current matrix
12558 have, by definition, to be the same as glyph pointers in the
12559 corresponding frame matrix. Note that frame matrices have no
12560 marginal areas (see build_frame_matrix). */
12561 window_row = w->current_matrix->rows;
12562 window_row_end = window_row + w->current_matrix->nrows;
12563 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
12564 while (window_row < window_row_end)
12565 {
12566 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
12567 struct glyph *end = window_row->glyphs[LAST_AREA];
12568
12569 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
12570 frame_row->glyphs[TEXT_AREA] = start;
12571 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
12572 frame_row->glyphs[LAST_AREA] = end;
12573
12574 /* Disable frame rows whose corresponding window rows have
12575 been disabled in try_window_id. */
12576 if (!window_row->enabled_p)
12577 frame_row->enabled_p = 0;
12578
12579 ++window_row, ++frame_row;
12580 }
12581 }
12582
12583
12584 /* Find the glyph row in window W containing CHARPOS. Consider all
12585 rows between START and END (not inclusive). END null means search
12586 all rows to the end of the display area of W. Value is the row
12587 containing CHARPOS or null. */
12588
12589 struct glyph_row *
12590 row_containing_pos (w, charpos, start, end, dy)
12591 struct window *w;
12592 int charpos;
12593 struct glyph_row *start, *end;
12594 int dy;
12595 {
12596 struct glyph_row *row = start;
12597 int last_y;
12598
12599 /* If we happen to start on a header-line, skip that. */
12600 if (row->mode_line_p)
12601 ++row;
12602
12603 if ((end && row >= end) || !row->enabled_p)
12604 return NULL;
12605
12606 last_y = window_text_bottom_y (w) - dy;
12607
12608 while (1)
12609 {
12610 /* Give up if we have gone too far. */
12611 if (end && row >= end)
12612 return NULL;
12613 /* This formerly returned if they were equal.
12614 I think that both quantities are of a "last plus one" type;
12615 if so, when they are equal, the row is within the screen. -- rms. */
12616 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
12617 return NULL;
12618
12619 /* If it is in this row, return this row. */
12620 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
12621 || (MATRIX_ROW_END_CHARPOS (row) == charpos
12622 /* The end position of a row equals the start
12623 position of the next row. If CHARPOS is there, we
12624 would rather display it in the next line, except
12625 when this line ends in ZV. */
12626 && !row->ends_at_zv_p
12627 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
12628 && charpos >= MATRIX_ROW_START_CHARPOS (row))
12629 return row;
12630 ++row;
12631 }
12632 }
12633
12634
12635 /* Try to redisplay window W by reusing its existing display. W's
12636 current matrix must be up to date when this function is called,
12637 i.e. window_end_valid must not be nil.
12638
12639 Value is
12640
12641 1 if display has been updated
12642 0 if otherwise unsuccessful
12643 -1 if redisplay with same window start is known not to succeed
12644
12645 The following steps are performed:
12646
12647 1. Find the last row in the current matrix of W that is not
12648 affected by changes at the start of current_buffer. If no such row
12649 is found, give up.
12650
12651 2. Find the first row in W's current matrix that is not affected by
12652 changes at the end of current_buffer. Maybe there is no such row.
12653
12654 3. Display lines beginning with the row + 1 found in step 1 to the
12655 row found in step 2 or, if step 2 didn't find a row, to the end of
12656 the window.
12657
12658 4. If cursor is not known to appear on the window, give up.
12659
12660 5. If display stopped at the row found in step 2, scroll the
12661 display and current matrix as needed.
12662
12663 6. Maybe display some lines at the end of W, if we must. This can
12664 happen under various circumstances, like a partially visible line
12665 becoming fully visible, or because newly displayed lines are displayed
12666 in smaller font sizes.
12667
12668 7. Update W's window end information. */
12669
12670 static int
12671 try_window_id (w)
12672 struct window *w;
12673 {
12674 struct frame *f = XFRAME (w->frame);
12675 struct glyph_matrix *current_matrix = w->current_matrix;
12676 struct glyph_matrix *desired_matrix = w->desired_matrix;
12677 struct glyph_row *last_unchanged_at_beg_row;
12678 struct glyph_row *first_unchanged_at_end_row;
12679 struct glyph_row *row;
12680 struct glyph_row *bottom_row;
12681 int bottom_vpos;
12682 struct it it;
12683 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
12684 struct text_pos start_pos;
12685 struct run run;
12686 int first_unchanged_at_end_vpos = 0;
12687 struct glyph_row *last_text_row, *last_text_row_at_end;
12688 struct text_pos start;
12689 int first_changed_charpos, last_changed_charpos;
12690
12691 #if GLYPH_DEBUG
12692 if (inhibit_try_window_id)
12693 return 0;
12694 #endif
12695
12696 /* This is handy for debugging. */
12697 #if 0
12698 #define GIVE_UP(X) \
12699 do { \
12700 fprintf (stderr, "try_window_id give up %d\n", (X)); \
12701 return 0; \
12702 } while (0)
12703 #else
12704 #define GIVE_UP(X) return 0
12705 #endif
12706
12707 SET_TEXT_POS_FROM_MARKER (start, w->start);
12708
12709 /* Don't use this for mini-windows because these can show
12710 messages and mini-buffers, and we don't handle that here. */
12711 if (MINI_WINDOW_P (w))
12712 GIVE_UP (1);
12713
12714 /* This flag is used to prevent redisplay optimizations. */
12715 if (windows_or_buffers_changed || cursor_type_changed)
12716 GIVE_UP (2);
12717
12718 /* Verify that narrowing has not changed.
12719 Also verify that we were not told to prevent redisplay optimizations.
12720 It would be nice to further
12721 reduce the number of cases where this prevents try_window_id. */
12722 if (current_buffer->clip_changed
12723 || current_buffer->prevent_redisplay_optimizations_p)
12724 GIVE_UP (3);
12725
12726 /* Window must either use window-based redisplay or be full width. */
12727 if (!FRAME_WINDOW_P (f)
12728 && (!line_ins_del_ok
12729 || !WINDOW_FULL_WIDTH_P (w)))
12730 GIVE_UP (4);
12731
12732 /* Give up if point is not known NOT to appear in W. */
12733 if (PT < CHARPOS (start))
12734 GIVE_UP (5);
12735
12736 /* Another way to prevent redisplay optimizations. */
12737 if (XFASTINT (w->last_modified) == 0)
12738 GIVE_UP (6);
12739
12740 /* Verify that window is not hscrolled. */
12741 if (XFASTINT (w->hscroll) != 0)
12742 GIVE_UP (7);
12743
12744 /* Verify that display wasn't paused. */
12745 if (NILP (w->window_end_valid))
12746 GIVE_UP (8);
12747
12748 /* Can't use this if highlighting a region because a cursor movement
12749 will do more than just set the cursor. */
12750 if (!NILP (Vtransient_mark_mode)
12751 && !NILP (current_buffer->mark_active))
12752 GIVE_UP (9);
12753
12754 /* Likewise if highlighting trailing whitespace. */
12755 if (!NILP (Vshow_trailing_whitespace))
12756 GIVE_UP (11);
12757
12758 /* Likewise if showing a region. */
12759 if (!NILP (w->region_showing))
12760 GIVE_UP (10);
12761
12762 /* Can use this if overlay arrow position and or string have changed. */
12763 if (!EQ (last_arrow_position, COERCE_MARKER (Voverlay_arrow_position))
12764 || !EQ (last_arrow_string, Voverlay_arrow_string))
12765 GIVE_UP (12);
12766
12767
12768 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
12769 only if buffer has really changed. The reason is that the gap is
12770 initially at Z for freshly visited files. The code below would
12771 set end_unchanged to 0 in that case. */
12772 if (MODIFF > SAVE_MODIFF
12773 /* This seems to happen sometimes after saving a buffer. */
12774 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
12775 {
12776 if (GPT - BEG < BEG_UNCHANGED)
12777 BEG_UNCHANGED = GPT - BEG;
12778 if (Z - GPT < END_UNCHANGED)
12779 END_UNCHANGED = Z - GPT;
12780 }
12781
12782 /* The position of the first and last character that has been changed. */
12783 first_changed_charpos = BEG + BEG_UNCHANGED;
12784 last_changed_charpos = Z - END_UNCHANGED;
12785
12786 /* If window starts after a line end, and the last change is in
12787 front of that newline, then changes don't affect the display.
12788 This case happens with stealth-fontification. Note that although
12789 the display is unchanged, glyph positions in the matrix have to
12790 be adjusted, of course. */
12791 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
12792 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
12793 && ((last_changed_charpos < CHARPOS (start)
12794 && CHARPOS (start) == BEGV)
12795 || (last_changed_charpos < CHARPOS (start) - 1
12796 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
12797 {
12798 int Z_old, delta, Z_BYTE_old, delta_bytes;
12799 struct glyph_row *r0;
12800
12801 /* Compute how many chars/bytes have been added to or removed
12802 from the buffer. */
12803 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
12804 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
12805 delta = Z - Z_old;
12806 delta_bytes = Z_BYTE - Z_BYTE_old;
12807
12808 /* Give up if PT is not in the window. Note that it already has
12809 been checked at the start of try_window_id that PT is not in
12810 front of the window start. */
12811 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
12812 GIVE_UP (13);
12813
12814 /* If window start is unchanged, we can reuse the whole matrix
12815 as is, after adjusting glyph positions. No need to compute
12816 the window end again, since its offset from Z hasn't changed. */
12817 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12818 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
12819 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
12820 /* PT must not be in a partially visible line. */
12821 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
12822 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
12823 {
12824 /* Adjust positions in the glyph matrix. */
12825 if (delta || delta_bytes)
12826 {
12827 struct glyph_row *r1
12828 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
12829 increment_matrix_positions (w->current_matrix,
12830 MATRIX_ROW_VPOS (r0, current_matrix),
12831 MATRIX_ROW_VPOS (r1, current_matrix),
12832 delta, delta_bytes);
12833 }
12834
12835 /* Set the cursor. */
12836 row = row_containing_pos (w, PT, r0, NULL, 0);
12837 if (row)
12838 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12839 else
12840 abort ();
12841 return 1;
12842 }
12843 }
12844
12845 /* Handle the case that changes are all below what is displayed in
12846 the window, and that PT is in the window. This shortcut cannot
12847 be taken if ZV is visible in the window, and text has been added
12848 there that is visible in the window. */
12849 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
12850 /* ZV is not visible in the window, or there are no
12851 changes at ZV, actually. */
12852 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
12853 || first_changed_charpos == last_changed_charpos))
12854 {
12855 struct glyph_row *r0;
12856
12857 /* Give up if PT is not in the window. Note that it already has
12858 been checked at the start of try_window_id that PT is not in
12859 front of the window start. */
12860 if (PT >= MATRIX_ROW_END_CHARPOS (row))
12861 GIVE_UP (14);
12862
12863 /* If window start is unchanged, we can reuse the whole matrix
12864 as is, without changing glyph positions since no text has
12865 been added/removed in front of the window end. */
12866 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
12867 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
12868 /* PT must not be in a partially visible line. */
12869 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
12870 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
12871 {
12872 /* We have to compute the window end anew since text
12873 can have been added/removed after it. */
12874 w->window_end_pos
12875 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
12876 w->window_end_bytepos
12877 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
12878
12879 /* Set the cursor. */
12880 row = row_containing_pos (w, PT, r0, NULL, 0);
12881 if (row)
12882 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
12883 else
12884 abort ();
12885 return 2;
12886 }
12887 }
12888
12889 /* Give up if window start is in the changed area.
12890
12891 The condition used to read
12892
12893 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
12894
12895 but why that was tested escapes me at the moment. */
12896 if (CHARPOS (start) >= first_changed_charpos
12897 && CHARPOS (start) <= last_changed_charpos)
12898 GIVE_UP (15);
12899
12900 /* Check that window start agrees with the start of the first glyph
12901 row in its current matrix. Check this after we know the window
12902 start is not in changed text, otherwise positions would not be
12903 comparable. */
12904 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
12905 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
12906 GIVE_UP (16);
12907
12908 /* Give up if the window ends in strings. Overlay strings
12909 at the end are difficult to handle, so don't try. */
12910 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
12911 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
12912 GIVE_UP (20);
12913
12914 /* Compute the position at which we have to start displaying new
12915 lines. Some of the lines at the top of the window might be
12916 reusable because they are not displaying changed text. Find the
12917 last row in W's current matrix not affected by changes at the
12918 start of current_buffer. Value is null if changes start in the
12919 first line of window. */
12920 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
12921 if (last_unchanged_at_beg_row)
12922 {
12923 /* Avoid starting to display in the moddle of a character, a TAB
12924 for instance. This is easier than to set up the iterator
12925 exactly, and it's not a frequent case, so the additional
12926 effort wouldn't really pay off. */
12927 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
12928 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
12929 && last_unchanged_at_beg_row > w->current_matrix->rows)
12930 --last_unchanged_at_beg_row;
12931
12932 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
12933 GIVE_UP (17);
12934
12935 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
12936 GIVE_UP (18);
12937 start_pos = it.current.pos;
12938
12939 /* Start displaying new lines in the desired matrix at the same
12940 vpos we would use in the current matrix, i.e. below
12941 last_unchanged_at_beg_row. */
12942 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
12943 current_matrix);
12944 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
12945 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
12946
12947 xassert (it.hpos == 0 && it.current_x == 0);
12948 }
12949 else
12950 {
12951 /* There are no reusable lines at the start of the window.
12952 Start displaying in the first text line. */
12953 start_display (&it, w, start);
12954 it.vpos = it.first_vpos;
12955 start_pos = it.current.pos;
12956 }
12957
12958 /* Find the first row that is not affected by changes at the end of
12959 the buffer. Value will be null if there is no unchanged row, in
12960 which case we must redisplay to the end of the window. delta
12961 will be set to the value by which buffer positions beginning with
12962 first_unchanged_at_end_row have to be adjusted due to text
12963 changes. */
12964 first_unchanged_at_end_row
12965 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
12966 IF_DEBUG (debug_delta = delta);
12967 IF_DEBUG (debug_delta_bytes = delta_bytes);
12968
12969 /* Set stop_pos to the buffer position up to which we will have to
12970 display new lines. If first_unchanged_at_end_row != NULL, this
12971 is the buffer position of the start of the line displayed in that
12972 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
12973 that we don't stop at a buffer position. */
12974 stop_pos = 0;
12975 if (first_unchanged_at_end_row)
12976 {
12977 xassert (last_unchanged_at_beg_row == NULL
12978 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
12979
12980 /* If this is a continuation line, move forward to the next one
12981 that isn't. Changes in lines above affect this line.
12982 Caution: this may move first_unchanged_at_end_row to a row
12983 not displaying text. */
12984 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
12985 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
12986 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
12987 < it.last_visible_y))
12988 ++first_unchanged_at_end_row;
12989
12990 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
12991 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
12992 >= it.last_visible_y))
12993 first_unchanged_at_end_row = NULL;
12994 else
12995 {
12996 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
12997 + delta);
12998 first_unchanged_at_end_vpos
12999 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13000 xassert (stop_pos >= Z - END_UNCHANGED);
13001 }
13002 }
13003 else if (last_unchanged_at_beg_row == NULL)
13004 GIVE_UP (19);
13005
13006
13007 #if GLYPH_DEBUG
13008
13009 /* Either there is no unchanged row at the end, or the one we have
13010 now displays text. This is a necessary condition for the window
13011 end pos calculation at the end of this function. */
13012 xassert (first_unchanged_at_end_row == NULL
13013 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13014
13015 debug_last_unchanged_at_beg_vpos
13016 = (last_unchanged_at_beg_row
13017 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13018 : -1);
13019 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13020
13021 #endif /* GLYPH_DEBUG != 0 */
13022
13023
13024 /* Display new lines. Set last_text_row to the last new line
13025 displayed which has text on it, i.e. might end up as being the
13026 line where the window_end_vpos is. */
13027 w->cursor.vpos = -1;
13028 last_text_row = NULL;
13029 overlay_arrow_seen = 0;
13030 while (it.current_y < it.last_visible_y
13031 && !fonts_changed_p
13032 && (first_unchanged_at_end_row == NULL
13033 || IT_CHARPOS (it) < stop_pos))
13034 {
13035 if (display_line (&it))
13036 last_text_row = it.glyph_row - 1;
13037 }
13038
13039 if (fonts_changed_p)
13040 return -1;
13041
13042
13043 /* Compute differences in buffer positions, y-positions etc. for
13044 lines reused at the bottom of the window. Compute what we can
13045 scroll. */
13046 if (first_unchanged_at_end_row
13047 /* No lines reused because we displayed everything up to the
13048 bottom of the window. */
13049 && it.current_y < it.last_visible_y)
13050 {
13051 dvpos = (it.vpos
13052 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13053 current_matrix));
13054 dy = it.current_y - first_unchanged_at_end_row->y;
13055 run.current_y = first_unchanged_at_end_row->y;
13056 run.desired_y = run.current_y + dy;
13057 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13058 }
13059 else
13060 {
13061 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13062 first_unchanged_at_end_row = NULL;
13063 }
13064 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13065
13066
13067 /* Find the cursor if not already found. We have to decide whether
13068 PT will appear on this window (it sometimes doesn't, but this is
13069 not a very frequent case.) This decision has to be made before
13070 the current matrix is altered. A value of cursor.vpos < 0 means
13071 that PT is either in one of the lines beginning at
13072 first_unchanged_at_end_row or below the window. Don't care for
13073 lines that might be displayed later at the window end; as
13074 mentioned, this is not a frequent case. */
13075 if (w->cursor.vpos < 0)
13076 {
13077 /* Cursor in unchanged rows at the top? */
13078 if (PT < CHARPOS (start_pos)
13079 && last_unchanged_at_beg_row)
13080 {
13081 row = row_containing_pos (w, PT,
13082 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13083 last_unchanged_at_beg_row + 1, 0);
13084 if (row)
13085 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13086 }
13087
13088 /* Start from first_unchanged_at_end_row looking for PT. */
13089 else if (first_unchanged_at_end_row)
13090 {
13091 row = row_containing_pos (w, PT - delta,
13092 first_unchanged_at_end_row, NULL, 0);
13093 if (row)
13094 set_cursor_from_row (w, row, w->current_matrix, delta,
13095 delta_bytes, dy, dvpos);
13096 }
13097
13098 /* Give up if cursor was not found. */
13099 if (w->cursor.vpos < 0)
13100 {
13101 clear_glyph_matrix (w->desired_matrix);
13102 return -1;
13103 }
13104 }
13105
13106 /* Don't let the cursor end in the scroll margins. */
13107 {
13108 int this_scroll_margin, cursor_height;
13109
13110 this_scroll_margin = max (0, scroll_margin);
13111 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13112 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13113 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13114
13115 if ((w->cursor.y < this_scroll_margin
13116 && CHARPOS (start) > BEGV)
13117 /* Don't take scroll margin into account at the bottom because
13118 old redisplay didn't do it either. */
13119 || w->cursor.y + cursor_height > it.last_visible_y)
13120 {
13121 w->cursor.vpos = -1;
13122 clear_glyph_matrix (w->desired_matrix);
13123 return -1;
13124 }
13125 }
13126
13127 /* Scroll the display. Do it before changing the current matrix so
13128 that xterm.c doesn't get confused about where the cursor glyph is
13129 found. */
13130 if (dy && run.height)
13131 {
13132 update_begin (f);
13133
13134 if (FRAME_WINDOW_P (f))
13135 {
13136 rif->update_window_begin_hook (w);
13137 rif->clear_window_mouse_face (w);
13138 rif->scroll_run_hook (w, &run);
13139 rif->update_window_end_hook (w, 0, 0);
13140 }
13141 else
13142 {
13143 /* Terminal frame. In this case, dvpos gives the number of
13144 lines to scroll by; dvpos < 0 means scroll up. */
13145 int first_unchanged_at_end_vpos
13146 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13147 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13148 int end = (WINDOW_TOP_EDGE_LINE (w)
13149 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13150 + window_internal_height (w));
13151
13152 /* Perform the operation on the screen. */
13153 if (dvpos > 0)
13154 {
13155 /* Scroll last_unchanged_at_beg_row to the end of the
13156 window down dvpos lines. */
13157 set_terminal_window (end);
13158
13159 /* On dumb terminals delete dvpos lines at the end
13160 before inserting dvpos empty lines. */
13161 if (!scroll_region_ok)
13162 ins_del_lines (end - dvpos, -dvpos);
13163
13164 /* Insert dvpos empty lines in front of
13165 last_unchanged_at_beg_row. */
13166 ins_del_lines (from, dvpos);
13167 }
13168 else if (dvpos < 0)
13169 {
13170 /* Scroll up last_unchanged_at_beg_vpos to the end of
13171 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13172 set_terminal_window (end);
13173
13174 /* Delete dvpos lines in front of
13175 last_unchanged_at_beg_vpos. ins_del_lines will set
13176 the cursor to the given vpos and emit |dvpos| delete
13177 line sequences. */
13178 ins_del_lines (from + dvpos, dvpos);
13179
13180 /* On a dumb terminal insert dvpos empty lines at the
13181 end. */
13182 if (!scroll_region_ok)
13183 ins_del_lines (end + dvpos, -dvpos);
13184 }
13185
13186 set_terminal_window (0);
13187 }
13188
13189 update_end (f);
13190 }
13191
13192 /* Shift reused rows of the current matrix to the right position.
13193 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13194 text. */
13195 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13196 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13197 if (dvpos < 0)
13198 {
13199 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13200 bottom_vpos, dvpos);
13201 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13202 bottom_vpos, 0);
13203 }
13204 else if (dvpos > 0)
13205 {
13206 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13207 bottom_vpos, dvpos);
13208 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13209 first_unchanged_at_end_vpos + dvpos, 0);
13210 }
13211
13212 /* For frame-based redisplay, make sure that current frame and window
13213 matrix are in sync with respect to glyph memory. */
13214 if (!FRAME_WINDOW_P (f))
13215 sync_frame_with_window_matrix_rows (w);
13216
13217 /* Adjust buffer positions in reused rows. */
13218 if (delta)
13219 increment_matrix_positions (current_matrix,
13220 first_unchanged_at_end_vpos + dvpos,
13221 bottom_vpos, delta, delta_bytes);
13222
13223 /* Adjust Y positions. */
13224 if (dy)
13225 shift_glyph_matrix (w, current_matrix,
13226 first_unchanged_at_end_vpos + dvpos,
13227 bottom_vpos, dy);
13228
13229 if (first_unchanged_at_end_row)
13230 first_unchanged_at_end_row += dvpos;
13231
13232 /* If scrolling up, there may be some lines to display at the end of
13233 the window. */
13234 last_text_row_at_end = NULL;
13235 if (dy < 0)
13236 {
13237 /* Scrolling up can leave for example a partially visible line
13238 at the end of the window to be redisplayed. */
13239 /* Set last_row to the glyph row in the current matrix where the
13240 window end line is found. It has been moved up or down in
13241 the matrix by dvpos. */
13242 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13243 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13244
13245 /* If last_row is the window end line, it should display text. */
13246 xassert (last_row->displays_text_p);
13247
13248 /* If window end line was partially visible before, begin
13249 displaying at that line. Otherwise begin displaying with the
13250 line following it. */
13251 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13252 {
13253 init_to_row_start (&it, w, last_row);
13254 it.vpos = last_vpos;
13255 it.current_y = last_row->y;
13256 }
13257 else
13258 {
13259 init_to_row_end (&it, w, last_row);
13260 it.vpos = 1 + last_vpos;
13261 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13262 ++last_row;
13263 }
13264
13265 /* We may start in a continuation line. If so, we have to
13266 get the right continuation_lines_width and current_x. */
13267 it.continuation_lines_width = last_row->continuation_lines_width;
13268 it.hpos = it.current_x = 0;
13269
13270 /* Display the rest of the lines at the window end. */
13271 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13272 while (it.current_y < it.last_visible_y
13273 && !fonts_changed_p)
13274 {
13275 /* Is it always sure that the display agrees with lines in
13276 the current matrix? I don't think so, so we mark rows
13277 displayed invalid in the current matrix by setting their
13278 enabled_p flag to zero. */
13279 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13280 if (display_line (&it))
13281 last_text_row_at_end = it.glyph_row - 1;
13282 }
13283 }
13284
13285 /* Update window_end_pos and window_end_vpos. */
13286 if (first_unchanged_at_end_row
13287 && first_unchanged_at_end_row->y < it.last_visible_y
13288 && !last_text_row_at_end)
13289 {
13290 /* Window end line if one of the preserved rows from the current
13291 matrix. Set row to the last row displaying text in current
13292 matrix starting at first_unchanged_at_end_row, after
13293 scrolling. */
13294 xassert (first_unchanged_at_end_row->displays_text_p);
13295 row = find_last_row_displaying_text (w->current_matrix, &it,
13296 first_unchanged_at_end_row);
13297 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13298
13299 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13300 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13301 w->window_end_vpos
13302 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13303 xassert (w->window_end_bytepos >= 0);
13304 IF_DEBUG (debug_method_add (w, "A"));
13305 }
13306 else if (last_text_row_at_end)
13307 {
13308 w->window_end_pos
13309 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13310 w->window_end_bytepos
13311 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13312 w->window_end_vpos
13313 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13314 xassert (w->window_end_bytepos >= 0);
13315 IF_DEBUG (debug_method_add (w, "B"));
13316 }
13317 else if (last_text_row)
13318 {
13319 /* We have displayed either to the end of the window or at the
13320 end of the window, i.e. the last row with text is to be found
13321 in the desired matrix. */
13322 w->window_end_pos
13323 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13324 w->window_end_bytepos
13325 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13326 w->window_end_vpos
13327 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13328 xassert (w->window_end_bytepos >= 0);
13329 }
13330 else if (first_unchanged_at_end_row == NULL
13331 && last_text_row == NULL
13332 && last_text_row_at_end == NULL)
13333 {
13334 /* Displayed to end of window, but no line containing text was
13335 displayed. Lines were deleted at the end of the window. */
13336 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13337 int vpos = XFASTINT (w->window_end_vpos);
13338 struct glyph_row *current_row = current_matrix->rows + vpos;
13339 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13340
13341 for (row = NULL;
13342 row == NULL && vpos >= first_vpos;
13343 --vpos, --current_row, --desired_row)
13344 {
13345 if (desired_row->enabled_p)
13346 {
13347 if (desired_row->displays_text_p)
13348 row = desired_row;
13349 }
13350 else if (current_row->displays_text_p)
13351 row = current_row;
13352 }
13353
13354 xassert (row != NULL);
13355 w->window_end_vpos = make_number (vpos + 1);
13356 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13357 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13358 xassert (w->window_end_bytepos >= 0);
13359 IF_DEBUG (debug_method_add (w, "C"));
13360 }
13361 else
13362 abort ();
13363
13364 #if 0 /* This leads to problems, for instance when the cursor is
13365 at ZV, and the cursor line displays no text. */
13366 /* Disable rows below what's displayed in the window. This makes
13367 debugging easier. */
13368 enable_glyph_matrix_rows (current_matrix,
13369 XFASTINT (w->window_end_vpos) + 1,
13370 bottom_vpos, 0);
13371 #endif
13372
13373 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
13374 debug_end_vpos = XFASTINT (w->window_end_vpos));
13375
13376 /* Record that display has not been completed. */
13377 w->window_end_valid = Qnil;
13378 w->desired_matrix->no_scrolling_p = 1;
13379 return 3;
13380
13381 #undef GIVE_UP
13382 }
13383
13384
13385 \f
13386 /***********************************************************************
13387 More debugging support
13388 ***********************************************************************/
13389
13390 #if GLYPH_DEBUG
13391
13392 void dump_glyph_row P_ ((struct glyph_row *, int, int));
13393 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
13394 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
13395
13396
13397 /* Dump the contents of glyph matrix MATRIX on stderr.
13398
13399 GLYPHS 0 means don't show glyph contents.
13400 GLYPHS 1 means show glyphs in short form
13401 GLYPHS > 1 means show glyphs in long form. */
13402
13403 void
13404 dump_glyph_matrix (matrix, glyphs)
13405 struct glyph_matrix *matrix;
13406 int glyphs;
13407 {
13408 int i;
13409 for (i = 0; i < matrix->nrows; ++i)
13410 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
13411 }
13412
13413
13414 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
13415 the glyph row and area where the glyph comes from. */
13416
13417 void
13418 dump_glyph (row, glyph, area)
13419 struct glyph_row *row;
13420 struct glyph *glyph;
13421 int area;
13422 {
13423 if (glyph->type == CHAR_GLYPH)
13424 {
13425 fprintf (stderr,
13426 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13427 glyph - row->glyphs[TEXT_AREA],
13428 'C',
13429 glyph->charpos,
13430 (BUFFERP (glyph->object)
13431 ? 'B'
13432 : (STRINGP (glyph->object)
13433 ? 'S'
13434 : '-')),
13435 glyph->pixel_width,
13436 glyph->u.ch,
13437 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
13438 ? glyph->u.ch
13439 : '.'),
13440 glyph->face_id,
13441 glyph->left_box_line_p,
13442 glyph->right_box_line_p);
13443 }
13444 else if (glyph->type == STRETCH_GLYPH)
13445 {
13446 fprintf (stderr,
13447 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13448 glyph - row->glyphs[TEXT_AREA],
13449 'S',
13450 glyph->charpos,
13451 (BUFFERP (glyph->object)
13452 ? 'B'
13453 : (STRINGP (glyph->object)
13454 ? 'S'
13455 : '-')),
13456 glyph->pixel_width,
13457 0,
13458 '.',
13459 glyph->face_id,
13460 glyph->left_box_line_p,
13461 glyph->right_box_line_p);
13462 }
13463 else if (glyph->type == IMAGE_GLYPH)
13464 {
13465 fprintf (stderr,
13466 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
13467 glyph - row->glyphs[TEXT_AREA],
13468 'I',
13469 glyph->charpos,
13470 (BUFFERP (glyph->object)
13471 ? 'B'
13472 : (STRINGP (glyph->object)
13473 ? 'S'
13474 : '-')),
13475 glyph->pixel_width,
13476 glyph->u.img_id,
13477 '.',
13478 glyph->face_id,
13479 glyph->left_box_line_p,
13480 glyph->right_box_line_p);
13481 }
13482 }
13483
13484
13485 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
13486 GLYPHS 0 means don't show glyph contents.
13487 GLYPHS 1 means show glyphs in short form
13488 GLYPHS > 1 means show glyphs in long form. */
13489
13490 void
13491 dump_glyph_row (row, vpos, glyphs)
13492 struct glyph_row *row;
13493 int vpos, glyphs;
13494 {
13495 if (glyphs != 1)
13496 {
13497 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
13498 fprintf (stderr, "=======================================================================\n");
13499
13500 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
13501 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
13502 vpos,
13503 MATRIX_ROW_START_CHARPOS (row),
13504 MATRIX_ROW_END_CHARPOS (row),
13505 row->used[TEXT_AREA],
13506 row->contains_overlapping_glyphs_p,
13507 row->enabled_p,
13508 row->truncated_on_left_p,
13509 row->truncated_on_right_p,
13510 row->overlay_arrow_p,
13511 row->continued_p,
13512 MATRIX_ROW_CONTINUATION_LINE_P (row),
13513 row->displays_text_p,
13514 row->ends_at_zv_p,
13515 row->fill_line_p,
13516 row->ends_in_middle_of_char_p,
13517 row->starts_in_middle_of_char_p,
13518 row->mouse_face_p,
13519 row->x,
13520 row->y,
13521 row->pixel_width,
13522 row->height,
13523 row->visible_height,
13524 row->ascent,
13525 row->phys_ascent);
13526 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
13527 row->end.overlay_string_index,
13528 row->continuation_lines_width);
13529 fprintf (stderr, "%9d %5d\n",
13530 CHARPOS (row->start.string_pos),
13531 CHARPOS (row->end.string_pos));
13532 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
13533 row->end.dpvec_index);
13534 }
13535
13536 if (glyphs > 1)
13537 {
13538 int area;
13539
13540 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13541 {
13542 struct glyph *glyph = row->glyphs[area];
13543 struct glyph *glyph_end = glyph + row->used[area];
13544
13545 /* Glyph for a line end in text. */
13546 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
13547 ++glyph_end;
13548
13549 if (glyph < glyph_end)
13550 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
13551
13552 for (; glyph < glyph_end; ++glyph)
13553 dump_glyph (row, glyph, area);
13554 }
13555 }
13556 else if (glyphs == 1)
13557 {
13558 int area;
13559
13560 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13561 {
13562 char *s = (char *) alloca (row->used[area] + 1);
13563 int i;
13564
13565 for (i = 0; i < row->used[area]; ++i)
13566 {
13567 struct glyph *glyph = row->glyphs[area] + i;
13568 if (glyph->type == CHAR_GLYPH
13569 && glyph->u.ch < 0x80
13570 && glyph->u.ch >= ' ')
13571 s[i] = glyph->u.ch;
13572 else
13573 s[i] = '.';
13574 }
13575
13576 s[i] = '\0';
13577 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
13578 }
13579 }
13580 }
13581
13582
13583 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
13584 Sdump_glyph_matrix, 0, 1, "p",
13585 doc: /* Dump the current matrix of the selected window to stderr.
13586 Shows contents of glyph row structures. With non-nil
13587 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
13588 glyphs in short form, otherwise show glyphs in long form. */)
13589 (glyphs)
13590 Lisp_Object glyphs;
13591 {
13592 struct window *w = XWINDOW (selected_window);
13593 struct buffer *buffer = XBUFFER (w->buffer);
13594
13595 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
13596 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
13597 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
13598 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
13599 fprintf (stderr, "=============================================\n");
13600 dump_glyph_matrix (w->current_matrix,
13601 NILP (glyphs) ? 0 : XINT (glyphs));
13602 return Qnil;
13603 }
13604
13605
13606 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
13607 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
13608 ()
13609 {
13610 struct frame *f = XFRAME (selected_frame);
13611 dump_glyph_matrix (f->current_matrix, 1);
13612 return Qnil;
13613 }
13614
13615
13616 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
13617 doc: /* Dump glyph row ROW to stderr.
13618 GLYPH 0 means don't dump glyphs.
13619 GLYPH 1 means dump glyphs in short form.
13620 GLYPH > 1 or omitted means dump glyphs in long form. */)
13621 (row, glyphs)
13622 Lisp_Object row, glyphs;
13623 {
13624 struct glyph_matrix *matrix;
13625 int vpos;
13626
13627 CHECK_NUMBER (row);
13628 matrix = XWINDOW (selected_window)->current_matrix;
13629 vpos = XINT (row);
13630 if (vpos >= 0 && vpos < matrix->nrows)
13631 dump_glyph_row (MATRIX_ROW (matrix, vpos),
13632 vpos,
13633 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13634 return Qnil;
13635 }
13636
13637
13638 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
13639 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
13640 GLYPH 0 means don't dump glyphs.
13641 GLYPH 1 means dump glyphs in short form.
13642 GLYPH > 1 or omitted means dump glyphs in long form. */)
13643 (row, glyphs)
13644 Lisp_Object row, glyphs;
13645 {
13646 struct frame *sf = SELECTED_FRAME ();
13647 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
13648 int vpos;
13649
13650 CHECK_NUMBER (row);
13651 vpos = XINT (row);
13652 if (vpos >= 0 && vpos < m->nrows)
13653 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
13654 INTEGERP (glyphs) ? XINT (glyphs) : 2);
13655 return Qnil;
13656 }
13657
13658
13659 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
13660 doc: /* Toggle tracing of redisplay.
13661 With ARG, turn tracing on if and only if ARG is positive. */)
13662 (arg)
13663 Lisp_Object arg;
13664 {
13665 if (NILP (arg))
13666 trace_redisplay_p = !trace_redisplay_p;
13667 else
13668 {
13669 arg = Fprefix_numeric_value (arg);
13670 trace_redisplay_p = XINT (arg) > 0;
13671 }
13672
13673 return Qnil;
13674 }
13675
13676
13677 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
13678 doc: /* Like `format', but print result to stderr.
13679 usage: (trace-to-stderr STRING &rest OBJECTS) */)
13680 (nargs, args)
13681 int nargs;
13682 Lisp_Object *args;
13683 {
13684 Lisp_Object s = Fformat (nargs, args);
13685 fprintf (stderr, "%s", SDATA (s));
13686 return Qnil;
13687 }
13688
13689 #endif /* GLYPH_DEBUG */
13690
13691
13692 \f
13693 /***********************************************************************
13694 Building Desired Matrix Rows
13695 ***********************************************************************/
13696
13697 /* Return a temporary glyph row holding the glyphs of an overlay
13698 arrow. Only used for non-window-redisplay windows. */
13699
13700 static struct glyph_row *
13701 get_overlay_arrow_glyph_row (w)
13702 struct window *w;
13703 {
13704 struct frame *f = XFRAME (WINDOW_FRAME (w));
13705 struct buffer *buffer = XBUFFER (w->buffer);
13706 struct buffer *old = current_buffer;
13707 const unsigned char *arrow_string = SDATA (Voverlay_arrow_string);
13708 int arrow_len = SCHARS (Voverlay_arrow_string);
13709 const unsigned char *arrow_end = arrow_string + arrow_len;
13710 const unsigned char *p;
13711 struct it it;
13712 int multibyte_p;
13713 int n_glyphs_before;
13714
13715 set_buffer_temp (buffer);
13716 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
13717 it.glyph_row->used[TEXT_AREA] = 0;
13718 SET_TEXT_POS (it.position, 0, 0);
13719
13720 multibyte_p = !NILP (buffer->enable_multibyte_characters);
13721 p = arrow_string;
13722 while (p < arrow_end)
13723 {
13724 Lisp_Object face, ilisp;
13725
13726 /* Get the next character. */
13727 if (multibyte_p)
13728 it.c = string_char_and_length (p, arrow_len, &it.len);
13729 else
13730 it.c = *p, it.len = 1;
13731 p += it.len;
13732
13733 /* Get its face. */
13734 ilisp = make_number (p - arrow_string);
13735 face = Fget_text_property (ilisp, Qface, Voverlay_arrow_string);
13736 it.face_id = compute_char_face (f, it.c, face);
13737
13738 /* Compute its width, get its glyphs. */
13739 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
13740 SET_TEXT_POS (it.position, -1, -1);
13741 PRODUCE_GLYPHS (&it);
13742
13743 /* If this character doesn't fit any more in the line, we have
13744 to remove some glyphs. */
13745 if (it.current_x > it.last_visible_x)
13746 {
13747 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
13748 break;
13749 }
13750 }
13751
13752 set_buffer_temp (old);
13753 return it.glyph_row;
13754 }
13755
13756
13757 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
13758 glyphs are only inserted for terminal frames since we can't really
13759 win with truncation glyphs when partially visible glyphs are
13760 involved. Which glyphs to insert is determined by
13761 produce_special_glyphs. */
13762
13763 static void
13764 insert_left_trunc_glyphs (it)
13765 struct it *it;
13766 {
13767 struct it truncate_it;
13768 struct glyph *from, *end, *to, *toend;
13769
13770 xassert (!FRAME_WINDOW_P (it->f));
13771
13772 /* Get the truncation glyphs. */
13773 truncate_it = *it;
13774 truncate_it.current_x = 0;
13775 truncate_it.face_id = DEFAULT_FACE_ID;
13776 truncate_it.glyph_row = &scratch_glyph_row;
13777 truncate_it.glyph_row->used[TEXT_AREA] = 0;
13778 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
13779 truncate_it.object = make_number (0);
13780 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
13781
13782 /* Overwrite glyphs from IT with truncation glyphs. */
13783 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13784 end = from + truncate_it.glyph_row->used[TEXT_AREA];
13785 to = it->glyph_row->glyphs[TEXT_AREA];
13786 toend = to + it->glyph_row->used[TEXT_AREA];
13787
13788 while (from < end)
13789 *to++ = *from++;
13790
13791 /* There may be padding glyphs left over. Overwrite them too. */
13792 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
13793 {
13794 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
13795 while (from < end)
13796 *to++ = *from++;
13797 }
13798
13799 if (to > toend)
13800 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
13801 }
13802
13803
13804 /* Compute the pixel height and width of IT->glyph_row.
13805
13806 Most of the time, ascent and height of a display line will be equal
13807 to the max_ascent and max_height values of the display iterator
13808 structure. This is not the case if
13809
13810 1. We hit ZV without displaying anything. In this case, max_ascent
13811 and max_height will be zero.
13812
13813 2. We have some glyphs that don't contribute to the line height.
13814 (The glyph row flag contributes_to_line_height_p is for future
13815 pixmap extensions).
13816
13817 The first case is easily covered by using default values because in
13818 these cases, the line height does not really matter, except that it
13819 must not be zero. */
13820
13821 static void
13822 compute_line_metrics (it)
13823 struct it *it;
13824 {
13825 struct glyph_row *row = it->glyph_row;
13826 int area, i;
13827
13828 if (FRAME_WINDOW_P (it->f))
13829 {
13830 int i, min_y, max_y;
13831
13832 /* The line may consist of one space only, that was added to
13833 place the cursor on it. If so, the row's height hasn't been
13834 computed yet. */
13835 if (row->height == 0)
13836 {
13837 if (it->max_ascent + it->max_descent == 0)
13838 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
13839 row->ascent = it->max_ascent;
13840 row->height = it->max_ascent + it->max_descent;
13841 row->phys_ascent = it->max_phys_ascent;
13842 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
13843 }
13844
13845 /* Compute the width of this line. */
13846 row->pixel_width = row->x;
13847 for (i = 0; i < row->used[TEXT_AREA]; ++i)
13848 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
13849
13850 xassert (row->pixel_width >= 0);
13851 xassert (row->ascent >= 0 && row->height > 0);
13852
13853 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
13854 || MATRIX_ROW_OVERLAPS_PRED_P (row));
13855
13856 /* If first line's physical ascent is larger than its logical
13857 ascent, use the physical ascent, and make the row taller.
13858 This makes accented characters fully visible. */
13859 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
13860 && row->phys_ascent > row->ascent)
13861 {
13862 row->height += row->phys_ascent - row->ascent;
13863 row->ascent = row->phys_ascent;
13864 }
13865
13866 /* Compute how much of the line is visible. */
13867 row->visible_height = row->height;
13868
13869 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
13870 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
13871
13872 if (row->y < min_y)
13873 row->visible_height -= min_y - row->y;
13874 if (row->y + row->height > max_y)
13875 row->visible_height -= row->y + row->height - max_y;
13876 }
13877 else
13878 {
13879 row->pixel_width = row->used[TEXT_AREA];
13880 if (row->continued_p)
13881 row->pixel_width -= it->continuation_pixel_width;
13882 else if (row->truncated_on_right_p)
13883 row->pixel_width -= it->truncation_pixel_width;
13884 row->ascent = row->phys_ascent = 0;
13885 row->height = row->phys_height = row->visible_height = 1;
13886 }
13887
13888 /* Compute a hash code for this row. */
13889 row->hash = 0;
13890 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
13891 for (i = 0; i < row->used[area]; ++i)
13892 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
13893 + row->glyphs[area][i].u.val
13894 + row->glyphs[area][i].face_id
13895 + row->glyphs[area][i].padding_p
13896 + (row->glyphs[area][i].type << 2));
13897
13898 it->max_ascent = it->max_descent = 0;
13899 it->max_phys_ascent = it->max_phys_descent = 0;
13900 }
13901
13902
13903 /* Append one space to the glyph row of iterator IT if doing a
13904 window-based redisplay. DEFAULT_FACE_P non-zero means let the
13905 space have the default face, otherwise let it have the same face as
13906 IT->face_id. Value is non-zero if a space was added.
13907
13908 This function is called to make sure that there is always one glyph
13909 at the end of a glyph row that the cursor can be set on under
13910 window-systems. (If there weren't such a glyph we would not know
13911 how wide and tall a box cursor should be displayed).
13912
13913 At the same time this space let's a nicely handle clearing to the
13914 end of the line if the row ends in italic text. */
13915
13916 static int
13917 append_space (it, default_face_p)
13918 struct it *it;
13919 int default_face_p;
13920 {
13921 if (FRAME_WINDOW_P (it->f))
13922 {
13923 int n = it->glyph_row->used[TEXT_AREA];
13924
13925 if (it->glyph_row->glyphs[TEXT_AREA] + n
13926 < it->glyph_row->glyphs[1 + TEXT_AREA])
13927 {
13928 /* Save some values that must not be changed.
13929 Must save IT->c and IT->len because otherwise
13930 ITERATOR_AT_END_P wouldn't work anymore after
13931 append_space has been called. */
13932 enum display_element_type saved_what = it->what;
13933 int saved_c = it->c, saved_len = it->len;
13934 int saved_x = it->current_x;
13935 int saved_face_id = it->face_id;
13936 struct text_pos saved_pos;
13937 Lisp_Object saved_object;
13938 struct face *face;
13939
13940 saved_object = it->object;
13941 saved_pos = it->position;
13942
13943 it->what = IT_CHARACTER;
13944 bzero (&it->position, sizeof it->position);
13945 it->object = make_number (0);
13946 it->c = ' ';
13947 it->len = 1;
13948
13949 if (default_face_p)
13950 it->face_id = DEFAULT_FACE_ID;
13951 else if (it->face_before_selective_p)
13952 it->face_id = it->saved_face_id;
13953 face = FACE_FROM_ID (it->f, it->face_id);
13954 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
13955
13956 PRODUCE_GLYPHS (it);
13957
13958 it->current_x = saved_x;
13959 it->object = saved_object;
13960 it->position = saved_pos;
13961 it->what = saved_what;
13962 it->face_id = saved_face_id;
13963 it->len = saved_len;
13964 it->c = saved_c;
13965 return 1;
13966 }
13967 }
13968
13969 return 0;
13970 }
13971
13972
13973 /* Extend the face of the last glyph in the text area of IT->glyph_row
13974 to the end of the display line. Called from display_line.
13975 If the glyph row is empty, add a space glyph to it so that we
13976 know the face to draw. Set the glyph row flag fill_line_p. */
13977
13978 static void
13979 extend_face_to_end_of_line (it)
13980 struct it *it;
13981 {
13982 struct face *face;
13983 struct frame *f = it->f;
13984
13985 /* If line is already filled, do nothing. */
13986 if (it->current_x >= it->last_visible_x)
13987 return;
13988
13989 /* Face extension extends the background and box of IT->face_id
13990 to the end of the line. If the background equals the background
13991 of the frame, we don't have to do anything. */
13992 if (it->face_before_selective_p)
13993 face = FACE_FROM_ID (it->f, it->saved_face_id);
13994 else
13995 face = FACE_FROM_ID (f, it->face_id);
13996
13997 if (FRAME_WINDOW_P (f)
13998 && face->box == FACE_NO_BOX
13999 && face->background == FRAME_BACKGROUND_PIXEL (f)
14000 && !face->stipple)
14001 return;
14002
14003 /* Set the glyph row flag indicating that the face of the last glyph
14004 in the text area has to be drawn to the end of the text area. */
14005 it->glyph_row->fill_line_p = 1;
14006
14007 /* If current character of IT is not ASCII, make sure we have the
14008 ASCII face. This will be automatically undone the next time
14009 get_next_display_element returns a multibyte character. Note
14010 that the character will always be single byte in unibyte text. */
14011 if (!SINGLE_BYTE_CHAR_P (it->c))
14012 {
14013 it->face_id = FACE_FOR_CHAR (f, face, 0);
14014 }
14015
14016 if (FRAME_WINDOW_P (f))
14017 {
14018 /* If the row is empty, add a space with the current face of IT,
14019 so that we know which face to draw. */
14020 if (it->glyph_row->used[TEXT_AREA] == 0)
14021 {
14022 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14023 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14024 it->glyph_row->used[TEXT_AREA] = 1;
14025 }
14026 }
14027 else
14028 {
14029 /* Save some values that must not be changed. */
14030 int saved_x = it->current_x;
14031 struct text_pos saved_pos;
14032 Lisp_Object saved_object;
14033 enum display_element_type saved_what = it->what;
14034 int saved_face_id = it->face_id;
14035
14036 saved_object = it->object;
14037 saved_pos = it->position;
14038
14039 it->what = IT_CHARACTER;
14040 bzero (&it->position, sizeof it->position);
14041 it->object = make_number (0);
14042 it->c = ' ';
14043 it->len = 1;
14044 it->face_id = face->id;
14045
14046 PRODUCE_GLYPHS (it);
14047
14048 while (it->current_x <= it->last_visible_x)
14049 PRODUCE_GLYPHS (it);
14050
14051 /* Don't count these blanks really. It would let us insert a left
14052 truncation glyph below and make us set the cursor on them, maybe. */
14053 it->current_x = saved_x;
14054 it->object = saved_object;
14055 it->position = saved_pos;
14056 it->what = saved_what;
14057 it->face_id = saved_face_id;
14058 }
14059 }
14060
14061
14062 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14063 trailing whitespace. */
14064
14065 static int
14066 trailing_whitespace_p (charpos)
14067 int charpos;
14068 {
14069 int bytepos = CHAR_TO_BYTE (charpos);
14070 int c = 0;
14071
14072 while (bytepos < ZV_BYTE
14073 && (c = FETCH_CHAR (bytepos),
14074 c == ' ' || c == '\t'))
14075 ++bytepos;
14076
14077 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14078 {
14079 if (bytepos != PT_BYTE)
14080 return 1;
14081 }
14082 return 0;
14083 }
14084
14085
14086 /* Highlight trailing whitespace, if any, in ROW. */
14087
14088 void
14089 highlight_trailing_whitespace (f, row)
14090 struct frame *f;
14091 struct glyph_row *row;
14092 {
14093 int used = row->used[TEXT_AREA];
14094
14095 if (used)
14096 {
14097 struct glyph *start = row->glyphs[TEXT_AREA];
14098 struct glyph *glyph = start + used - 1;
14099
14100 /* Skip over glyphs inserted to display the cursor at the
14101 end of a line, for extending the face of the last glyph
14102 to the end of the line on terminals, and for truncation
14103 and continuation glyphs. */
14104 while (glyph >= start
14105 && glyph->type == CHAR_GLYPH
14106 && INTEGERP (glyph->object))
14107 --glyph;
14108
14109 /* If last glyph is a space or stretch, and it's trailing
14110 whitespace, set the face of all trailing whitespace glyphs in
14111 IT->glyph_row to `trailing-whitespace'. */
14112 if (glyph >= start
14113 && BUFFERP (glyph->object)
14114 && (glyph->type == STRETCH_GLYPH
14115 || (glyph->type == CHAR_GLYPH
14116 && glyph->u.ch == ' '))
14117 && trailing_whitespace_p (glyph->charpos))
14118 {
14119 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0);
14120
14121 while (glyph >= start
14122 && BUFFERP (glyph->object)
14123 && (glyph->type == STRETCH_GLYPH
14124 || (glyph->type == CHAR_GLYPH
14125 && glyph->u.ch == ' ')))
14126 (glyph--)->face_id = face_id;
14127 }
14128 }
14129 }
14130
14131
14132 /* Value is non-zero if glyph row ROW in window W should be
14133 used to hold the cursor. */
14134
14135 static int
14136 cursor_row_p (w, row)
14137 struct window *w;
14138 struct glyph_row *row;
14139 {
14140 int cursor_row_p = 1;
14141
14142 if (PT == MATRIX_ROW_END_CHARPOS (row))
14143 {
14144 /* If the row ends with a newline from a string, we don't want
14145 the cursor there (if the row is continued it doesn't end in a
14146 newline). */
14147 if (CHARPOS (row->end.string_pos) >= 0
14148 || MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14149 cursor_row_p = row->continued_p;
14150
14151 /* If the row ends at ZV, display the cursor at the end of that
14152 row instead of at the start of the row below. */
14153 else if (row->ends_at_zv_p)
14154 cursor_row_p = 1;
14155 else
14156 cursor_row_p = 0;
14157 }
14158
14159 return cursor_row_p;
14160 }
14161
14162
14163 /* Construct the glyph row IT->glyph_row in the desired matrix of
14164 IT->w from text at the current position of IT. See dispextern.h
14165 for an overview of struct it. Value is non-zero if
14166 IT->glyph_row displays text, as opposed to a line displaying ZV
14167 only. */
14168
14169 static int
14170 display_line (it)
14171 struct it *it;
14172 {
14173 struct glyph_row *row = it->glyph_row;
14174
14175 /* We always start displaying at hpos zero even if hscrolled. */
14176 xassert (it->hpos == 0 && it->current_x == 0);
14177
14178 /* We must not display in a row that's not a text row. */
14179 xassert (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14180 < it->w->desired_matrix->nrows);
14181
14182 /* Is IT->w showing the region? */
14183 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14184
14185 /* Clear the result glyph row and enable it. */
14186 prepare_desired_row (row);
14187
14188 row->y = it->current_y;
14189 row->start = it->start;
14190 row->continuation_lines_width = it->continuation_lines_width;
14191 row->displays_text_p = 1;
14192 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14193 it->starts_in_middle_of_char_p = 0;
14194
14195 /* Arrange the overlays nicely for our purposes. Usually, we call
14196 display_line on only one line at a time, in which case this
14197 can't really hurt too much, or we call it on lines which appear
14198 one after another in the buffer, in which case all calls to
14199 recenter_overlay_lists but the first will be pretty cheap. */
14200 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14201
14202 /* Move over display elements that are not visible because we are
14203 hscrolled. This may stop at an x-position < IT->first_visible_x
14204 if the first glyph is partially visible or if we hit a line end. */
14205 if (it->current_x < it->first_visible_x)
14206 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14207 MOVE_TO_POS | MOVE_TO_X);
14208
14209 /* Get the initial row height. This is either the height of the
14210 text hscrolled, if there is any, or zero. */
14211 row->ascent = it->max_ascent;
14212 row->height = it->max_ascent + it->max_descent;
14213 row->phys_ascent = it->max_phys_ascent;
14214 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14215
14216 /* Loop generating characters. The loop is left with IT on the next
14217 character to display. */
14218 while (1)
14219 {
14220 int n_glyphs_before, hpos_before, x_before;
14221 int x, i, nglyphs;
14222 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14223
14224 /* Retrieve the next thing to display. Value is zero if end of
14225 buffer reached. */
14226 if (!get_next_display_element (it))
14227 {
14228 /* Maybe add a space at the end of this line that is used to
14229 display the cursor there under X. Set the charpos of the
14230 first glyph of blank lines not corresponding to any text
14231 to -1. */
14232 #ifdef HAVE_WINDOW_SYSTEM
14233 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14234 row->exact_window_width_line_p = 1;
14235 else
14236 #endif /* HAVE_WINDOW_SYSTEM */
14237 if ((append_space (it, 1) && row->used[TEXT_AREA] == 1)
14238 || row->used[TEXT_AREA] == 0)
14239 {
14240 row->glyphs[TEXT_AREA]->charpos = -1;
14241 row->displays_text_p = 0;
14242
14243 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14244 && (!MINI_WINDOW_P (it->w)
14245 || (minibuf_level && EQ (it->window, minibuf_window))))
14246 row->indicate_empty_line_p = 1;
14247 }
14248
14249 it->continuation_lines_width = 0;
14250 row->ends_at_zv_p = 1;
14251 break;
14252 }
14253
14254 /* Now, get the metrics of what we want to display. This also
14255 generates glyphs in `row' (which is IT->glyph_row). */
14256 n_glyphs_before = row->used[TEXT_AREA];
14257 x = it->current_x;
14258
14259 /* Remember the line height so far in case the next element doesn't
14260 fit on the line. */
14261 if (!it->truncate_lines_p)
14262 {
14263 ascent = it->max_ascent;
14264 descent = it->max_descent;
14265 phys_ascent = it->max_phys_ascent;
14266 phys_descent = it->max_phys_descent;
14267 }
14268
14269 PRODUCE_GLYPHS (it);
14270
14271 /* If this display element was in marginal areas, continue with
14272 the next one. */
14273 if (it->area != TEXT_AREA)
14274 {
14275 row->ascent = max (row->ascent, it->max_ascent);
14276 row->height = max (row->height, it->max_ascent + it->max_descent);
14277 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14278 row->phys_height = max (row->phys_height,
14279 it->max_phys_ascent + it->max_phys_descent);
14280 set_iterator_to_next (it, 1);
14281 continue;
14282 }
14283
14284 /* Does the display element fit on the line? If we truncate
14285 lines, we should draw past the right edge of the window. If
14286 we don't truncate, we want to stop so that we can display the
14287 continuation glyph before the right margin. If lines are
14288 continued, there are two possible strategies for characters
14289 resulting in more than 1 glyph (e.g. tabs): Display as many
14290 glyphs as possible in this line and leave the rest for the
14291 continuation line, or display the whole element in the next
14292 line. Original redisplay did the former, so we do it also. */
14293 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14294 hpos_before = it->hpos;
14295 x_before = x;
14296
14297 if (/* Not a newline. */
14298 nglyphs > 0
14299 /* Glyphs produced fit entirely in the line. */
14300 && it->current_x < it->last_visible_x)
14301 {
14302 it->hpos += nglyphs;
14303 row->ascent = max (row->ascent, it->max_ascent);
14304 row->height = max (row->height, it->max_ascent + it->max_descent);
14305 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14306 row->phys_height = max (row->phys_height,
14307 it->max_phys_ascent + it->max_phys_descent);
14308 if (it->current_x - it->pixel_width < it->first_visible_x)
14309 row->x = x - it->first_visible_x;
14310 }
14311 else
14312 {
14313 int new_x;
14314 struct glyph *glyph;
14315
14316 for (i = 0; i < nglyphs; ++i, x = new_x)
14317 {
14318 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
14319 new_x = x + glyph->pixel_width;
14320
14321 if (/* Lines are continued. */
14322 !it->truncate_lines_p
14323 && (/* Glyph doesn't fit on the line. */
14324 new_x > it->last_visible_x
14325 /* Or it fits exactly on a window system frame. */
14326 || (new_x == it->last_visible_x
14327 && FRAME_WINDOW_P (it->f))))
14328 {
14329 /* End of a continued line. */
14330
14331 if (it->hpos == 0
14332 || (new_x == it->last_visible_x
14333 && FRAME_WINDOW_P (it->f)))
14334 {
14335 /* Current glyph is the only one on the line or
14336 fits exactly on the line. We must continue
14337 the line because we can't draw the cursor
14338 after the glyph. */
14339 row->continued_p = 1;
14340 it->current_x = new_x;
14341 it->continuation_lines_width += new_x;
14342 ++it->hpos;
14343 if (i == nglyphs - 1)
14344 {
14345 set_iterator_to_next (it, 1);
14346 #ifdef HAVE_WINDOW_SYSTEM
14347 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14348 {
14349 if (!get_next_display_element (it))
14350 {
14351 row->exact_window_width_line_p = 1;
14352 it->continuation_lines_width = 0;
14353 row->continued_p = 0;
14354 row->ends_at_zv_p = 1;
14355 }
14356 else if (ITERATOR_AT_END_OF_LINE_P (it))
14357 {
14358 row->continued_p = 0;
14359 row->exact_window_width_line_p = 1;
14360 }
14361 }
14362 #endif /* HAVE_WINDOW_SYSTEM */
14363 }
14364 }
14365 else if (CHAR_GLYPH_PADDING_P (*glyph)
14366 && !FRAME_WINDOW_P (it->f))
14367 {
14368 /* A padding glyph that doesn't fit on this line.
14369 This means the whole character doesn't fit
14370 on the line. */
14371 row->used[TEXT_AREA] = n_glyphs_before;
14372
14373 /* Fill the rest of the row with continuation
14374 glyphs like in 20.x. */
14375 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
14376 < row->glyphs[1 + TEXT_AREA])
14377 produce_special_glyphs (it, IT_CONTINUATION);
14378
14379 row->continued_p = 1;
14380 it->current_x = x_before;
14381 it->continuation_lines_width += x_before;
14382
14383 /* Restore the height to what it was before the
14384 element not fitting on the line. */
14385 it->max_ascent = ascent;
14386 it->max_descent = descent;
14387 it->max_phys_ascent = phys_ascent;
14388 it->max_phys_descent = phys_descent;
14389 }
14390 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
14391 {
14392 /* A TAB that extends past the right edge of the
14393 window. This produces a single glyph on
14394 window system frames. We leave the glyph in
14395 this row and let it fill the row, but don't
14396 consume the TAB. */
14397 it->continuation_lines_width += it->last_visible_x;
14398 row->ends_in_middle_of_char_p = 1;
14399 row->continued_p = 1;
14400 glyph->pixel_width = it->last_visible_x - x;
14401 it->starts_in_middle_of_char_p = 1;
14402 }
14403 else
14404 {
14405 /* Something other than a TAB that draws past
14406 the right edge of the window. Restore
14407 positions to values before the element. */
14408 row->used[TEXT_AREA] = n_glyphs_before + i;
14409
14410 /* Display continuation glyphs. */
14411 if (!FRAME_WINDOW_P (it->f))
14412 produce_special_glyphs (it, IT_CONTINUATION);
14413 row->continued_p = 1;
14414
14415 it->continuation_lines_width += x;
14416
14417 if (nglyphs > 1 && i > 0)
14418 {
14419 row->ends_in_middle_of_char_p = 1;
14420 it->starts_in_middle_of_char_p = 1;
14421 }
14422
14423 /* Restore the height to what it was before the
14424 element not fitting on the line. */
14425 it->max_ascent = ascent;
14426 it->max_descent = descent;
14427 it->max_phys_ascent = phys_ascent;
14428 it->max_phys_descent = phys_descent;
14429 }
14430
14431 break;
14432 }
14433 else if (new_x > it->first_visible_x)
14434 {
14435 /* Increment number of glyphs actually displayed. */
14436 ++it->hpos;
14437
14438 if (x < it->first_visible_x)
14439 /* Glyph is partially visible, i.e. row starts at
14440 negative X position. */
14441 row->x = x - it->first_visible_x;
14442 }
14443 else
14444 {
14445 /* Glyph is completely off the left margin of the
14446 window. This should not happen because of the
14447 move_it_in_display_line at the start of this
14448 function, unless the text display area of the
14449 window is empty. */
14450 xassert (it->first_visible_x <= it->last_visible_x);
14451 }
14452 }
14453
14454 row->ascent = max (row->ascent, it->max_ascent);
14455 row->height = max (row->height, it->max_ascent + it->max_descent);
14456 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14457 row->phys_height = max (row->phys_height,
14458 it->max_phys_ascent + it->max_phys_descent);
14459
14460 /* End of this display line if row is continued. */
14461 if (row->continued_p || row->ends_at_zv_p)
14462 break;
14463 }
14464
14465 at_end_of_line:
14466 /* Is this a line end? If yes, we're also done, after making
14467 sure that a non-default face is extended up to the right
14468 margin of the window. */
14469 if (ITERATOR_AT_END_OF_LINE_P (it))
14470 {
14471 int used_before = row->used[TEXT_AREA];
14472
14473 row->ends_in_newline_from_string_p = STRINGP (it->object);
14474
14475 #ifdef HAVE_WINDOW_SYSTEM
14476 /* Add a space at the end of the line that is used to
14477 display the cursor there. */
14478 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14479 append_space (it, 0);
14480 #endif /* HAVE_WINDOW_SYSTEM */
14481
14482 /* Extend the face to the end of the line. */
14483 extend_face_to_end_of_line (it);
14484
14485 /* Make sure we have the position. */
14486 if (used_before == 0)
14487 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
14488
14489 /* Consume the line end. This skips over invisible lines. */
14490 set_iterator_to_next (it, 1);
14491 it->continuation_lines_width = 0;
14492 break;
14493 }
14494
14495 /* Proceed with next display element. Note that this skips
14496 over lines invisible because of selective display. */
14497 set_iterator_to_next (it, 1);
14498
14499 /* If we truncate lines, we are done when the last displayed
14500 glyphs reach past the right margin of the window. */
14501 if (it->truncate_lines_p
14502 && (FRAME_WINDOW_P (it->f)
14503 ? (it->current_x >= it->last_visible_x)
14504 : (it->current_x > it->last_visible_x)))
14505 {
14506 /* Maybe add truncation glyphs. */
14507 if (!FRAME_WINDOW_P (it->f))
14508 {
14509 int i, n;
14510
14511 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
14512 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
14513 break;
14514
14515 for (n = row->used[TEXT_AREA]; i < n; ++i)
14516 {
14517 row->used[TEXT_AREA] = i;
14518 produce_special_glyphs (it, IT_TRUNCATION);
14519 }
14520 }
14521 #ifdef HAVE_WINDOW_SYSTEM
14522 else
14523 {
14524 /* Don't truncate if we can overflow newline into fringe. */
14525 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14526 {
14527 if (!get_next_display_element (it))
14528 {
14529 #ifdef HAVE_WINDOW_SYSTEM
14530 it->continuation_lines_width = 0;
14531 row->ends_at_zv_p = 1;
14532 row->exact_window_width_line_p = 1;
14533 break;
14534 #endif /* HAVE_WINDOW_SYSTEM */
14535 }
14536 if (ITERATOR_AT_END_OF_LINE_P (it))
14537 {
14538 row->exact_window_width_line_p = 1;
14539 goto at_end_of_line;
14540 }
14541 }
14542 }
14543 #endif /* HAVE_WINDOW_SYSTEM */
14544
14545 row->truncated_on_right_p = 1;
14546 it->continuation_lines_width = 0;
14547 reseat_at_next_visible_line_start (it, 0);
14548 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
14549 it->hpos = hpos_before;
14550 it->current_x = x_before;
14551 break;
14552 }
14553 }
14554
14555 /* If line is not empty and hscrolled, maybe insert truncation glyphs
14556 at the left window margin. */
14557 if (it->first_visible_x
14558 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
14559 {
14560 if (!FRAME_WINDOW_P (it->f))
14561 insert_left_trunc_glyphs (it);
14562 row->truncated_on_left_p = 1;
14563 }
14564
14565 /* If the start of this line is the overlay arrow-position, then
14566 mark this glyph row as the one containing the overlay arrow.
14567 This is clearly a mess with variable size fonts. It would be
14568 better to let it be displayed like cursors under X. */
14569 if (MARKERP (Voverlay_arrow_position)
14570 && current_buffer == XMARKER (Voverlay_arrow_position)->buffer
14571 && (MATRIX_ROW_START_CHARPOS (row)
14572 == marker_position (Voverlay_arrow_position))
14573 && STRINGP (Voverlay_arrow_string)
14574 && ! overlay_arrow_seen)
14575 {
14576 /* Overlay arrow in window redisplay is a fringe bitmap. */
14577 if (!FRAME_WINDOW_P (it->f))
14578 {
14579 struct glyph_row *arrow_row = get_overlay_arrow_glyph_row (it->w);
14580 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
14581 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
14582 struct glyph *p = row->glyphs[TEXT_AREA];
14583 struct glyph *p2, *end;
14584
14585 /* Copy the arrow glyphs. */
14586 while (glyph < arrow_end)
14587 *p++ = *glyph++;
14588
14589 /* Throw away padding glyphs. */
14590 p2 = p;
14591 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
14592 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
14593 ++p2;
14594 if (p2 > p)
14595 {
14596 while (p2 < end)
14597 *p++ = *p2++;
14598 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
14599 }
14600 }
14601
14602 overlay_arrow_seen = 1;
14603 row->overlay_arrow_p = 1;
14604 }
14605
14606 /* Compute pixel dimensions of this line. */
14607 compute_line_metrics (it);
14608
14609 /* Remember the position at which this line ends. */
14610 row->end = it->current;
14611
14612 /* Save fringe bitmaps in this row. */
14613 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
14614 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
14615 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
14616 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
14617
14618 it->left_user_fringe_bitmap = 0;
14619 it->left_user_fringe_face_id = 0;
14620 it->right_user_fringe_bitmap = 0;
14621 it->right_user_fringe_face_id = 0;
14622
14623 /* Maybe set the cursor. */
14624 if (it->w->cursor.vpos < 0
14625 && PT >= MATRIX_ROW_START_CHARPOS (row)
14626 && PT <= MATRIX_ROW_END_CHARPOS (row)
14627 && cursor_row_p (it->w, row))
14628 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
14629
14630 /* Highlight trailing whitespace. */
14631 if (!NILP (Vshow_trailing_whitespace))
14632 highlight_trailing_whitespace (it->f, it->glyph_row);
14633
14634 /* Prepare for the next line. This line starts horizontally at (X
14635 HPOS) = (0 0). Vertical positions are incremented. As a
14636 convenience for the caller, IT->glyph_row is set to the next
14637 row to be used. */
14638 it->current_x = it->hpos = 0;
14639 it->current_y += row->height;
14640 ++it->vpos;
14641 ++it->glyph_row;
14642 it->start = it->current;
14643 return row->displays_text_p;
14644 }
14645
14646
14647 \f
14648 /***********************************************************************
14649 Menu Bar
14650 ***********************************************************************/
14651
14652 /* Redisplay the menu bar in the frame for window W.
14653
14654 The menu bar of X frames that don't have X toolkit support is
14655 displayed in a special window W->frame->menu_bar_window.
14656
14657 The menu bar of terminal frames is treated specially as far as
14658 glyph matrices are concerned. Menu bar lines are not part of
14659 windows, so the update is done directly on the frame matrix rows
14660 for the menu bar. */
14661
14662 static void
14663 display_menu_bar (w)
14664 struct window *w;
14665 {
14666 struct frame *f = XFRAME (WINDOW_FRAME (w));
14667 struct it it;
14668 Lisp_Object items;
14669 int i;
14670
14671 /* Don't do all this for graphical frames. */
14672 #ifdef HAVE_NTGUI
14673 if (!NILP (Vwindow_system))
14674 return;
14675 #endif
14676 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
14677 if (FRAME_X_P (f))
14678 return;
14679 #endif
14680 #ifdef MAC_OS
14681 if (FRAME_MAC_P (f))
14682 return;
14683 #endif
14684
14685 #ifdef USE_X_TOOLKIT
14686 xassert (!FRAME_WINDOW_P (f));
14687 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
14688 it.first_visible_x = 0;
14689 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14690 #else /* not USE_X_TOOLKIT */
14691 if (FRAME_WINDOW_P (f))
14692 {
14693 /* Menu bar lines are displayed in the desired matrix of the
14694 dummy window menu_bar_window. */
14695 struct window *menu_w;
14696 xassert (WINDOWP (f->menu_bar_window));
14697 menu_w = XWINDOW (f->menu_bar_window);
14698 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
14699 MENU_FACE_ID);
14700 it.first_visible_x = 0;
14701 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
14702 }
14703 else
14704 {
14705 /* This is a TTY frame, i.e. character hpos/vpos are used as
14706 pixel x/y. */
14707 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
14708 MENU_FACE_ID);
14709 it.first_visible_x = 0;
14710 it.last_visible_x = FRAME_COLS (f);
14711 }
14712 #endif /* not USE_X_TOOLKIT */
14713
14714 if (! mode_line_inverse_video)
14715 /* Force the menu-bar to be displayed in the default face. */
14716 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14717
14718 /* Clear all rows of the menu bar. */
14719 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
14720 {
14721 struct glyph_row *row = it.glyph_row + i;
14722 clear_glyph_row (row);
14723 row->enabled_p = 1;
14724 row->full_width_p = 1;
14725 }
14726
14727 /* Display all items of the menu bar. */
14728 items = FRAME_MENU_BAR_ITEMS (it.f);
14729 for (i = 0; i < XVECTOR (items)->size; i += 4)
14730 {
14731 Lisp_Object string;
14732
14733 /* Stop at nil string. */
14734 string = AREF (items, i + 1);
14735 if (NILP (string))
14736 break;
14737
14738 /* Remember where item was displayed. */
14739 AREF (items, i + 3) = make_number (it.hpos);
14740
14741 /* Display the item, pad with one space. */
14742 if (it.current_x < it.last_visible_x)
14743 display_string (NULL, string, Qnil, 0, 0, &it,
14744 SCHARS (string) + 1, 0, 0, -1);
14745 }
14746
14747 /* Fill out the line with spaces. */
14748 if (it.current_x < it.last_visible_x)
14749 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
14750
14751 /* Compute the total height of the lines. */
14752 compute_line_metrics (&it);
14753 }
14754
14755
14756 \f
14757 /***********************************************************************
14758 Mode Line
14759 ***********************************************************************/
14760
14761 /* Redisplay mode lines in the window tree whose root is WINDOW. If
14762 FORCE is non-zero, redisplay mode lines unconditionally.
14763 Otherwise, redisplay only mode lines that are garbaged. Value is
14764 the number of windows whose mode lines were redisplayed. */
14765
14766 static int
14767 redisplay_mode_lines (window, force)
14768 Lisp_Object window;
14769 int force;
14770 {
14771 int nwindows = 0;
14772
14773 while (!NILP (window))
14774 {
14775 struct window *w = XWINDOW (window);
14776
14777 if (WINDOWP (w->hchild))
14778 nwindows += redisplay_mode_lines (w->hchild, force);
14779 else if (WINDOWP (w->vchild))
14780 nwindows += redisplay_mode_lines (w->vchild, force);
14781 else if (force
14782 || FRAME_GARBAGED_P (XFRAME (w->frame))
14783 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
14784 {
14785 struct text_pos lpoint;
14786 struct buffer *old = current_buffer;
14787
14788 /* Set the window's buffer for the mode line display. */
14789 SET_TEXT_POS (lpoint, PT, PT_BYTE);
14790 set_buffer_internal_1 (XBUFFER (w->buffer));
14791
14792 /* Point refers normally to the selected window. For any
14793 other window, set up appropriate value. */
14794 if (!EQ (window, selected_window))
14795 {
14796 struct text_pos pt;
14797
14798 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
14799 if (CHARPOS (pt) < BEGV)
14800 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
14801 else if (CHARPOS (pt) > (ZV - 1))
14802 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
14803 else
14804 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
14805 }
14806
14807 /* Display mode lines. */
14808 clear_glyph_matrix (w->desired_matrix);
14809 if (display_mode_lines (w))
14810 {
14811 ++nwindows;
14812 w->must_be_updated_p = 1;
14813 }
14814
14815 /* Restore old settings. */
14816 set_buffer_internal_1 (old);
14817 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
14818 }
14819
14820 window = w->next;
14821 }
14822
14823 return nwindows;
14824 }
14825
14826
14827 /* Display the mode and/or top line of window W. Value is the number
14828 of mode lines displayed. */
14829
14830 static int
14831 display_mode_lines (w)
14832 struct window *w;
14833 {
14834 Lisp_Object old_selected_window, old_selected_frame;
14835 int n = 0;
14836
14837 old_selected_frame = selected_frame;
14838 selected_frame = w->frame;
14839 old_selected_window = selected_window;
14840 XSETWINDOW (selected_window, w);
14841
14842 /* These will be set while the mode line specs are processed. */
14843 line_number_displayed = 0;
14844 w->column_number_displayed = Qnil;
14845
14846 if (WINDOW_WANTS_MODELINE_P (w))
14847 {
14848 struct window *sel_w = XWINDOW (old_selected_window);
14849
14850 /* Select mode line face based on the real selected window. */
14851 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
14852 current_buffer->mode_line_format);
14853 ++n;
14854 }
14855
14856 if (WINDOW_WANTS_HEADER_LINE_P (w))
14857 {
14858 display_mode_line (w, HEADER_LINE_FACE_ID,
14859 current_buffer->header_line_format);
14860 ++n;
14861 }
14862
14863 selected_frame = old_selected_frame;
14864 selected_window = old_selected_window;
14865 return n;
14866 }
14867
14868
14869 /* Display mode or top line of window W. FACE_ID specifies which line
14870 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
14871 FORMAT is the mode line format to display. Value is the pixel
14872 height of the mode line displayed. */
14873
14874 static int
14875 display_mode_line (w, face_id, format)
14876 struct window *w;
14877 enum face_id face_id;
14878 Lisp_Object format;
14879 {
14880 struct it it;
14881 struct face *face;
14882
14883 init_iterator (&it, w, -1, -1, NULL, face_id);
14884 prepare_desired_row (it.glyph_row);
14885
14886 if (! mode_line_inverse_video)
14887 /* Force the mode-line to be displayed in the default face. */
14888 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
14889
14890 /* Temporarily make frame's keyboard the current kboard so that
14891 kboard-local variables in the mode_line_format will get the right
14892 values. */
14893 push_frame_kboard (it.f);
14894 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
14895 pop_frame_kboard ();
14896
14897 /* Fill up with spaces. */
14898 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
14899
14900 compute_line_metrics (&it);
14901 it.glyph_row->full_width_p = 1;
14902 it.glyph_row->mode_line_p = 1;
14903 it.glyph_row->continued_p = 0;
14904 it.glyph_row->truncated_on_left_p = 0;
14905 it.glyph_row->truncated_on_right_p = 0;
14906
14907 /* Make a 3D mode-line have a shadow at its right end. */
14908 face = FACE_FROM_ID (it.f, face_id);
14909 extend_face_to_end_of_line (&it);
14910 if (face->box != FACE_NO_BOX)
14911 {
14912 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
14913 + it.glyph_row->used[TEXT_AREA] - 1);
14914 last->right_box_line_p = 1;
14915 }
14916
14917 return it.glyph_row->height;
14918 }
14919
14920 /* Alist that caches the results of :propertize.
14921 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
14922 Lisp_Object mode_line_proptrans_alist;
14923
14924 /* List of strings making up the mode-line. */
14925 Lisp_Object mode_line_string_list;
14926
14927 /* Base face property when building propertized mode line string. */
14928 static Lisp_Object mode_line_string_face;
14929 static Lisp_Object mode_line_string_face_prop;
14930
14931
14932 /* Contribute ELT to the mode line for window IT->w. How it
14933 translates into text depends on its data type.
14934
14935 IT describes the display environment in which we display, as usual.
14936
14937 DEPTH is the depth in recursion. It is used to prevent
14938 infinite recursion here.
14939
14940 FIELD_WIDTH is the number of characters the display of ELT should
14941 occupy in the mode line, and PRECISION is the maximum number of
14942 characters to display from ELT's representation. See
14943 display_string for details.
14944
14945 Returns the hpos of the end of the text generated by ELT.
14946
14947 PROPS is a property list to add to any string we encounter.
14948
14949 If RISKY is nonzero, remove (disregard) any properties in any string
14950 we encounter, and ignore :eval and :propertize.
14951
14952 If the global variable `frame_title_ptr' is non-NULL, then the output
14953 is passed to `store_frame_title' instead of `display_string'. */
14954
14955 static int
14956 display_mode_element (it, depth, field_width, precision, elt, props, risky)
14957 struct it *it;
14958 int depth;
14959 int field_width, precision;
14960 Lisp_Object elt, props;
14961 int risky;
14962 {
14963 int n = 0, field, prec;
14964 int literal = 0;
14965
14966 tail_recurse:
14967 if (depth > 100)
14968 elt = build_string ("*too-deep*");
14969
14970 depth++;
14971
14972 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
14973 {
14974 case Lisp_String:
14975 {
14976 /* A string: output it and check for %-constructs within it. */
14977 unsigned char c;
14978 const unsigned char *this, *lisp_string;
14979
14980 if (!NILP (props) || risky)
14981 {
14982 Lisp_Object oprops, aelt;
14983 oprops = Ftext_properties_at (make_number (0), elt);
14984
14985 if (NILP (Fequal (props, oprops)) || risky)
14986 {
14987 /* If the starting string has properties,
14988 merge the specified ones onto the existing ones. */
14989 if (! NILP (oprops) && !risky)
14990 {
14991 Lisp_Object tem;
14992
14993 oprops = Fcopy_sequence (oprops);
14994 tem = props;
14995 while (CONSP (tem))
14996 {
14997 oprops = Fplist_put (oprops, XCAR (tem),
14998 XCAR (XCDR (tem)));
14999 tem = XCDR (XCDR (tem));
15000 }
15001 props = oprops;
15002 }
15003
15004 aelt = Fassoc (elt, mode_line_proptrans_alist);
15005 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15006 {
15007 mode_line_proptrans_alist
15008 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15009 elt = XCAR (aelt);
15010 }
15011 else
15012 {
15013 Lisp_Object tem;
15014
15015 elt = Fcopy_sequence (elt);
15016 Fset_text_properties (make_number (0), Flength (elt),
15017 props, elt);
15018 /* Add this item to mode_line_proptrans_alist. */
15019 mode_line_proptrans_alist
15020 = Fcons (Fcons (elt, props),
15021 mode_line_proptrans_alist);
15022 /* Truncate mode_line_proptrans_alist
15023 to at most 50 elements. */
15024 tem = Fnthcdr (make_number (50),
15025 mode_line_proptrans_alist);
15026 if (! NILP (tem))
15027 XSETCDR (tem, Qnil);
15028 }
15029 }
15030 }
15031
15032 this = SDATA (elt);
15033 lisp_string = this;
15034
15035 if (literal)
15036 {
15037 prec = precision - n;
15038 if (frame_title_ptr)
15039 n += store_frame_title (SDATA (elt), -1, prec);
15040 else if (!NILP (mode_line_string_list))
15041 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15042 else
15043 n += display_string (NULL, elt, Qnil, 0, 0, it,
15044 0, prec, 0, STRING_MULTIBYTE (elt));
15045
15046 break;
15047 }
15048
15049 while ((precision <= 0 || n < precision)
15050 && *this
15051 && (frame_title_ptr
15052 || !NILP (mode_line_string_list)
15053 || it->current_x < it->last_visible_x))
15054 {
15055 const unsigned char *last = this;
15056
15057 /* Advance to end of string or next format specifier. */
15058 while ((c = *this++) != '\0' && c != '%')
15059 ;
15060
15061 if (this - 1 != last)
15062 {
15063 /* Output to end of string or up to '%'. Field width
15064 is length of string. Don't output more than
15065 PRECISION allows us. */
15066 --this;
15067
15068 prec = chars_in_text (last, this - last);
15069 if (precision > 0 && prec > precision - n)
15070 prec = precision - n;
15071
15072 if (frame_title_ptr)
15073 n += store_frame_title (last, 0, prec);
15074 else if (!NILP (mode_line_string_list))
15075 {
15076 int bytepos = last - lisp_string;
15077 int charpos = string_byte_to_char (elt, bytepos);
15078 n += store_mode_line_string (NULL,
15079 Fsubstring (elt, make_number (charpos),
15080 make_number (charpos + prec)),
15081 0, 0, 0, Qnil);
15082 }
15083 else
15084 {
15085 int bytepos = last - lisp_string;
15086 int charpos = string_byte_to_char (elt, bytepos);
15087 n += display_string (NULL, elt, Qnil, 0, charpos,
15088 it, 0, prec, 0,
15089 STRING_MULTIBYTE (elt));
15090 }
15091 }
15092 else /* c == '%' */
15093 {
15094 const unsigned char *percent_position = this;
15095
15096 /* Get the specified minimum width. Zero means
15097 don't pad. */
15098 field = 0;
15099 while ((c = *this++) >= '0' && c <= '9')
15100 field = field * 10 + c - '0';
15101
15102 /* Don't pad beyond the total padding allowed. */
15103 if (field_width - n > 0 && field > field_width - n)
15104 field = field_width - n;
15105
15106 /* Note that either PRECISION <= 0 or N < PRECISION. */
15107 prec = precision - n;
15108
15109 if (c == 'M')
15110 n += display_mode_element (it, depth, field, prec,
15111 Vglobal_mode_string, props,
15112 risky);
15113 else if (c != 0)
15114 {
15115 int multibyte;
15116 int bytepos, charpos;
15117 unsigned char *spec;
15118
15119 bytepos = percent_position - lisp_string;
15120 charpos = (STRING_MULTIBYTE (elt)
15121 ? string_byte_to_char (elt, bytepos)
15122 : bytepos);
15123
15124 spec
15125 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15126
15127 if (frame_title_ptr)
15128 n += store_frame_title (spec, field, prec);
15129 else if (!NILP (mode_line_string_list))
15130 {
15131 int len = strlen (spec);
15132 Lisp_Object tem = make_string (spec, len);
15133 props = Ftext_properties_at (make_number (charpos), elt);
15134 /* Should only keep face property in props */
15135 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15136 }
15137 else
15138 {
15139 int nglyphs_before, nwritten;
15140
15141 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15142 nwritten = display_string (spec, Qnil, elt,
15143 charpos, 0, it,
15144 field, prec, 0,
15145 multibyte);
15146
15147 /* Assign to the glyphs written above the
15148 string where the `%x' came from, position
15149 of the `%'. */
15150 if (nwritten > 0)
15151 {
15152 struct glyph *glyph
15153 = (it->glyph_row->glyphs[TEXT_AREA]
15154 + nglyphs_before);
15155 int i;
15156
15157 for (i = 0; i < nwritten; ++i)
15158 {
15159 glyph[i].object = elt;
15160 glyph[i].charpos = charpos;
15161 }
15162
15163 n += nwritten;
15164 }
15165 }
15166 }
15167 else /* c == 0 */
15168 break;
15169 }
15170 }
15171 }
15172 break;
15173
15174 case Lisp_Symbol:
15175 /* A symbol: process the value of the symbol recursively
15176 as if it appeared here directly. Avoid error if symbol void.
15177 Special case: if value of symbol is a string, output the string
15178 literally. */
15179 {
15180 register Lisp_Object tem;
15181
15182 /* If the variable is not marked as risky to set
15183 then its contents are risky to use. */
15184 if (NILP (Fget (elt, Qrisky_local_variable)))
15185 risky = 1;
15186
15187 tem = Fboundp (elt);
15188 if (!NILP (tem))
15189 {
15190 tem = Fsymbol_value (elt);
15191 /* If value is a string, output that string literally:
15192 don't check for % within it. */
15193 if (STRINGP (tem))
15194 literal = 1;
15195
15196 if (!EQ (tem, elt))
15197 {
15198 /* Give up right away for nil or t. */
15199 elt = tem;
15200 goto tail_recurse;
15201 }
15202 }
15203 }
15204 break;
15205
15206 case Lisp_Cons:
15207 {
15208 register Lisp_Object car, tem;
15209
15210 /* A cons cell: five distinct cases.
15211 If first element is :eval or :propertize, do something special.
15212 If first element is a string or a cons, process all the elements
15213 and effectively concatenate them.
15214 If first element is a negative number, truncate displaying cdr to
15215 at most that many characters. If positive, pad (with spaces)
15216 to at least that many characters.
15217 If first element is a symbol, process the cadr or caddr recursively
15218 according to whether the symbol's value is non-nil or nil. */
15219 car = XCAR (elt);
15220 if (EQ (car, QCeval))
15221 {
15222 /* An element of the form (:eval FORM) means evaluate FORM
15223 and use the result as mode line elements. */
15224
15225 if (risky)
15226 break;
15227
15228 if (CONSP (XCDR (elt)))
15229 {
15230 Lisp_Object spec;
15231 spec = safe_eval (XCAR (XCDR (elt)));
15232 n += display_mode_element (it, depth, field_width - n,
15233 precision - n, spec, props,
15234 risky);
15235 }
15236 }
15237 else if (EQ (car, QCpropertize))
15238 {
15239 /* An element of the form (:propertize ELT PROPS...)
15240 means display ELT but applying properties PROPS. */
15241
15242 if (risky)
15243 break;
15244
15245 if (CONSP (XCDR (elt)))
15246 n += display_mode_element (it, depth, field_width - n,
15247 precision - n, XCAR (XCDR (elt)),
15248 XCDR (XCDR (elt)), risky);
15249 }
15250 else if (SYMBOLP (car))
15251 {
15252 tem = Fboundp (car);
15253 elt = XCDR (elt);
15254 if (!CONSP (elt))
15255 goto invalid;
15256 /* elt is now the cdr, and we know it is a cons cell.
15257 Use its car if CAR has a non-nil value. */
15258 if (!NILP (tem))
15259 {
15260 tem = Fsymbol_value (car);
15261 if (!NILP (tem))
15262 {
15263 elt = XCAR (elt);
15264 goto tail_recurse;
15265 }
15266 }
15267 /* Symbol's value is nil (or symbol is unbound)
15268 Get the cddr of the original list
15269 and if possible find the caddr and use that. */
15270 elt = XCDR (elt);
15271 if (NILP (elt))
15272 break;
15273 else if (!CONSP (elt))
15274 goto invalid;
15275 elt = XCAR (elt);
15276 goto tail_recurse;
15277 }
15278 else if (INTEGERP (car))
15279 {
15280 register int lim = XINT (car);
15281 elt = XCDR (elt);
15282 if (lim < 0)
15283 {
15284 /* Negative int means reduce maximum width. */
15285 if (precision <= 0)
15286 precision = -lim;
15287 else
15288 precision = min (precision, -lim);
15289 }
15290 else if (lim > 0)
15291 {
15292 /* Padding specified. Don't let it be more than
15293 current maximum. */
15294 if (precision > 0)
15295 lim = min (precision, lim);
15296
15297 /* If that's more padding than already wanted, queue it.
15298 But don't reduce padding already specified even if
15299 that is beyond the current truncation point. */
15300 field_width = max (lim, field_width);
15301 }
15302 goto tail_recurse;
15303 }
15304 else if (STRINGP (car) || CONSP (car))
15305 {
15306 register int limit = 50;
15307 /* Limit is to protect against circular lists. */
15308 while (CONSP (elt)
15309 && --limit > 0
15310 && (precision <= 0 || n < precision))
15311 {
15312 n += display_mode_element (it, depth, field_width - n,
15313 precision - n, XCAR (elt),
15314 props, risky);
15315 elt = XCDR (elt);
15316 }
15317 }
15318 }
15319 break;
15320
15321 default:
15322 invalid:
15323 elt = build_string ("*invalid*");
15324 goto tail_recurse;
15325 }
15326
15327 /* Pad to FIELD_WIDTH. */
15328 if (field_width > 0 && n < field_width)
15329 {
15330 if (frame_title_ptr)
15331 n += store_frame_title ("", field_width - n, 0);
15332 else if (!NILP (mode_line_string_list))
15333 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
15334 else
15335 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
15336 0, 0, 0);
15337 }
15338
15339 return n;
15340 }
15341
15342 /* Store a mode-line string element in mode_line_string_list.
15343
15344 If STRING is non-null, display that C string. Otherwise, the Lisp
15345 string LISP_STRING is displayed.
15346
15347 FIELD_WIDTH is the minimum number of output glyphs to produce.
15348 If STRING has fewer characters than FIELD_WIDTH, pad to the right
15349 with spaces. FIELD_WIDTH <= 0 means don't pad.
15350
15351 PRECISION is the maximum number of characters to output from
15352 STRING. PRECISION <= 0 means don't truncate the string.
15353
15354 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
15355 properties to the string.
15356
15357 PROPS are the properties to add to the string.
15358 The mode_line_string_face face property is always added to the string.
15359 */
15360
15361 static int store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
15362 char *string;
15363 Lisp_Object lisp_string;
15364 int copy_string;
15365 int field_width;
15366 int precision;
15367 Lisp_Object props;
15368 {
15369 int len;
15370 int n = 0;
15371
15372 if (string != NULL)
15373 {
15374 len = strlen (string);
15375 if (precision > 0 && len > precision)
15376 len = precision;
15377 lisp_string = make_string (string, len);
15378 if (NILP (props))
15379 props = mode_line_string_face_prop;
15380 else if (!NILP (mode_line_string_face))
15381 {
15382 Lisp_Object face = Fplist_get (props, Qface);
15383 props = Fcopy_sequence (props);
15384 if (NILP (face))
15385 face = mode_line_string_face;
15386 else
15387 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15388 props = Fplist_put (props, Qface, face);
15389 }
15390 Fadd_text_properties (make_number (0), make_number (len),
15391 props, lisp_string);
15392 }
15393 else
15394 {
15395 len = XFASTINT (Flength (lisp_string));
15396 if (precision > 0 && len > precision)
15397 {
15398 len = precision;
15399 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
15400 precision = -1;
15401 }
15402 if (!NILP (mode_line_string_face))
15403 {
15404 Lisp_Object face;
15405 if (NILP (props))
15406 props = Ftext_properties_at (make_number (0), lisp_string);
15407 face = Fplist_get (props, Qface);
15408 if (NILP (face))
15409 face = mode_line_string_face;
15410 else
15411 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
15412 props = Fcons (Qface, Fcons (face, Qnil));
15413 if (copy_string)
15414 lisp_string = Fcopy_sequence (lisp_string);
15415 }
15416 if (!NILP (props))
15417 Fadd_text_properties (make_number (0), make_number (len),
15418 props, lisp_string);
15419 }
15420
15421 if (len > 0)
15422 {
15423 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15424 n += len;
15425 }
15426
15427 if (field_width > len)
15428 {
15429 field_width -= len;
15430 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
15431 if (!NILP (props))
15432 Fadd_text_properties (make_number (0), make_number (field_width),
15433 props, lisp_string);
15434 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
15435 n += field_width;
15436 }
15437
15438 return n;
15439 }
15440
15441
15442 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
15443 0, 3, 0,
15444 doc: /* Return the mode-line of selected window as a string.
15445 First optional arg FORMAT specifies a different format string (see
15446 `mode-line-format' for details) to use. If FORMAT is t, return
15447 the buffer's header-line. Second optional arg WINDOW specifies a
15448 different window to use as the context for the formatting.
15449 If third optional arg NO-PROPS is non-nil, string is not propertized. */)
15450 (format, window, no_props)
15451 Lisp_Object format, window, no_props;
15452 {
15453 struct it it;
15454 int len;
15455 struct window *w;
15456 struct buffer *old_buffer = NULL;
15457 enum face_id face_id = DEFAULT_FACE_ID;
15458
15459 if (NILP (window))
15460 window = selected_window;
15461 CHECK_WINDOW (window);
15462 w = XWINDOW (window);
15463 CHECK_BUFFER (w->buffer);
15464
15465 if (XBUFFER (w->buffer) != current_buffer)
15466 {
15467 old_buffer = current_buffer;
15468 set_buffer_internal_1 (XBUFFER (w->buffer));
15469 }
15470
15471 if (NILP (format) || EQ (format, Qt))
15472 {
15473 face_id = NILP (format)
15474 ? CURRENT_MODE_LINE_FACE_ID (w) :
15475 HEADER_LINE_FACE_ID;
15476 format = NILP (format)
15477 ? current_buffer->mode_line_format
15478 : current_buffer->header_line_format;
15479 }
15480
15481 init_iterator (&it, w, -1, -1, NULL, face_id);
15482
15483 if (NILP (no_props))
15484 {
15485 mode_line_string_face =
15486 (face_id == MODE_LINE_FACE_ID ? Qmode_line :
15487 face_id == MODE_LINE_INACTIVE_FACE_ID ? Qmode_line_inactive :
15488 face_id == HEADER_LINE_FACE_ID ? Qheader_line : Qnil);
15489
15490 mode_line_string_face_prop =
15491 NILP (mode_line_string_face) ? Qnil :
15492 Fcons (Qface, Fcons (mode_line_string_face, Qnil));
15493
15494 /* We need a dummy last element in mode_line_string_list to
15495 indicate we are building the propertized mode-line string.
15496 Using mode_line_string_face_prop here GC protects it. */
15497 mode_line_string_list =
15498 Fcons (mode_line_string_face_prop, Qnil);
15499 frame_title_ptr = NULL;
15500 }
15501 else
15502 {
15503 mode_line_string_face_prop = Qnil;
15504 mode_line_string_list = Qnil;
15505 frame_title_ptr = frame_title_buf;
15506 }
15507
15508 push_frame_kboard (it.f);
15509 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15510 pop_frame_kboard ();
15511
15512 if (old_buffer)
15513 set_buffer_internal_1 (old_buffer);
15514
15515 if (NILP (no_props))
15516 {
15517 Lisp_Object str;
15518 mode_line_string_list = Fnreverse (mode_line_string_list);
15519 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
15520 make_string ("", 0));
15521 mode_line_string_face_prop = Qnil;
15522 mode_line_string_list = Qnil;
15523 return str;
15524 }
15525
15526 len = frame_title_ptr - frame_title_buf;
15527 if (len > 0 && frame_title_ptr[-1] == '-')
15528 {
15529 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
15530 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
15531 ;
15532 frame_title_ptr += 3; /* restore last non-dash + two dashes */
15533 if (len > frame_title_ptr - frame_title_buf)
15534 len = frame_title_ptr - frame_title_buf;
15535 }
15536
15537 frame_title_ptr = NULL;
15538 return make_string (frame_title_buf, len);
15539 }
15540
15541 /* Write a null-terminated, right justified decimal representation of
15542 the positive integer D to BUF using a minimal field width WIDTH. */
15543
15544 static void
15545 pint2str (buf, width, d)
15546 register char *buf;
15547 register int width;
15548 register int d;
15549 {
15550 register char *p = buf;
15551
15552 if (d <= 0)
15553 *p++ = '0';
15554 else
15555 {
15556 while (d > 0)
15557 {
15558 *p++ = d % 10 + '0';
15559 d /= 10;
15560 }
15561 }
15562
15563 for (width -= (int) (p - buf); width > 0; --width)
15564 *p++ = ' ';
15565 *p-- = '\0';
15566 while (p > buf)
15567 {
15568 d = *buf;
15569 *buf++ = *p;
15570 *p-- = d;
15571 }
15572 }
15573
15574 /* Write a null-terminated, right justified decimal and "human
15575 readable" representation of the nonnegative integer D to BUF using
15576 a minimal field width WIDTH. D should be smaller than 999.5e24. */
15577
15578 static const char power_letter[] =
15579 {
15580 0, /* not used */
15581 'k', /* kilo */
15582 'M', /* mega */
15583 'G', /* giga */
15584 'T', /* tera */
15585 'P', /* peta */
15586 'E', /* exa */
15587 'Z', /* zetta */
15588 'Y' /* yotta */
15589 };
15590
15591 static void
15592 pint2hrstr (buf, width, d)
15593 char *buf;
15594 int width;
15595 int d;
15596 {
15597 /* We aim to represent the nonnegative integer D as
15598 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
15599 int quotient = d;
15600 int remainder = 0;
15601 /* -1 means: do not use TENTHS. */
15602 int tenths = -1;
15603 int exponent = 0;
15604
15605 /* Length of QUOTIENT.TENTHS as a string. */
15606 int length;
15607
15608 char * psuffix;
15609 char * p;
15610
15611 if (1000 <= quotient)
15612 {
15613 /* Scale to the appropriate EXPONENT. */
15614 do
15615 {
15616 remainder = quotient % 1000;
15617 quotient /= 1000;
15618 exponent++;
15619 }
15620 while (1000 <= quotient);
15621
15622 /* Round to nearest and decide whether to use TENTHS or not. */
15623 if (quotient <= 9)
15624 {
15625 tenths = remainder / 100;
15626 if (50 <= remainder % 100)
15627 if (tenths < 9)
15628 tenths++;
15629 else
15630 {
15631 quotient++;
15632 if (quotient == 10)
15633 tenths = -1;
15634 else
15635 tenths = 0;
15636 }
15637 }
15638 else
15639 if (500 <= remainder)
15640 if (quotient < 999)
15641 quotient++;
15642 else
15643 {
15644 quotient = 1;
15645 exponent++;
15646 tenths = 0;
15647 }
15648 }
15649
15650 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
15651 if (tenths == -1 && quotient <= 99)
15652 if (quotient <= 9)
15653 length = 1;
15654 else
15655 length = 2;
15656 else
15657 length = 3;
15658 p = psuffix = buf + max (width, length);
15659
15660 /* Print EXPONENT. */
15661 if (exponent)
15662 *psuffix++ = power_letter[exponent];
15663 *psuffix = '\0';
15664
15665 /* Print TENTHS. */
15666 if (tenths >= 0)
15667 {
15668 *--p = '0' + tenths;
15669 *--p = '.';
15670 }
15671
15672 /* Print QUOTIENT. */
15673 do
15674 {
15675 int digit = quotient % 10;
15676 *--p = '0' + digit;
15677 }
15678 while ((quotient /= 10) != 0);
15679
15680 /* Print leading spaces. */
15681 while (buf < p)
15682 *--p = ' ';
15683 }
15684
15685 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
15686 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
15687 type of CODING_SYSTEM. Return updated pointer into BUF. */
15688
15689 static unsigned char invalid_eol_type[] = "(*invalid*)";
15690
15691 static char *
15692 decode_mode_spec_coding (coding_system, buf, eol_flag)
15693 Lisp_Object coding_system;
15694 register char *buf;
15695 int eol_flag;
15696 {
15697 Lisp_Object val;
15698 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
15699 const unsigned char *eol_str;
15700 int eol_str_len;
15701 /* The EOL conversion we are using. */
15702 Lisp_Object eoltype;
15703
15704 val = Fget (coding_system, Qcoding_system);
15705 eoltype = Qnil;
15706
15707 if (!VECTORP (val)) /* Not yet decided. */
15708 {
15709 if (multibyte)
15710 *buf++ = '-';
15711 if (eol_flag)
15712 eoltype = eol_mnemonic_undecided;
15713 /* Don't mention EOL conversion if it isn't decided. */
15714 }
15715 else
15716 {
15717 Lisp_Object eolvalue;
15718
15719 eolvalue = Fget (coding_system, Qeol_type);
15720
15721 if (multibyte)
15722 *buf++ = XFASTINT (AREF (val, 1));
15723
15724 if (eol_flag)
15725 {
15726 /* The EOL conversion that is normal on this system. */
15727
15728 if (NILP (eolvalue)) /* Not yet decided. */
15729 eoltype = eol_mnemonic_undecided;
15730 else if (VECTORP (eolvalue)) /* Not yet decided. */
15731 eoltype = eol_mnemonic_undecided;
15732 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
15733 eoltype = (XFASTINT (eolvalue) == 0
15734 ? eol_mnemonic_unix
15735 : (XFASTINT (eolvalue) == 1
15736 ? eol_mnemonic_dos : eol_mnemonic_mac));
15737 }
15738 }
15739
15740 if (eol_flag)
15741 {
15742 /* Mention the EOL conversion if it is not the usual one. */
15743 if (STRINGP (eoltype))
15744 {
15745 eol_str = SDATA (eoltype);
15746 eol_str_len = SBYTES (eoltype);
15747 }
15748 else if (INTEGERP (eoltype)
15749 && CHAR_VALID_P (XINT (eoltype), 0))
15750 {
15751 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
15752 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
15753 eol_str = tmp;
15754 }
15755 else
15756 {
15757 eol_str = invalid_eol_type;
15758 eol_str_len = sizeof (invalid_eol_type) - 1;
15759 }
15760 bcopy (eol_str, buf, eol_str_len);
15761 buf += eol_str_len;
15762 }
15763
15764 return buf;
15765 }
15766
15767 /* Return a string for the output of a mode line %-spec for window W,
15768 generated by character C. PRECISION >= 0 means don't return a
15769 string longer than that value. FIELD_WIDTH > 0 means pad the
15770 string returned with spaces to that value. Return 1 in *MULTIBYTE
15771 if the result is multibyte text. */
15772
15773 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
15774
15775 static char *
15776 decode_mode_spec (w, c, field_width, precision, multibyte)
15777 struct window *w;
15778 register int c;
15779 int field_width, precision;
15780 int *multibyte;
15781 {
15782 Lisp_Object obj;
15783 struct frame *f = XFRAME (WINDOW_FRAME (w));
15784 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
15785 struct buffer *b = XBUFFER (w->buffer);
15786
15787 obj = Qnil;
15788 *multibyte = 0;
15789
15790 switch (c)
15791 {
15792 case '*':
15793 if (!NILP (b->read_only))
15794 return "%";
15795 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15796 return "*";
15797 return "-";
15798
15799 case '+':
15800 /* This differs from %* only for a modified read-only buffer. */
15801 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15802 return "*";
15803 if (!NILP (b->read_only))
15804 return "%";
15805 return "-";
15806
15807 case '&':
15808 /* This differs from %* in ignoring read-only-ness. */
15809 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
15810 return "*";
15811 return "-";
15812
15813 case '%':
15814 return "%";
15815
15816 case '[':
15817 {
15818 int i;
15819 char *p;
15820
15821 if (command_loop_level > 5)
15822 return "[[[... ";
15823 p = decode_mode_spec_buf;
15824 for (i = 0; i < command_loop_level; i++)
15825 *p++ = '[';
15826 *p = 0;
15827 return decode_mode_spec_buf;
15828 }
15829
15830 case ']':
15831 {
15832 int i;
15833 char *p;
15834
15835 if (command_loop_level > 5)
15836 return " ...]]]";
15837 p = decode_mode_spec_buf;
15838 for (i = 0; i < command_loop_level; i++)
15839 *p++ = ']';
15840 *p = 0;
15841 return decode_mode_spec_buf;
15842 }
15843
15844 case '-':
15845 {
15846 register int i;
15847
15848 /* Let lots_of_dashes be a string of infinite length. */
15849 if (!NILP (mode_line_string_list))
15850 return "--";
15851 if (field_width <= 0
15852 || field_width > sizeof (lots_of_dashes))
15853 {
15854 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
15855 decode_mode_spec_buf[i] = '-';
15856 decode_mode_spec_buf[i] = '\0';
15857 return decode_mode_spec_buf;
15858 }
15859 else
15860 return lots_of_dashes;
15861 }
15862
15863 case 'b':
15864 obj = b->name;
15865 break;
15866
15867 case 'c':
15868 {
15869 int col = (int) current_column (); /* iftc */
15870 w->column_number_displayed = make_number (col);
15871 pint2str (decode_mode_spec_buf, field_width, col);
15872 return decode_mode_spec_buf;
15873 }
15874
15875 case 'F':
15876 /* %F displays the frame name. */
15877 if (!NILP (f->title))
15878 return (char *) SDATA (f->title);
15879 if (f->explicit_name || ! FRAME_WINDOW_P (f))
15880 return (char *) SDATA (f->name);
15881 return "Emacs";
15882
15883 case 'f':
15884 obj = b->filename;
15885 break;
15886
15887 case 'i':
15888 {
15889 int size = ZV - BEGV;
15890 pint2str (decode_mode_spec_buf, field_width, size);
15891 return decode_mode_spec_buf;
15892 }
15893
15894 case 'I':
15895 {
15896 int size = ZV - BEGV;
15897 pint2hrstr (decode_mode_spec_buf, field_width, size);
15898 return decode_mode_spec_buf;
15899 }
15900
15901 case 'l':
15902 {
15903 int startpos = XMARKER (w->start)->charpos;
15904 int startpos_byte = marker_byte_position (w->start);
15905 int line, linepos, linepos_byte, topline;
15906 int nlines, junk;
15907 int height = WINDOW_TOTAL_LINES (w);
15908
15909 /* If we decided that this buffer isn't suitable for line numbers,
15910 don't forget that too fast. */
15911 if (EQ (w->base_line_pos, w->buffer))
15912 goto no_value;
15913 /* But do forget it, if the window shows a different buffer now. */
15914 else if (BUFFERP (w->base_line_pos))
15915 w->base_line_pos = Qnil;
15916
15917 /* If the buffer is very big, don't waste time. */
15918 if (INTEGERP (Vline_number_display_limit)
15919 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
15920 {
15921 w->base_line_pos = Qnil;
15922 w->base_line_number = Qnil;
15923 goto no_value;
15924 }
15925
15926 if (!NILP (w->base_line_number)
15927 && !NILP (w->base_line_pos)
15928 && XFASTINT (w->base_line_pos) <= startpos)
15929 {
15930 line = XFASTINT (w->base_line_number);
15931 linepos = XFASTINT (w->base_line_pos);
15932 linepos_byte = buf_charpos_to_bytepos (b, linepos);
15933 }
15934 else
15935 {
15936 line = 1;
15937 linepos = BUF_BEGV (b);
15938 linepos_byte = BUF_BEGV_BYTE (b);
15939 }
15940
15941 /* Count lines from base line to window start position. */
15942 nlines = display_count_lines (linepos, linepos_byte,
15943 startpos_byte,
15944 startpos, &junk);
15945
15946 topline = nlines + line;
15947
15948 /* Determine a new base line, if the old one is too close
15949 or too far away, or if we did not have one.
15950 "Too close" means it's plausible a scroll-down would
15951 go back past it. */
15952 if (startpos == BUF_BEGV (b))
15953 {
15954 w->base_line_number = make_number (topline);
15955 w->base_line_pos = make_number (BUF_BEGV (b));
15956 }
15957 else if (nlines < height + 25 || nlines > height * 3 + 50
15958 || linepos == BUF_BEGV (b))
15959 {
15960 int limit = BUF_BEGV (b);
15961 int limit_byte = BUF_BEGV_BYTE (b);
15962 int position;
15963 int distance = (height * 2 + 30) * line_number_display_limit_width;
15964
15965 if (startpos - distance > limit)
15966 {
15967 limit = startpos - distance;
15968 limit_byte = CHAR_TO_BYTE (limit);
15969 }
15970
15971 nlines = display_count_lines (startpos, startpos_byte,
15972 limit_byte,
15973 - (height * 2 + 30),
15974 &position);
15975 /* If we couldn't find the lines we wanted within
15976 line_number_display_limit_width chars per line,
15977 give up on line numbers for this window. */
15978 if (position == limit_byte && limit == startpos - distance)
15979 {
15980 w->base_line_pos = w->buffer;
15981 w->base_line_number = Qnil;
15982 goto no_value;
15983 }
15984
15985 w->base_line_number = make_number (topline - nlines);
15986 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
15987 }
15988
15989 /* Now count lines from the start pos to point. */
15990 nlines = display_count_lines (startpos, startpos_byte,
15991 PT_BYTE, PT, &junk);
15992
15993 /* Record that we did display the line number. */
15994 line_number_displayed = 1;
15995
15996 /* Make the string to show. */
15997 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
15998 return decode_mode_spec_buf;
15999 no_value:
16000 {
16001 char* p = decode_mode_spec_buf;
16002 int pad = field_width - 2;
16003 while (pad-- > 0)
16004 *p++ = ' ';
16005 *p++ = '?';
16006 *p++ = '?';
16007 *p = '\0';
16008 return decode_mode_spec_buf;
16009 }
16010 }
16011 break;
16012
16013 case 'm':
16014 obj = b->mode_name;
16015 break;
16016
16017 case 'n':
16018 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16019 return " Narrow";
16020 break;
16021
16022 case 'p':
16023 {
16024 int pos = marker_position (w->start);
16025 int total = BUF_ZV (b) - BUF_BEGV (b);
16026
16027 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16028 {
16029 if (pos <= BUF_BEGV (b))
16030 return "All";
16031 else
16032 return "Bottom";
16033 }
16034 else if (pos <= BUF_BEGV (b))
16035 return "Top";
16036 else
16037 {
16038 if (total > 1000000)
16039 /* Do it differently for a large value, to avoid overflow. */
16040 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16041 else
16042 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16043 /* We can't normally display a 3-digit number,
16044 so get us a 2-digit number that is close. */
16045 if (total == 100)
16046 total = 99;
16047 sprintf (decode_mode_spec_buf, "%2d%%", total);
16048 return decode_mode_spec_buf;
16049 }
16050 }
16051
16052 /* Display percentage of size above the bottom of the screen. */
16053 case 'P':
16054 {
16055 int toppos = marker_position (w->start);
16056 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16057 int total = BUF_ZV (b) - BUF_BEGV (b);
16058
16059 if (botpos >= BUF_ZV (b))
16060 {
16061 if (toppos <= BUF_BEGV (b))
16062 return "All";
16063 else
16064 return "Bottom";
16065 }
16066 else
16067 {
16068 if (total > 1000000)
16069 /* Do it differently for a large value, to avoid overflow. */
16070 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16071 else
16072 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16073 /* We can't normally display a 3-digit number,
16074 so get us a 2-digit number that is close. */
16075 if (total == 100)
16076 total = 99;
16077 if (toppos <= BUF_BEGV (b))
16078 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16079 else
16080 sprintf (decode_mode_spec_buf, "%2d%%", total);
16081 return decode_mode_spec_buf;
16082 }
16083 }
16084
16085 case 's':
16086 /* status of process */
16087 obj = Fget_buffer_process (w->buffer);
16088 if (NILP (obj))
16089 return "no process";
16090 #ifdef subprocesses
16091 obj = Fsymbol_name (Fprocess_status (obj));
16092 #endif
16093 break;
16094
16095 case 't': /* indicate TEXT or BINARY */
16096 #ifdef MODE_LINE_BINARY_TEXT
16097 return MODE_LINE_BINARY_TEXT (b);
16098 #else
16099 return "T";
16100 #endif
16101
16102 case 'z':
16103 /* coding-system (not including end-of-line format) */
16104 case 'Z':
16105 /* coding-system (including end-of-line type) */
16106 {
16107 int eol_flag = (c == 'Z');
16108 char *p = decode_mode_spec_buf;
16109
16110 if (! FRAME_WINDOW_P (f))
16111 {
16112 /* No need to mention EOL here--the terminal never needs
16113 to do EOL conversion. */
16114 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16115 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16116 }
16117 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16118 p, eol_flag);
16119
16120 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16121 #ifdef subprocesses
16122 obj = Fget_buffer_process (Fcurrent_buffer ());
16123 if (PROCESSP (obj))
16124 {
16125 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16126 p, eol_flag);
16127 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16128 p, eol_flag);
16129 }
16130 #endif /* subprocesses */
16131 #endif /* 0 */
16132 *p = 0;
16133 return decode_mode_spec_buf;
16134 }
16135 }
16136
16137 if (STRINGP (obj))
16138 {
16139 *multibyte = STRING_MULTIBYTE (obj);
16140 return (char *) SDATA (obj);
16141 }
16142 else
16143 return "";
16144 }
16145
16146
16147 /* Count up to COUNT lines starting from START / START_BYTE.
16148 But don't go beyond LIMIT_BYTE.
16149 Return the number of lines thus found (always nonnegative).
16150
16151 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16152
16153 static int
16154 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16155 int start, start_byte, limit_byte, count;
16156 int *byte_pos_ptr;
16157 {
16158 register unsigned char *cursor;
16159 unsigned char *base;
16160
16161 register int ceiling;
16162 register unsigned char *ceiling_addr;
16163 int orig_count = count;
16164
16165 /* If we are not in selective display mode,
16166 check only for newlines. */
16167 int selective_display = (!NILP (current_buffer->selective_display)
16168 && !INTEGERP (current_buffer->selective_display));
16169
16170 if (count > 0)
16171 {
16172 while (start_byte < limit_byte)
16173 {
16174 ceiling = BUFFER_CEILING_OF (start_byte);
16175 ceiling = min (limit_byte - 1, ceiling);
16176 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16177 base = (cursor = BYTE_POS_ADDR (start_byte));
16178 while (1)
16179 {
16180 if (selective_display)
16181 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16182 ;
16183 else
16184 while (*cursor != '\n' && ++cursor != ceiling_addr)
16185 ;
16186
16187 if (cursor != ceiling_addr)
16188 {
16189 if (--count == 0)
16190 {
16191 start_byte += cursor - base + 1;
16192 *byte_pos_ptr = start_byte;
16193 return orig_count;
16194 }
16195 else
16196 if (++cursor == ceiling_addr)
16197 break;
16198 }
16199 else
16200 break;
16201 }
16202 start_byte += cursor - base;
16203 }
16204 }
16205 else
16206 {
16207 while (start_byte > limit_byte)
16208 {
16209 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16210 ceiling = max (limit_byte, ceiling);
16211 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16212 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16213 while (1)
16214 {
16215 if (selective_display)
16216 while (--cursor != ceiling_addr
16217 && *cursor != '\n' && *cursor != 015)
16218 ;
16219 else
16220 while (--cursor != ceiling_addr && *cursor != '\n')
16221 ;
16222
16223 if (cursor != ceiling_addr)
16224 {
16225 if (++count == 0)
16226 {
16227 start_byte += cursor - base + 1;
16228 *byte_pos_ptr = start_byte;
16229 /* When scanning backwards, we should
16230 not count the newline posterior to which we stop. */
16231 return - orig_count - 1;
16232 }
16233 }
16234 else
16235 break;
16236 }
16237 /* Here we add 1 to compensate for the last decrement
16238 of CURSOR, which took it past the valid range. */
16239 start_byte += cursor - base + 1;
16240 }
16241 }
16242
16243 *byte_pos_ptr = limit_byte;
16244
16245 if (count < 0)
16246 return - orig_count + count;
16247 return orig_count - count;
16248
16249 }
16250
16251
16252 \f
16253 /***********************************************************************
16254 Displaying strings
16255 ***********************************************************************/
16256
16257 /* Display a NUL-terminated string, starting with index START.
16258
16259 If STRING is non-null, display that C string. Otherwise, the Lisp
16260 string LISP_STRING is displayed.
16261
16262 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16263 FACE_STRING. Display STRING or LISP_STRING with the face at
16264 FACE_STRING_POS in FACE_STRING:
16265
16266 Display the string in the environment given by IT, but use the
16267 standard display table, temporarily.
16268
16269 FIELD_WIDTH is the minimum number of output glyphs to produce.
16270 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16271 with spaces. If STRING has more characters, more than FIELD_WIDTH
16272 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16273
16274 PRECISION is the maximum number of characters to output from
16275 STRING. PRECISION < 0 means don't truncate the string.
16276
16277 This is roughly equivalent to printf format specifiers:
16278
16279 FIELD_WIDTH PRECISION PRINTF
16280 ----------------------------------------
16281 -1 -1 %s
16282 -1 10 %.10s
16283 10 -1 %10s
16284 20 10 %20.10s
16285
16286 MULTIBYTE zero means do not display multibyte chars, > 0 means do
16287 display them, and < 0 means obey the current buffer's value of
16288 enable_multibyte_characters.
16289
16290 Value is the number of glyphs produced. */
16291
16292 static int
16293 display_string (string, lisp_string, face_string, face_string_pos,
16294 start, it, field_width, precision, max_x, multibyte)
16295 unsigned char *string;
16296 Lisp_Object lisp_string;
16297 Lisp_Object face_string;
16298 int face_string_pos;
16299 int start;
16300 struct it *it;
16301 int field_width, precision, max_x;
16302 int multibyte;
16303 {
16304 int hpos_at_start = it->hpos;
16305 int saved_face_id = it->face_id;
16306 struct glyph_row *row = it->glyph_row;
16307
16308 /* Initialize the iterator IT for iteration over STRING beginning
16309 with index START. */
16310 reseat_to_string (it, string, lisp_string, start,
16311 precision, field_width, multibyte);
16312
16313 /* If displaying STRING, set up the face of the iterator
16314 from LISP_STRING, if that's given. */
16315 if (STRINGP (face_string))
16316 {
16317 int endptr;
16318 struct face *face;
16319
16320 it->face_id
16321 = face_at_string_position (it->w, face_string, face_string_pos,
16322 0, it->region_beg_charpos,
16323 it->region_end_charpos,
16324 &endptr, it->base_face_id, 0);
16325 face = FACE_FROM_ID (it->f, it->face_id);
16326 it->face_box_p = face->box != FACE_NO_BOX;
16327 }
16328
16329 /* Set max_x to the maximum allowed X position. Don't let it go
16330 beyond the right edge of the window. */
16331 if (max_x <= 0)
16332 max_x = it->last_visible_x;
16333 else
16334 max_x = min (max_x, it->last_visible_x);
16335
16336 /* Skip over display elements that are not visible. because IT->w is
16337 hscrolled. */
16338 if (it->current_x < it->first_visible_x)
16339 move_it_in_display_line_to (it, 100000, it->first_visible_x,
16340 MOVE_TO_POS | MOVE_TO_X);
16341
16342 row->ascent = it->max_ascent;
16343 row->height = it->max_ascent + it->max_descent;
16344 row->phys_ascent = it->max_phys_ascent;
16345 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
16346
16347 /* This condition is for the case that we are called with current_x
16348 past last_visible_x. */
16349 while (it->current_x < max_x)
16350 {
16351 int x_before, x, n_glyphs_before, i, nglyphs;
16352
16353 /* Get the next display element. */
16354 if (!get_next_display_element (it))
16355 break;
16356
16357 /* Produce glyphs. */
16358 x_before = it->current_x;
16359 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
16360 PRODUCE_GLYPHS (it);
16361
16362 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
16363 i = 0;
16364 x = x_before;
16365 while (i < nglyphs)
16366 {
16367 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
16368
16369 if (!it->truncate_lines_p
16370 && x + glyph->pixel_width > max_x)
16371 {
16372 /* End of continued line or max_x reached. */
16373 if (CHAR_GLYPH_PADDING_P (*glyph))
16374 {
16375 /* A wide character is unbreakable. */
16376 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
16377 it->current_x = x_before;
16378 }
16379 else
16380 {
16381 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
16382 it->current_x = x;
16383 }
16384 break;
16385 }
16386 else if (x + glyph->pixel_width > it->first_visible_x)
16387 {
16388 /* Glyph is at least partially visible. */
16389 ++it->hpos;
16390 if (x < it->first_visible_x)
16391 it->glyph_row->x = x - it->first_visible_x;
16392 }
16393 else
16394 {
16395 /* Glyph is off the left margin of the display area.
16396 Should not happen. */
16397 abort ();
16398 }
16399
16400 row->ascent = max (row->ascent, it->max_ascent);
16401 row->height = max (row->height, it->max_ascent + it->max_descent);
16402 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
16403 row->phys_height = max (row->phys_height,
16404 it->max_phys_ascent + it->max_phys_descent);
16405 x += glyph->pixel_width;
16406 ++i;
16407 }
16408
16409 /* Stop if max_x reached. */
16410 if (i < nglyphs)
16411 break;
16412
16413 /* Stop at line ends. */
16414 if (ITERATOR_AT_END_OF_LINE_P (it))
16415 {
16416 it->continuation_lines_width = 0;
16417 break;
16418 }
16419
16420 set_iterator_to_next (it, 1);
16421
16422 /* Stop if truncating at the right edge. */
16423 if (it->truncate_lines_p
16424 && it->current_x >= it->last_visible_x)
16425 {
16426 /* Add truncation mark, but don't do it if the line is
16427 truncated at a padding space. */
16428 if (IT_CHARPOS (*it) < it->string_nchars)
16429 {
16430 if (!FRAME_WINDOW_P (it->f))
16431 {
16432 int i, n;
16433
16434 if (it->current_x > it->last_visible_x)
16435 {
16436 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
16437 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
16438 break;
16439 for (n = row->used[TEXT_AREA]; i < n; ++i)
16440 {
16441 row->used[TEXT_AREA] = i;
16442 produce_special_glyphs (it, IT_TRUNCATION);
16443 }
16444 }
16445 produce_special_glyphs (it, IT_TRUNCATION);
16446 }
16447 it->glyph_row->truncated_on_right_p = 1;
16448 }
16449 break;
16450 }
16451 }
16452
16453 /* Maybe insert a truncation at the left. */
16454 if (it->first_visible_x
16455 && IT_CHARPOS (*it) > 0)
16456 {
16457 if (!FRAME_WINDOW_P (it->f))
16458 insert_left_trunc_glyphs (it);
16459 it->glyph_row->truncated_on_left_p = 1;
16460 }
16461
16462 it->face_id = saved_face_id;
16463
16464 /* Value is number of columns displayed. */
16465 return it->hpos - hpos_at_start;
16466 }
16467
16468
16469 \f
16470 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
16471 appears as an element of LIST or as the car of an element of LIST.
16472 If PROPVAL is a list, compare each element against LIST in that
16473 way, and return 1/2 if any element of PROPVAL is found in LIST.
16474 Otherwise return 0. This function cannot quit.
16475 The return value is 2 if the text is invisible but with an ellipsis
16476 and 1 if it's invisible and without an ellipsis. */
16477
16478 int
16479 invisible_p (propval, list)
16480 register Lisp_Object propval;
16481 Lisp_Object list;
16482 {
16483 register Lisp_Object tail, proptail;
16484
16485 for (tail = list; CONSP (tail); tail = XCDR (tail))
16486 {
16487 register Lisp_Object tem;
16488 tem = XCAR (tail);
16489 if (EQ (propval, tem))
16490 return 1;
16491 if (CONSP (tem) && EQ (propval, XCAR (tem)))
16492 return NILP (XCDR (tem)) ? 1 : 2;
16493 }
16494
16495 if (CONSP (propval))
16496 {
16497 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
16498 {
16499 Lisp_Object propelt;
16500 propelt = XCAR (proptail);
16501 for (tail = list; CONSP (tail); tail = XCDR (tail))
16502 {
16503 register Lisp_Object tem;
16504 tem = XCAR (tail);
16505 if (EQ (propelt, tem))
16506 return 1;
16507 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
16508 return NILP (XCDR (tem)) ? 1 : 2;
16509 }
16510 }
16511 }
16512
16513 return 0;
16514 }
16515
16516 \f
16517 /***********************************************************************
16518 Glyph Display
16519 ***********************************************************************/
16520
16521 #ifdef HAVE_WINDOW_SYSTEM
16522
16523 #if GLYPH_DEBUG
16524
16525 void
16526 dump_glyph_string (s)
16527 struct glyph_string *s;
16528 {
16529 fprintf (stderr, "glyph string\n");
16530 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
16531 s->x, s->y, s->width, s->height);
16532 fprintf (stderr, " ybase = %d\n", s->ybase);
16533 fprintf (stderr, " hl = %d\n", s->hl);
16534 fprintf (stderr, " left overhang = %d, right = %d\n",
16535 s->left_overhang, s->right_overhang);
16536 fprintf (stderr, " nchars = %d\n", s->nchars);
16537 fprintf (stderr, " extends to end of line = %d\n",
16538 s->extends_to_end_of_line_p);
16539 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
16540 fprintf (stderr, " bg width = %d\n", s->background_width);
16541 }
16542
16543 #endif /* GLYPH_DEBUG */
16544
16545 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
16546 of XChar2b structures for S; it can't be allocated in
16547 init_glyph_string because it must be allocated via `alloca'. W
16548 is the window on which S is drawn. ROW and AREA are the glyph row
16549 and area within the row from which S is constructed. START is the
16550 index of the first glyph structure covered by S. HL is a
16551 face-override for drawing S. */
16552
16553 #ifdef HAVE_NTGUI
16554 #define OPTIONAL_HDC(hdc) hdc,
16555 #define DECLARE_HDC(hdc) HDC hdc;
16556 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
16557 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
16558 #endif
16559
16560 #ifndef OPTIONAL_HDC
16561 #define OPTIONAL_HDC(hdc)
16562 #define DECLARE_HDC(hdc)
16563 #define ALLOCATE_HDC(hdc, f)
16564 #define RELEASE_HDC(hdc, f)
16565 #endif
16566
16567 static void
16568 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
16569 struct glyph_string *s;
16570 DECLARE_HDC (hdc)
16571 XChar2b *char2b;
16572 struct window *w;
16573 struct glyph_row *row;
16574 enum glyph_row_area area;
16575 int start;
16576 enum draw_glyphs_face hl;
16577 {
16578 bzero (s, sizeof *s);
16579 s->w = w;
16580 s->f = XFRAME (w->frame);
16581 #ifdef HAVE_NTGUI
16582 s->hdc = hdc;
16583 #endif
16584 s->display = FRAME_X_DISPLAY (s->f);
16585 s->window = FRAME_X_WINDOW (s->f);
16586 s->char2b = char2b;
16587 s->hl = hl;
16588 s->row = row;
16589 s->area = area;
16590 s->first_glyph = row->glyphs[area] + start;
16591 s->height = row->height;
16592 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
16593
16594 /* Display the internal border below the tool-bar window. */
16595 if (s->w == XWINDOW (s->f->tool_bar_window))
16596 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
16597
16598 s->ybase = s->y + row->ascent;
16599 }
16600
16601
16602 /* Append the list of glyph strings with head H and tail T to the list
16603 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
16604
16605 static INLINE void
16606 append_glyph_string_lists (head, tail, h, t)
16607 struct glyph_string **head, **tail;
16608 struct glyph_string *h, *t;
16609 {
16610 if (h)
16611 {
16612 if (*head)
16613 (*tail)->next = h;
16614 else
16615 *head = h;
16616 h->prev = *tail;
16617 *tail = t;
16618 }
16619 }
16620
16621
16622 /* Prepend the list of glyph strings with head H and tail T to the
16623 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
16624 result. */
16625
16626 static INLINE void
16627 prepend_glyph_string_lists (head, tail, h, t)
16628 struct glyph_string **head, **tail;
16629 struct glyph_string *h, *t;
16630 {
16631 if (h)
16632 {
16633 if (*head)
16634 (*head)->prev = t;
16635 else
16636 *tail = t;
16637 t->next = *head;
16638 *head = h;
16639 }
16640 }
16641
16642
16643 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
16644 Set *HEAD and *TAIL to the resulting list. */
16645
16646 static INLINE void
16647 append_glyph_string (head, tail, s)
16648 struct glyph_string **head, **tail;
16649 struct glyph_string *s;
16650 {
16651 s->next = s->prev = NULL;
16652 append_glyph_string_lists (head, tail, s, s);
16653 }
16654
16655
16656 /* Get face and two-byte form of character glyph GLYPH on frame F.
16657 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
16658 a pointer to a realized face that is ready for display. */
16659
16660 static INLINE struct face *
16661 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
16662 struct frame *f;
16663 struct glyph *glyph;
16664 XChar2b *char2b;
16665 int *two_byte_p;
16666 {
16667 struct face *face;
16668
16669 xassert (glyph->type == CHAR_GLYPH);
16670 face = FACE_FROM_ID (f, glyph->face_id);
16671
16672 if (two_byte_p)
16673 *two_byte_p = 0;
16674
16675 if (!glyph->multibyte_p)
16676 {
16677 /* Unibyte case. We don't have to encode, but we have to make
16678 sure to use a face suitable for unibyte. */
16679 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16680 }
16681 else if (glyph->u.ch < 128
16682 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
16683 {
16684 /* Case of ASCII in a face known to fit ASCII. */
16685 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
16686 }
16687 else
16688 {
16689 int c1, c2, charset;
16690
16691 /* Split characters into bytes. If c2 is -1 afterwards, C is
16692 really a one-byte character so that byte1 is zero. */
16693 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
16694 if (c2 > 0)
16695 STORE_XCHAR2B (char2b, c1, c2);
16696 else
16697 STORE_XCHAR2B (char2b, 0, c1);
16698
16699 /* Maybe encode the character in *CHAR2B. */
16700 if (charset != CHARSET_ASCII)
16701 {
16702 struct font_info *font_info
16703 = FONT_INFO_FROM_ID (f, face->font_info_id);
16704 if (font_info)
16705 glyph->font_type
16706 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
16707 }
16708 }
16709
16710 /* Make sure X resources of the face are allocated. */
16711 xassert (face != NULL);
16712 PREPARE_FACE_FOR_DISPLAY (f, face);
16713 return face;
16714 }
16715
16716
16717 /* Fill glyph string S with composition components specified by S->cmp.
16718
16719 FACES is an array of faces for all components of this composition.
16720 S->gidx is the index of the first component for S.
16721 OVERLAPS_P non-zero means S should draw the foreground only, and
16722 use its physical height for clipping.
16723
16724 Value is the index of a component not in S. */
16725
16726 static int
16727 fill_composite_glyph_string (s, faces, overlaps_p)
16728 struct glyph_string *s;
16729 struct face **faces;
16730 int overlaps_p;
16731 {
16732 int i;
16733
16734 xassert (s);
16735
16736 s->for_overlaps_p = overlaps_p;
16737
16738 s->face = faces[s->gidx];
16739 s->font = s->face->font;
16740 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16741
16742 /* For all glyphs of this composition, starting at the offset
16743 S->gidx, until we reach the end of the definition or encounter a
16744 glyph that requires the different face, add it to S. */
16745 ++s->nchars;
16746 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
16747 ++s->nchars;
16748
16749 /* All glyph strings for the same composition has the same width,
16750 i.e. the width set for the first component of the composition. */
16751
16752 s->width = s->first_glyph->pixel_width;
16753
16754 /* If the specified font could not be loaded, use the frame's
16755 default font, but record the fact that we couldn't load it in
16756 the glyph string so that we can draw rectangles for the
16757 characters of the glyph string. */
16758 if (s->font == NULL)
16759 {
16760 s->font_not_found_p = 1;
16761 s->font = FRAME_FONT (s->f);
16762 }
16763
16764 /* Adjust base line for subscript/superscript text. */
16765 s->ybase += s->first_glyph->voffset;
16766
16767 xassert (s->face && s->face->gc);
16768
16769 /* This glyph string must always be drawn with 16-bit functions. */
16770 s->two_byte_p = 1;
16771
16772 return s->gidx + s->nchars;
16773 }
16774
16775
16776 /* Fill glyph string S from a sequence of character glyphs.
16777
16778 FACE_ID is the face id of the string. START is the index of the
16779 first glyph to consider, END is the index of the last + 1.
16780 OVERLAPS_P non-zero means S should draw the foreground only, and
16781 use its physical height for clipping.
16782
16783 Value is the index of the first glyph not in S. */
16784
16785 static int
16786 fill_glyph_string (s, face_id, start, end, overlaps_p)
16787 struct glyph_string *s;
16788 int face_id;
16789 int start, end, overlaps_p;
16790 {
16791 struct glyph *glyph, *last;
16792 int voffset;
16793 int glyph_not_available_p;
16794
16795 xassert (s->f == XFRAME (s->w->frame));
16796 xassert (s->nchars == 0);
16797 xassert (start >= 0 && end > start);
16798
16799 s->for_overlaps_p = overlaps_p,
16800 glyph = s->row->glyphs[s->area] + start;
16801 last = s->row->glyphs[s->area] + end;
16802 voffset = glyph->voffset;
16803
16804 glyph_not_available_p = glyph->glyph_not_available_p;
16805
16806 while (glyph < last
16807 && glyph->type == CHAR_GLYPH
16808 && glyph->voffset == voffset
16809 /* Same face id implies same font, nowadays. */
16810 && glyph->face_id == face_id
16811 && glyph->glyph_not_available_p == glyph_not_available_p)
16812 {
16813 int two_byte_p;
16814
16815 s->face = get_glyph_face_and_encoding (s->f, glyph,
16816 s->char2b + s->nchars,
16817 &two_byte_p);
16818 s->two_byte_p = two_byte_p;
16819 ++s->nchars;
16820 xassert (s->nchars <= end - start);
16821 s->width += glyph->pixel_width;
16822 ++glyph;
16823 }
16824
16825 s->font = s->face->font;
16826 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16827
16828 /* If the specified font could not be loaded, use the frame's font,
16829 but record the fact that we couldn't load it in
16830 S->font_not_found_p so that we can draw rectangles for the
16831 characters of the glyph string. */
16832 if (s->font == NULL || glyph_not_available_p)
16833 {
16834 s->font_not_found_p = 1;
16835 s->font = FRAME_FONT (s->f);
16836 }
16837
16838 /* Adjust base line for subscript/superscript text. */
16839 s->ybase += voffset;
16840
16841 xassert (s->face && s->face->gc);
16842 return glyph - s->row->glyphs[s->area];
16843 }
16844
16845
16846 /* Fill glyph string S from image glyph S->first_glyph. */
16847
16848 static void
16849 fill_image_glyph_string (s)
16850 struct glyph_string *s;
16851 {
16852 xassert (s->first_glyph->type == IMAGE_GLYPH);
16853 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
16854 xassert (s->img);
16855 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
16856 s->font = s->face->font;
16857 s->width = s->first_glyph->pixel_width;
16858
16859 /* Adjust base line for subscript/superscript text. */
16860 s->ybase += s->first_glyph->voffset;
16861 }
16862
16863
16864 /* Fill glyph string S from a sequence of stretch glyphs.
16865
16866 ROW is the glyph row in which the glyphs are found, AREA is the
16867 area within the row. START is the index of the first glyph to
16868 consider, END is the index of the last + 1.
16869
16870 Value is the index of the first glyph not in S. */
16871
16872 static int
16873 fill_stretch_glyph_string (s, row, area, start, end)
16874 struct glyph_string *s;
16875 struct glyph_row *row;
16876 enum glyph_row_area area;
16877 int start, end;
16878 {
16879 struct glyph *glyph, *last;
16880 int voffset, face_id;
16881
16882 xassert (s->first_glyph->type == STRETCH_GLYPH);
16883
16884 glyph = s->row->glyphs[s->area] + start;
16885 last = s->row->glyphs[s->area] + end;
16886 face_id = glyph->face_id;
16887 s->face = FACE_FROM_ID (s->f, face_id);
16888 s->font = s->face->font;
16889 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
16890 s->width = glyph->pixel_width;
16891 voffset = glyph->voffset;
16892
16893 for (++glyph;
16894 (glyph < last
16895 && glyph->type == STRETCH_GLYPH
16896 && glyph->voffset == voffset
16897 && glyph->face_id == face_id);
16898 ++glyph)
16899 s->width += glyph->pixel_width;
16900
16901 /* Adjust base line for subscript/superscript text. */
16902 s->ybase += voffset;
16903
16904 /* The case that face->gc == 0 is handled when drawing the glyph
16905 string by calling PREPARE_FACE_FOR_DISPLAY. */
16906 xassert (s->face);
16907 return glyph - s->row->glyphs[s->area];
16908 }
16909
16910
16911 /* EXPORT for RIF:
16912 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
16913 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
16914 assumed to be zero. */
16915
16916 void
16917 x_get_glyph_overhangs (glyph, f, left, right)
16918 struct glyph *glyph;
16919 struct frame *f;
16920 int *left, *right;
16921 {
16922 *left = *right = 0;
16923
16924 if (glyph->type == CHAR_GLYPH)
16925 {
16926 XFontStruct *font;
16927 struct face *face;
16928 struct font_info *font_info;
16929 XChar2b char2b;
16930 XCharStruct *pcm;
16931
16932 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
16933 font = face->font;
16934 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
16935 if (font /* ++KFS: Should this be font_info ? */
16936 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
16937 {
16938 if (pcm->rbearing > pcm->width)
16939 *right = pcm->rbearing - pcm->width;
16940 if (pcm->lbearing < 0)
16941 *left = -pcm->lbearing;
16942 }
16943 }
16944 }
16945
16946
16947 /* Return the index of the first glyph preceding glyph string S that
16948 is overwritten by S because of S's left overhang. Value is -1
16949 if no glyphs are overwritten. */
16950
16951 static int
16952 left_overwritten (s)
16953 struct glyph_string *s;
16954 {
16955 int k;
16956
16957 if (s->left_overhang)
16958 {
16959 int x = 0, i;
16960 struct glyph *glyphs = s->row->glyphs[s->area];
16961 int first = s->first_glyph - glyphs;
16962
16963 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
16964 x -= glyphs[i].pixel_width;
16965
16966 k = i + 1;
16967 }
16968 else
16969 k = -1;
16970
16971 return k;
16972 }
16973
16974
16975 /* Return the index of the first glyph preceding glyph string S that
16976 is overwriting S because of its right overhang. Value is -1 if no
16977 glyph in front of S overwrites S. */
16978
16979 static int
16980 left_overwriting (s)
16981 struct glyph_string *s;
16982 {
16983 int i, k, x;
16984 struct glyph *glyphs = s->row->glyphs[s->area];
16985 int first = s->first_glyph - glyphs;
16986
16987 k = -1;
16988 x = 0;
16989 for (i = first - 1; i >= 0; --i)
16990 {
16991 int left, right;
16992 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
16993 if (x + right > 0)
16994 k = i;
16995 x -= glyphs[i].pixel_width;
16996 }
16997
16998 return k;
16999 }
17000
17001
17002 /* Return the index of the last glyph following glyph string S that is
17003 not overwritten by S because of S's right overhang. Value is -1 if
17004 no such glyph is found. */
17005
17006 static int
17007 right_overwritten (s)
17008 struct glyph_string *s;
17009 {
17010 int k = -1;
17011
17012 if (s->right_overhang)
17013 {
17014 int x = 0, i;
17015 struct glyph *glyphs = s->row->glyphs[s->area];
17016 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17017 int end = s->row->used[s->area];
17018
17019 for (i = first; i < end && s->right_overhang > x; ++i)
17020 x += glyphs[i].pixel_width;
17021
17022 k = i;
17023 }
17024
17025 return k;
17026 }
17027
17028
17029 /* Return the index of the last glyph following glyph string S that
17030 overwrites S because of its left overhang. Value is negative
17031 if no such glyph is found. */
17032
17033 static int
17034 right_overwriting (s)
17035 struct glyph_string *s;
17036 {
17037 int i, k, x;
17038 int end = s->row->used[s->area];
17039 struct glyph *glyphs = s->row->glyphs[s->area];
17040 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17041
17042 k = -1;
17043 x = 0;
17044 for (i = first; i < end; ++i)
17045 {
17046 int left, right;
17047 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17048 if (x - left < 0)
17049 k = i;
17050 x += glyphs[i].pixel_width;
17051 }
17052
17053 return k;
17054 }
17055
17056
17057 /* Get face and two-byte form of character C in face FACE_ID on frame
17058 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
17059 means we want to display multibyte text. DISPLAY_P non-zero means
17060 make sure that X resources for the face returned are allocated.
17061 Value is a pointer to a realized face that is ready for display if
17062 DISPLAY_P is non-zero. */
17063
17064 static INLINE struct face *
17065 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
17066 struct frame *f;
17067 int c, face_id;
17068 XChar2b *char2b;
17069 int multibyte_p, display_p;
17070 {
17071 struct face *face = FACE_FROM_ID (f, face_id);
17072
17073 if (!multibyte_p)
17074 {
17075 /* Unibyte case. We don't have to encode, but we have to make
17076 sure to use a face suitable for unibyte. */
17077 STORE_XCHAR2B (char2b, 0, c);
17078 face_id = FACE_FOR_CHAR (f, face, c);
17079 face = FACE_FROM_ID (f, face_id);
17080 }
17081 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
17082 {
17083 /* Case of ASCII in a face known to fit ASCII. */
17084 STORE_XCHAR2B (char2b, 0, c);
17085 }
17086 else
17087 {
17088 int c1, c2, charset;
17089
17090 /* Split characters into bytes. If c2 is -1 afterwards, C is
17091 really a one-byte character so that byte1 is zero. */
17092 SPLIT_CHAR (c, charset, c1, c2);
17093 if (c2 > 0)
17094 STORE_XCHAR2B (char2b, c1, c2);
17095 else
17096 STORE_XCHAR2B (char2b, 0, c1);
17097
17098 /* Maybe encode the character in *CHAR2B. */
17099 if (face->font != NULL)
17100 {
17101 struct font_info *font_info
17102 = FONT_INFO_FROM_ID (f, face->font_info_id);
17103 if (font_info)
17104 rif->encode_char (c, char2b, font_info, 0);
17105 }
17106 }
17107
17108 /* Make sure X resources of the face are allocated. */
17109 #ifdef HAVE_X_WINDOWS
17110 if (display_p)
17111 #endif
17112 {
17113 xassert (face != NULL);
17114 PREPARE_FACE_FOR_DISPLAY (f, face);
17115 }
17116
17117 return face;
17118 }
17119
17120
17121 /* Set background width of glyph string S. START is the index of the
17122 first glyph following S. LAST_X is the right-most x-position + 1
17123 in the drawing area. */
17124
17125 static INLINE void
17126 set_glyph_string_background_width (s, start, last_x)
17127 struct glyph_string *s;
17128 int start;
17129 int last_x;
17130 {
17131 /* If the face of this glyph string has to be drawn to the end of
17132 the drawing area, set S->extends_to_end_of_line_p. */
17133 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
17134
17135 if (start == s->row->used[s->area]
17136 && s->area == TEXT_AREA
17137 && ((s->hl == DRAW_NORMAL_TEXT
17138 && (s->row->fill_line_p
17139 || s->face->background != default_face->background
17140 || s->face->stipple != default_face->stipple
17141 || s->row->mouse_face_p))
17142 || s->hl == DRAW_MOUSE_FACE
17143 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
17144 && s->row->fill_line_p)))
17145 s->extends_to_end_of_line_p = 1;
17146
17147 /* If S extends its face to the end of the line, set its
17148 background_width to the distance to the right edge of the drawing
17149 area. */
17150 if (s->extends_to_end_of_line_p)
17151 s->background_width = last_x - s->x + 1;
17152 else
17153 s->background_width = s->width;
17154 }
17155
17156
17157 /* Compute overhangs and x-positions for glyph string S and its
17158 predecessors, or successors. X is the starting x-position for S.
17159 BACKWARD_P non-zero means process predecessors. */
17160
17161 static void
17162 compute_overhangs_and_x (s, x, backward_p)
17163 struct glyph_string *s;
17164 int x;
17165 int backward_p;
17166 {
17167 if (backward_p)
17168 {
17169 while (s)
17170 {
17171 if (rif->compute_glyph_string_overhangs)
17172 rif->compute_glyph_string_overhangs (s);
17173 x -= s->width;
17174 s->x = x;
17175 s = s->prev;
17176 }
17177 }
17178 else
17179 {
17180 while (s)
17181 {
17182 if (rif->compute_glyph_string_overhangs)
17183 rif->compute_glyph_string_overhangs (s);
17184 s->x = x;
17185 x += s->width;
17186 s = s->next;
17187 }
17188 }
17189 }
17190
17191
17192
17193 /* The following macros are only called from draw_glyphs below.
17194 They reference the following parameters of that function directly:
17195 `w', `row', `area', and `overlap_p'
17196 as well as the following local variables:
17197 `s', `f', and `hdc' (in W32) */
17198
17199 #ifdef HAVE_NTGUI
17200 /* On W32, silently add local `hdc' variable to argument list of
17201 init_glyph_string. */
17202 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17203 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
17204 #else
17205 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
17206 init_glyph_string (s, char2b, w, row, area, start, hl)
17207 #endif
17208
17209 /* Add a glyph string for a stretch glyph to the list of strings
17210 between HEAD and TAIL. START is the index of the stretch glyph in
17211 row area AREA of glyph row ROW. END is the index of the last glyph
17212 in that glyph row area. X is the current output position assigned
17213 to the new glyph string constructed. HL overrides that face of the
17214 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17215 is the right-most x-position of the drawing area. */
17216
17217 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
17218 and below -- keep them on one line. */
17219 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17220 do \
17221 { \
17222 s = (struct glyph_string *) alloca (sizeof *s); \
17223 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17224 START = fill_stretch_glyph_string (s, row, area, START, END); \
17225 append_glyph_string (&HEAD, &TAIL, s); \
17226 s->x = (X); \
17227 } \
17228 while (0)
17229
17230
17231 /* Add a glyph string for an image glyph to the list of strings
17232 between HEAD and TAIL. START is the index of the image glyph in
17233 row area AREA of glyph row ROW. END is the index of the last glyph
17234 in that glyph row area. X is the current output position assigned
17235 to the new glyph string constructed. HL overrides that face of the
17236 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
17237 is the right-most x-position of the drawing area. */
17238
17239 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17240 do \
17241 { \
17242 s = (struct glyph_string *) alloca (sizeof *s); \
17243 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
17244 fill_image_glyph_string (s); \
17245 append_glyph_string (&HEAD, &TAIL, s); \
17246 ++START; \
17247 s->x = (X); \
17248 } \
17249 while (0)
17250
17251
17252 /* Add a glyph string for a sequence of character glyphs to the list
17253 of strings between HEAD and TAIL. START is the index of the first
17254 glyph in row area AREA of glyph row ROW that is part of the new
17255 glyph string. END is the index of the last glyph in that glyph row
17256 area. X is the current output position assigned to the new glyph
17257 string constructed. HL overrides that face of the glyph; e.g. it
17258 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
17259 right-most x-position of the drawing area. */
17260
17261 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17262 do \
17263 { \
17264 int c, face_id; \
17265 XChar2b *char2b; \
17266 \
17267 c = (row)->glyphs[area][START].u.ch; \
17268 face_id = (row)->glyphs[area][START].face_id; \
17269 \
17270 s = (struct glyph_string *) alloca (sizeof *s); \
17271 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
17272 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
17273 append_glyph_string (&HEAD, &TAIL, s); \
17274 s->x = (X); \
17275 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
17276 } \
17277 while (0)
17278
17279
17280 /* Add a glyph string for a composite sequence to the list of strings
17281 between HEAD and TAIL. START is the index of the first glyph in
17282 row area AREA of glyph row ROW that is part of the new glyph
17283 string. END is the index of the last glyph in that glyph row area.
17284 X is the current output position assigned to the new glyph string
17285 constructed. HL overrides that face of the glyph; e.g. it is
17286 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
17287 x-position of the drawing area. */
17288
17289 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
17290 do { \
17291 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
17292 int face_id = (row)->glyphs[area][START].face_id; \
17293 struct face *base_face = FACE_FROM_ID (f, face_id); \
17294 struct composition *cmp = composition_table[cmp_id]; \
17295 int glyph_len = cmp->glyph_len; \
17296 XChar2b *char2b; \
17297 struct face **faces; \
17298 struct glyph_string *first_s = NULL; \
17299 int n; \
17300 \
17301 base_face = base_face->ascii_face; \
17302 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
17303 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
17304 /* At first, fill in `char2b' and `faces'. */ \
17305 for (n = 0; n < glyph_len; n++) \
17306 { \
17307 int c = COMPOSITION_GLYPH (cmp, n); \
17308 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
17309 faces[n] = FACE_FROM_ID (f, this_face_id); \
17310 get_char_face_and_encoding (f, c, this_face_id, \
17311 char2b + n, 1, 1); \
17312 } \
17313 \
17314 /* Make glyph_strings for each glyph sequence that is drawable by \
17315 the same face, and append them to HEAD/TAIL. */ \
17316 for (n = 0; n < cmp->glyph_len;) \
17317 { \
17318 s = (struct glyph_string *) alloca (sizeof *s); \
17319 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
17320 append_glyph_string (&(HEAD), &(TAIL), s); \
17321 s->cmp = cmp; \
17322 s->gidx = n; \
17323 s->x = (X); \
17324 \
17325 if (n == 0) \
17326 first_s = s; \
17327 \
17328 n = fill_composite_glyph_string (s, faces, overlaps_p); \
17329 } \
17330 \
17331 ++START; \
17332 s = first_s; \
17333 } while (0)
17334
17335
17336 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
17337 of AREA of glyph row ROW on window W between indices START and END.
17338 HL overrides the face for drawing glyph strings, e.g. it is
17339 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
17340 x-positions of the drawing area.
17341
17342 This is an ugly monster macro construct because we must use alloca
17343 to allocate glyph strings (because draw_glyphs can be called
17344 asynchronously). */
17345
17346 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
17347 do \
17348 { \
17349 HEAD = TAIL = NULL; \
17350 while (START < END) \
17351 { \
17352 struct glyph *first_glyph = (row)->glyphs[area] + START; \
17353 switch (first_glyph->type) \
17354 { \
17355 case CHAR_GLYPH: \
17356 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
17357 HL, X, LAST_X); \
17358 break; \
17359 \
17360 case COMPOSITE_GLYPH: \
17361 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
17362 HL, X, LAST_X); \
17363 break; \
17364 \
17365 case STRETCH_GLYPH: \
17366 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
17367 HL, X, LAST_X); \
17368 break; \
17369 \
17370 case IMAGE_GLYPH: \
17371 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
17372 HL, X, LAST_X); \
17373 break; \
17374 \
17375 default: \
17376 abort (); \
17377 } \
17378 \
17379 set_glyph_string_background_width (s, START, LAST_X); \
17380 (X) += s->width; \
17381 } \
17382 } \
17383 while (0)
17384
17385
17386 /* Draw glyphs between START and END in AREA of ROW on window W,
17387 starting at x-position X. X is relative to AREA in W. HL is a
17388 face-override with the following meaning:
17389
17390 DRAW_NORMAL_TEXT draw normally
17391 DRAW_CURSOR draw in cursor face
17392 DRAW_MOUSE_FACE draw in mouse face.
17393 DRAW_INVERSE_VIDEO draw in mode line face
17394 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
17395 DRAW_IMAGE_RAISED draw an image with a raised relief around it
17396
17397 If OVERLAPS_P is non-zero, draw only the foreground of characters
17398 and clip to the physical height of ROW.
17399
17400 Value is the x-position reached, relative to AREA of W. */
17401
17402 static int
17403 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
17404 struct window *w;
17405 int x;
17406 struct glyph_row *row;
17407 enum glyph_row_area area;
17408 int start, end;
17409 enum draw_glyphs_face hl;
17410 int overlaps_p;
17411 {
17412 struct glyph_string *head, *tail;
17413 struct glyph_string *s;
17414 int last_x, area_width;
17415 int x_reached;
17416 int i, j;
17417 struct frame *f = XFRAME (WINDOW_FRAME (w));
17418 DECLARE_HDC (hdc);
17419
17420 ALLOCATE_HDC (hdc, f);
17421
17422 /* Let's rather be paranoid than getting a SEGV. */
17423 end = min (end, row->used[area]);
17424 start = max (0, start);
17425 start = min (end, start);
17426
17427 /* Translate X to frame coordinates. Set last_x to the right
17428 end of the drawing area. */
17429 if (row->full_width_p)
17430 {
17431 /* X is relative to the left edge of W, without scroll bars
17432 or fringes. */
17433 x += WINDOW_LEFT_EDGE_X (w);
17434 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
17435 }
17436 else
17437 {
17438 int area_left = window_box_left (w, area);
17439 x += area_left;
17440 area_width = window_box_width (w, area);
17441 last_x = area_left + area_width;
17442 }
17443
17444 /* Build a doubly-linked list of glyph_string structures between
17445 head and tail from what we have to draw. Note that the macro
17446 BUILD_GLYPH_STRINGS will modify its start parameter. That's
17447 the reason we use a separate variable `i'. */
17448 i = start;
17449 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
17450 if (tail)
17451 x_reached = tail->x + tail->background_width;
17452 else
17453 x_reached = x;
17454
17455 /* If there are any glyphs with lbearing < 0 or rbearing > width in
17456 the row, redraw some glyphs in front or following the glyph
17457 strings built above. */
17458 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
17459 {
17460 int dummy_x = 0;
17461 struct glyph_string *h, *t;
17462
17463 /* Compute overhangs for all glyph strings. */
17464 if (rif->compute_glyph_string_overhangs)
17465 for (s = head; s; s = s->next)
17466 rif->compute_glyph_string_overhangs (s);
17467
17468 /* Prepend glyph strings for glyphs in front of the first glyph
17469 string that are overwritten because of the first glyph
17470 string's left overhang. The background of all strings
17471 prepended must be drawn because the first glyph string
17472 draws over it. */
17473 i = left_overwritten (head);
17474 if (i >= 0)
17475 {
17476 j = i;
17477 BUILD_GLYPH_STRINGS (j, start, h, t,
17478 DRAW_NORMAL_TEXT, dummy_x, last_x);
17479 start = i;
17480 compute_overhangs_and_x (t, head->x, 1);
17481 prepend_glyph_string_lists (&head, &tail, h, t);
17482 }
17483
17484 /* Prepend glyph strings for glyphs in front of the first glyph
17485 string that overwrite that glyph string because of their
17486 right overhang. For these strings, only the foreground must
17487 be drawn, because it draws over the glyph string at `head'.
17488 The background must not be drawn because this would overwrite
17489 right overhangs of preceding glyphs for which no glyph
17490 strings exist. */
17491 i = left_overwriting (head);
17492 if (i >= 0)
17493 {
17494 BUILD_GLYPH_STRINGS (i, start, h, t,
17495 DRAW_NORMAL_TEXT, dummy_x, last_x);
17496 for (s = h; s; s = s->next)
17497 s->background_filled_p = 1;
17498 compute_overhangs_and_x (t, head->x, 1);
17499 prepend_glyph_string_lists (&head, &tail, h, t);
17500 }
17501
17502 /* Append glyphs strings for glyphs following the last glyph
17503 string tail that are overwritten by tail. The background of
17504 these strings has to be drawn because tail's foreground draws
17505 over it. */
17506 i = right_overwritten (tail);
17507 if (i >= 0)
17508 {
17509 BUILD_GLYPH_STRINGS (end, i, h, t,
17510 DRAW_NORMAL_TEXT, x, last_x);
17511 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17512 append_glyph_string_lists (&head, &tail, h, t);
17513 }
17514
17515 /* Append glyph strings for glyphs following the last glyph
17516 string tail that overwrite tail. The foreground of such
17517 glyphs has to be drawn because it writes into the background
17518 of tail. The background must not be drawn because it could
17519 paint over the foreground of following glyphs. */
17520 i = right_overwriting (tail);
17521 if (i >= 0)
17522 {
17523 BUILD_GLYPH_STRINGS (end, i, h, t,
17524 DRAW_NORMAL_TEXT, x, last_x);
17525 for (s = h; s; s = s->next)
17526 s->background_filled_p = 1;
17527 compute_overhangs_and_x (h, tail->x + tail->width, 0);
17528 append_glyph_string_lists (&head, &tail, h, t);
17529 }
17530 }
17531
17532 /* Draw all strings. */
17533 for (s = head; s; s = s->next)
17534 rif->draw_glyph_string (s);
17535
17536 if (area == TEXT_AREA
17537 && !row->full_width_p
17538 /* When drawing overlapping rows, only the glyph strings'
17539 foreground is drawn, which doesn't erase a cursor
17540 completely. */
17541 && !overlaps_p)
17542 {
17543 int x0 = head ? head->x : x;
17544 int x1 = tail ? tail->x + tail->background_width : x;
17545
17546 int text_left = window_box_left (w, TEXT_AREA);
17547 x0 -= text_left;
17548 x1 -= text_left;
17549
17550 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
17551 row->y, MATRIX_ROW_BOTTOM_Y (row));
17552 }
17553
17554 /* Value is the x-position up to which drawn, relative to AREA of W.
17555 This doesn't include parts drawn because of overhangs. */
17556 if (row->full_width_p)
17557 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
17558 else
17559 x_reached -= window_box_left (w, area);
17560
17561 RELEASE_HDC (hdc, f);
17562
17563 return x_reached;
17564 }
17565
17566
17567 /* Store one glyph for IT->char_to_display in IT->glyph_row.
17568 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17569
17570 static INLINE void
17571 append_glyph (it)
17572 struct it *it;
17573 {
17574 struct glyph *glyph;
17575 enum glyph_row_area area = it->area;
17576
17577 xassert (it->glyph_row);
17578 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
17579
17580 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17581 if (glyph < it->glyph_row->glyphs[area + 1])
17582 {
17583 glyph->charpos = CHARPOS (it->position);
17584 glyph->object = it->object;
17585 glyph->pixel_width = it->pixel_width;
17586 glyph->ascent = it->ascent;
17587 glyph->descent = it->descent;
17588 glyph->voffset = it->voffset;
17589 glyph->type = CHAR_GLYPH;
17590 glyph->multibyte_p = it->multibyte_p;
17591 glyph->left_box_line_p = it->start_of_box_run_p;
17592 glyph->right_box_line_p = it->end_of_box_run_p;
17593 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17594 || it->phys_descent > it->descent);
17595 glyph->padding_p = 0;
17596 glyph->glyph_not_available_p = it->glyph_not_available_p;
17597 glyph->face_id = it->face_id;
17598 glyph->u.ch = it->char_to_display;
17599 glyph->font_type = FONT_TYPE_UNKNOWN;
17600 ++it->glyph_row->used[area];
17601 }
17602 }
17603
17604 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
17605 Called from x_produce_glyphs when IT->glyph_row is non-null. */
17606
17607 static INLINE void
17608 append_composite_glyph (it)
17609 struct it *it;
17610 {
17611 struct glyph *glyph;
17612 enum glyph_row_area area = it->area;
17613
17614 xassert (it->glyph_row);
17615
17616 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17617 if (glyph < it->glyph_row->glyphs[area + 1])
17618 {
17619 glyph->charpos = CHARPOS (it->position);
17620 glyph->object = it->object;
17621 glyph->pixel_width = it->pixel_width;
17622 glyph->ascent = it->ascent;
17623 glyph->descent = it->descent;
17624 glyph->voffset = it->voffset;
17625 glyph->type = COMPOSITE_GLYPH;
17626 glyph->multibyte_p = it->multibyte_p;
17627 glyph->left_box_line_p = it->start_of_box_run_p;
17628 glyph->right_box_line_p = it->end_of_box_run_p;
17629 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
17630 || it->phys_descent > it->descent);
17631 glyph->padding_p = 0;
17632 glyph->glyph_not_available_p = 0;
17633 glyph->face_id = it->face_id;
17634 glyph->u.cmp_id = it->cmp_id;
17635 glyph->font_type = FONT_TYPE_UNKNOWN;
17636 ++it->glyph_row->used[area];
17637 }
17638 }
17639
17640
17641 /* Change IT->ascent and IT->height according to the setting of
17642 IT->voffset. */
17643
17644 static INLINE void
17645 take_vertical_position_into_account (it)
17646 struct it *it;
17647 {
17648 if (it->voffset)
17649 {
17650 if (it->voffset < 0)
17651 /* Increase the ascent so that we can display the text higher
17652 in the line. */
17653 it->ascent += abs (it->voffset);
17654 else
17655 /* Increase the descent so that we can display the text lower
17656 in the line. */
17657 it->descent += it->voffset;
17658 }
17659 }
17660
17661
17662 /* Produce glyphs/get display metrics for the image IT is loaded with.
17663 See the description of struct display_iterator in dispextern.h for
17664 an overview of struct display_iterator. */
17665
17666 static void
17667 produce_image_glyph (it)
17668 struct it *it;
17669 {
17670 struct image *img;
17671 struct face *face;
17672 int face_ascent, glyph_ascent;
17673
17674 xassert (it->what == IT_IMAGE);
17675
17676 face = FACE_FROM_ID (it->f, it->face_id);
17677 img = IMAGE_FROM_ID (it->f, it->image_id);
17678 xassert (img);
17679
17680 /* Make sure X resources of the face and image are loaded. */
17681 PREPARE_FACE_FOR_DISPLAY (it->f, face);
17682 prepare_image_for_display (it->f, img);
17683
17684 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face);
17685 it->descent = it->phys_descent = img->height + 2 * img->vmargin - it->ascent;
17686 it->pixel_width = img->width + 2 * img->hmargin;
17687
17688 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
17689 face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
17690 if (face_ascent > it->ascent)
17691 it->ascent = it->phys_ascent = face_ascent;
17692
17693 it->nglyphs = 1;
17694
17695 if (face->box != FACE_NO_BOX)
17696 {
17697 if (face->box_line_width > 0)
17698 {
17699 it->ascent += face->box_line_width;
17700 it->descent += face->box_line_width;
17701 }
17702
17703 if (it->start_of_box_run_p)
17704 it->pixel_width += abs (face->box_line_width);
17705 if (it->end_of_box_run_p)
17706 it->pixel_width += abs (face->box_line_width);
17707 }
17708
17709 take_vertical_position_into_account (it);
17710
17711 if (it->glyph_row)
17712 {
17713 struct glyph *glyph;
17714 enum glyph_row_area area = it->area;
17715
17716 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17717 if (glyph < it->glyph_row->glyphs[area + 1])
17718 {
17719 glyph->charpos = CHARPOS (it->position);
17720 glyph->object = it->object;
17721 glyph->pixel_width = it->pixel_width;
17722 glyph->ascent = glyph_ascent;
17723 glyph->descent = it->descent;
17724 glyph->voffset = it->voffset;
17725 glyph->type = IMAGE_GLYPH;
17726 glyph->multibyte_p = it->multibyte_p;
17727 glyph->left_box_line_p = it->start_of_box_run_p;
17728 glyph->right_box_line_p = it->end_of_box_run_p;
17729 glyph->overlaps_vertically_p = 0;
17730 glyph->padding_p = 0;
17731 glyph->glyph_not_available_p = 0;
17732 glyph->face_id = it->face_id;
17733 glyph->u.img_id = img->id;
17734 glyph->font_type = FONT_TYPE_UNKNOWN;
17735 ++it->glyph_row->used[area];
17736 }
17737 }
17738 }
17739
17740
17741 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
17742 of the glyph, WIDTH and HEIGHT are the width and height of the
17743 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
17744
17745 static void
17746 append_stretch_glyph (it, object, width, height, ascent)
17747 struct it *it;
17748 Lisp_Object object;
17749 int width, height;
17750 int ascent;
17751 {
17752 struct glyph *glyph;
17753 enum glyph_row_area area = it->area;
17754
17755 xassert (ascent >= 0 && ascent <= height);
17756
17757 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
17758 if (glyph < it->glyph_row->glyphs[area + 1])
17759 {
17760 glyph->charpos = CHARPOS (it->position);
17761 glyph->object = object;
17762 glyph->pixel_width = width;
17763 glyph->ascent = ascent;
17764 glyph->descent = height - ascent;
17765 glyph->voffset = it->voffset;
17766 glyph->type = STRETCH_GLYPH;
17767 glyph->multibyte_p = it->multibyte_p;
17768 glyph->left_box_line_p = it->start_of_box_run_p;
17769 glyph->right_box_line_p = it->end_of_box_run_p;
17770 glyph->overlaps_vertically_p = 0;
17771 glyph->padding_p = 0;
17772 glyph->glyph_not_available_p = 0;
17773 glyph->face_id = it->face_id;
17774 glyph->u.stretch.ascent = ascent;
17775 glyph->u.stretch.height = height;
17776 glyph->font_type = FONT_TYPE_UNKNOWN;
17777 ++it->glyph_row->used[area];
17778 }
17779 }
17780
17781
17782 /* Calculate a width or height in pixels from a specification using
17783 the following elements:
17784
17785 SPEC ::=
17786 NUM - a (fractional) multiple of the default font width/height
17787 (NUM) - specifies exactly NUM pixels
17788 UNIT - a fixed number of pixels, see below.
17789 ELEMENT - size of a display element in pixels, see below.
17790 (NUM . SPEC) - equals NUM * SPEC
17791 (+ SPEC SPEC ...) - add pixel values
17792 (- SPEC SPEC ...) - subtract pixel values
17793 (- SPEC) - negate pixel value
17794
17795 NUM ::=
17796 INT or FLOAT - a number constant
17797 SYMBOL - use symbol's (buffer local) variable binding.
17798
17799 UNIT ::=
17800 in - pixels per inch *)
17801 mm - pixels per 1/1000 meter *)
17802 cm - pixels per 1/100 meter *)
17803 width - width of current font in pixels.
17804 height - height of current font in pixels.
17805
17806 *) using the ratio(s) defined in display-pixels-per-inch.
17807
17808 ELEMENT ::=
17809
17810 left-fringe - left fringe width in pixels
17811 (left-fringe . nil) - left fringe width if inside margins, else 0
17812 (left-fringe . t) - left fringe width if outside margins, else 0
17813
17814 right-fringe - right fringe width in pixels
17815 (right-fringe . nil) - right fringe width if inside margins, else 0
17816 (right-fringe . t) - right fringe width if outside margins, else 0
17817
17818 left-margin - left margin width in pixels
17819 right-margin - right margin width in pixels
17820
17821 scroll-bar - scroll-bar area width in pixels
17822 (scroll-bar . left) - scroll-bar width if on left, else 0
17823 (scroll-bar . right) - scroll-bar width if on right, else 0
17824
17825 Examples:
17826
17827 Pixels corresponding to 5 inches:
17828 (5 . in)
17829
17830 Total width of non-text areas on left side of window:
17831 (+ left-fringe left-margin (scroll-bar . left))
17832
17833 Total width of fringes if inside display margins:
17834 (+ (left-fringe) (right-fringe))
17835
17836 Width of left margin minus width of 1 character in the default font:
17837 (- left-margin 1)
17838
17839 Width of left margin minus width of 2 characters in the current font:
17840 (- left-margin (2 . width))
17841
17842 Width of left fringe plus left margin minus one pixel:
17843 (- (+ left-fringe left-margin) (1))
17844 (+ left-fringe left-margin (- (1)))
17845 (+ left-fringe left-margin (-1))
17846
17847 */
17848
17849 #define NUMVAL(X) \
17850 ((INTEGERP (X) || FLOATP (X)) \
17851 ? XFLOATINT (X) \
17852 : - 1)
17853
17854 static int
17855 calc_pixel_width_or_height (res, it, prop, font, width_p)
17856 double *res;
17857 struct it *it;
17858 Lisp_Object prop;
17859 XFontStruct *font;
17860 int width_p;
17861 {
17862 double pixels;
17863
17864 #define OK_PIXELS(val) ((*res = (val)), 1)
17865
17866 if (SYMBOLP (prop))
17867 {
17868 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17869 {
17870 char *unit = SDATA (SYMBOL_NAME (prop));
17871
17872 if (unit[0] == 'i' && unit[1] == 'n')
17873 pixels = 1.0;
17874 else if (unit[0] == 'm' && unit[1] == 'm')
17875 pixels = 25.4;
17876 else if (unit[0] == 'c' && unit[1] == 'm')
17877 pixels = 2.54;
17878 else
17879 pixels = 0;
17880 if (pixels > 0)
17881 {
17882 double ppi;
17883 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17884 || (CONSP (Vdisplay_pixels_per_inch)
17885 && (ppi = (width_p
17886 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17887 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17888 ppi > 0)))
17889 return OK_PIXELS (ppi / pixels);
17890
17891 return 0;
17892 }
17893 }
17894
17895 if (EQ (prop, Qheight))
17896 return OK_PIXELS (font ? FONT_HEIGHT (font) : FRAME_LINE_HEIGHT (it->f));
17897 if (EQ (prop, Qwidth))
17898 return OK_PIXELS (font ? FONT_WIDTH (font) : FRAME_COLUMN_WIDTH (it->f));
17899 if (EQ (prop, Qleft_fringe))
17900 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17901 if (EQ (prop, Qright_fringe))
17902 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17903 if (EQ (prop, Qleft_margin))
17904 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17905 if (EQ (prop, Qright_margin))
17906 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17907 if (EQ (prop, Qscroll_bar))
17908 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17909
17910 prop = Fbuffer_local_value (prop, it->w->buffer);
17911 }
17912
17913 if (INTEGERP (prop) || FLOATP (prop))
17914 {
17915 int base_unit = (width_p
17916 ? FRAME_COLUMN_WIDTH (it->f)
17917 : FRAME_LINE_HEIGHT (it->f));
17918 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17919 }
17920
17921 if (CONSP (prop))
17922 {
17923 Lisp_Object car = XCAR (prop);
17924 Lisp_Object cdr = XCDR (prop);
17925
17926 if (SYMBOLP (car))
17927 {
17928 if (EQ (car, Qplus) || EQ (car, Qminus))
17929 {
17930 int first = 1;
17931 double px;
17932
17933 pixels = 0;
17934 while (CONSP (cdr))
17935 {
17936 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr), font, width_p))
17937 return 0;
17938 if (first)
17939 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17940 else
17941 pixels += px;
17942 cdr = XCDR (cdr);
17943 }
17944 if (EQ (car, Qminus))
17945 pixels = -pixels;
17946 return OK_PIXELS (pixels);
17947 }
17948
17949 if (EQ (car, Qleft_fringe))
17950 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17951 == !NILP (cdr))
17952 ? WINDOW_LEFT_FRINGE_WIDTH (it->w)
17953 : 0);
17954 if (EQ (car, Qright_fringe))
17955 return OK_PIXELS ((WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17956 == !NILP (cdr))
17957 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17958 : 0);
17959 if (EQ (car, Qscroll_bar))
17960 return OK_PIXELS ((WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17961 == EQ (cdr, Qleft))
17962 ? WINDOW_SCROLL_BAR_AREA_WIDTH (it->w)
17963 : 0);
17964
17965 car = Fbuffer_local_value (car, it->w->buffer);
17966 }
17967
17968 if (INTEGERP (car) || FLOATP (car))
17969 {
17970 double fact;
17971 pixels = XFLOATINT (car);
17972 if (NILP (cdr))
17973 return OK_PIXELS (pixels);
17974 if (calc_pixel_width_or_height (&fact, it, cdr, font, width_p))
17975 return OK_PIXELS (pixels * fact);
17976 return 0;
17977 }
17978
17979 return 0;
17980 }
17981
17982 return 0;
17983 }
17984
17985 /* Produce a stretch glyph for iterator IT. IT->object is the value
17986 of the glyph property displayed. The value must be a list
17987 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
17988 being recognized:
17989
17990 1. `:width WIDTH' specifies that the space should be WIDTH *
17991 canonical char width wide. WIDTH may be an integer or floating
17992 point number.
17993
17994 2. `:relative-width FACTOR' specifies that the width of the stretch
17995 should be computed from the width of the first character having the
17996 `glyph' property, and should be FACTOR times that width.
17997
17998 3. `:align-to HPOS' specifies that the space should be wide enough
17999 to reach HPOS, a value in canonical character units.
18000
18001 Exactly one of the above pairs must be present.
18002
18003 4. `:height HEIGHT' specifies that the height of the stretch produced
18004 should be HEIGHT, measured in canonical character units.
18005
18006 5. `:relative-height FACTOR' specifies that the height of the
18007 stretch should be FACTOR times the height of the characters having
18008 the glyph property.
18009
18010 Either none or exactly one of 4 or 5 must be present.
18011
18012 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18013 of the stretch should be used for the ascent of the stretch.
18014 ASCENT must be in the range 0 <= ASCENT <= 100. */
18015
18016 static void
18017 produce_stretch_glyph (it)
18018 struct it *it;
18019 {
18020 /* (space :width WIDTH :height HEIGHT ...) */
18021 Lisp_Object prop, plist;
18022 int width = 0, height = 0;
18023 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18024 int ascent = 0;
18025 double tem;
18026 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18027 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18028
18029 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18030
18031 /* List should start with `space'. */
18032 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18033 plist = XCDR (it->object);
18034
18035 /* Compute the width of the stretch. */
18036 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18037 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18038 {
18039 /* Absolute width `:width WIDTH' specified and valid. */
18040 zero_width_ok_p = 1;
18041 width = (int)tem;
18042 }
18043 else if (prop = Fplist_get (plist, QCrelative_width),
18044 NUMVAL (prop) > 0)
18045 {
18046 /* Relative width `:relative-width FACTOR' specified and valid.
18047 Compute the width of the characters having the `glyph'
18048 property. */
18049 struct it it2;
18050 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18051
18052 it2 = *it;
18053 if (it->multibyte_p)
18054 {
18055 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18056 - IT_BYTEPOS (*it));
18057 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18058 }
18059 else
18060 it2.c = *p, it2.len = 1;
18061
18062 it2.glyph_row = NULL;
18063 it2.what = IT_CHARACTER;
18064 x_produce_glyphs (&it2);
18065 width = NUMVAL (prop) * it2.pixel_width;
18066 }
18067 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18068 && calc_pixel_width_or_height (&tem, it, prop, font, 1))
18069 {
18070 width = max (0, (int)tem - it->current_x);
18071 zero_width_ok_p = 1;
18072 }
18073 else
18074 /* Nothing specified -> width defaults to canonical char width. */
18075 width = FRAME_COLUMN_WIDTH (it->f);
18076
18077 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18078 width = 1;
18079
18080 /* Compute height. */
18081 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18082 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18083 {
18084 height = (int)tem;
18085 zero_height_ok_p = 1;
18086 }
18087 else if (prop = Fplist_get (plist, QCrelative_height),
18088 NUMVAL (prop) > 0)
18089 height = FONT_HEIGHT (font) * NUMVAL (prop);
18090 else
18091 height = FONT_HEIGHT (font);
18092
18093 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18094 height = 1;
18095
18096 /* Compute percentage of height used for ascent. If
18097 `:ascent ASCENT' is present and valid, use that. Otherwise,
18098 derive the ascent from the font in use. */
18099 if (prop = Fplist_get (plist, QCascent),
18100 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18101 ascent = height * NUMVAL (prop) / 100.0;
18102 else if (!NILP (prop)
18103 && calc_pixel_width_or_height (&tem, it, prop, font, 0))
18104 ascent = min (max (0, (int)tem), height);
18105 else
18106 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18107
18108 if (width > 0 && height > 0 && it->glyph_row)
18109 {
18110 Lisp_Object object = it->stack[it->sp - 1].string;
18111 if (!STRINGP (object))
18112 object = it->w->buffer;
18113 append_stretch_glyph (it, object, width, height, ascent);
18114 }
18115
18116 it->pixel_width = width;
18117 it->ascent = it->phys_ascent = ascent;
18118 it->descent = it->phys_descent = height - it->ascent;
18119 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
18120
18121 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
18122 {
18123 if (face->box_line_width > 0)
18124 {
18125 it->ascent += face->box_line_width;
18126 it->descent += face->box_line_width;
18127 }
18128
18129 if (it->start_of_box_run_p)
18130 it->pixel_width += abs (face->box_line_width);
18131 if (it->end_of_box_run_p)
18132 it->pixel_width += abs (face->box_line_width);
18133 }
18134
18135 take_vertical_position_into_account (it);
18136 }
18137
18138 /* RIF:
18139 Produce glyphs/get display metrics for the display element IT is
18140 loaded with. See the description of struct display_iterator in
18141 dispextern.h for an overview of struct display_iterator. */
18142
18143 void
18144 x_produce_glyphs (it)
18145 struct it *it;
18146 {
18147 it->glyph_not_available_p = 0;
18148
18149 if (it->what == IT_CHARACTER)
18150 {
18151 XChar2b char2b;
18152 XFontStruct *font;
18153 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18154 XCharStruct *pcm;
18155 int font_not_found_p;
18156 struct font_info *font_info;
18157 int boff; /* baseline offset */
18158 /* We may change it->multibyte_p upon unibyte<->multibyte
18159 conversion. So, save the current value now and restore it
18160 later.
18161
18162 Note: It seems that we don't have to record multibyte_p in
18163 struct glyph because the character code itself tells if or
18164 not the character is multibyte. Thus, in the future, we must
18165 consider eliminating the field `multibyte_p' in the struct
18166 glyph. */
18167 int saved_multibyte_p = it->multibyte_p;
18168
18169 /* Maybe translate single-byte characters to multibyte, or the
18170 other way. */
18171 it->char_to_display = it->c;
18172 if (!ASCII_BYTE_P (it->c))
18173 {
18174 if (unibyte_display_via_language_environment
18175 && SINGLE_BYTE_CHAR_P (it->c)
18176 && (it->c >= 0240
18177 || !NILP (Vnonascii_translation_table)))
18178 {
18179 it->char_to_display = unibyte_char_to_multibyte (it->c);
18180 it->multibyte_p = 1;
18181 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18182 face = FACE_FROM_ID (it->f, it->face_id);
18183 }
18184 else if (!SINGLE_BYTE_CHAR_P (it->c)
18185 && !it->multibyte_p)
18186 {
18187 it->multibyte_p = 1;
18188 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18189 face = FACE_FROM_ID (it->f, it->face_id);
18190 }
18191 }
18192
18193 /* Get font to use. Encode IT->char_to_display. */
18194 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18195 &char2b, it->multibyte_p, 0);
18196 font = face->font;
18197
18198 /* When no suitable font found, use the default font. */
18199 font_not_found_p = font == NULL;
18200 if (font_not_found_p)
18201 {
18202 font = FRAME_FONT (it->f);
18203 boff = FRAME_BASELINE_OFFSET (it->f);
18204 font_info = NULL;
18205 }
18206 else
18207 {
18208 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18209 boff = font_info->baseline_offset;
18210 if (font_info->vertical_centering)
18211 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18212 }
18213
18214 if (it->char_to_display >= ' '
18215 && (!it->multibyte_p || it->char_to_display < 128))
18216 {
18217 /* Either unibyte or ASCII. */
18218 int stretched_p;
18219
18220 it->nglyphs = 1;
18221
18222 pcm = rif->per_char_metric (font, &char2b,
18223 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
18224 it->ascent = FONT_BASE (font) + boff;
18225 it->descent = FONT_DESCENT (font) - boff;
18226
18227 if (pcm)
18228 {
18229 it->phys_ascent = pcm->ascent + boff;
18230 it->phys_descent = pcm->descent - boff;
18231 it->pixel_width = pcm->width;
18232 }
18233 else
18234 {
18235 it->glyph_not_available_p = 1;
18236 it->phys_ascent = FONT_BASE (font) + boff;
18237 it->phys_descent = FONT_DESCENT (font) - boff;
18238 it->pixel_width = FONT_WIDTH (font);
18239 }
18240
18241 /* If this is a space inside a region of text with
18242 `space-width' property, change its width. */
18243 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
18244 if (stretched_p)
18245 it->pixel_width *= XFLOATINT (it->space_width);
18246
18247 /* If face has a box, add the box thickness to the character
18248 height. If character has a box line to the left and/or
18249 right, add the box line width to the character's width. */
18250 if (face->box != FACE_NO_BOX)
18251 {
18252 int thick = face->box_line_width;
18253
18254 if (thick > 0)
18255 {
18256 it->ascent += thick;
18257 it->descent += thick;
18258 }
18259 else
18260 thick = -thick;
18261
18262 if (it->start_of_box_run_p)
18263 it->pixel_width += thick;
18264 if (it->end_of_box_run_p)
18265 it->pixel_width += thick;
18266 }
18267
18268 /* If face has an overline, add the height of the overline
18269 (1 pixel) and a 1 pixel margin to the character height. */
18270 if (face->overline_p)
18271 it->ascent += 2;
18272
18273 take_vertical_position_into_account (it);
18274
18275 /* If we have to actually produce glyphs, do it. */
18276 if (it->glyph_row)
18277 {
18278 if (stretched_p)
18279 {
18280 /* Translate a space with a `space-width' property
18281 into a stretch glyph. */
18282 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
18283 / FONT_HEIGHT (font));
18284 append_stretch_glyph (it, it->object, it->pixel_width,
18285 it->ascent + it->descent, ascent);
18286 }
18287 else
18288 append_glyph (it);
18289
18290 /* If characters with lbearing or rbearing are displayed
18291 in this line, record that fact in a flag of the
18292 glyph row. This is used to optimize X output code. */
18293 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
18294 it->glyph_row->contains_overlapping_glyphs_p = 1;
18295 }
18296 }
18297 else if (it->char_to_display == '\n')
18298 {
18299 /* A newline has no width but we need the height of the line. */
18300 it->pixel_width = 0;
18301 it->nglyphs = 0;
18302 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18303 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18304
18305 if (face->box != FACE_NO_BOX
18306 && face->box_line_width > 0)
18307 {
18308 it->ascent += face->box_line_width;
18309 it->descent += face->box_line_width;
18310 }
18311 }
18312 else if (it->char_to_display == '\t')
18313 {
18314 int tab_width = it->tab_width * FRAME_COLUMN_WIDTH (it->f);
18315 int x = it->current_x + it->continuation_lines_width;
18316 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
18317
18318 /* If the distance from the current position to the next tab
18319 stop is less than a canonical character width, use the
18320 tab stop after that. */
18321 if (next_tab_x - x < FRAME_COLUMN_WIDTH (it->f))
18322 next_tab_x += tab_width;
18323
18324 it->pixel_width = next_tab_x - x;
18325 it->nglyphs = 1;
18326 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
18327 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
18328
18329 if (it->glyph_row)
18330 {
18331 append_stretch_glyph (it, it->object, it->pixel_width,
18332 it->ascent + it->descent, it->ascent);
18333 }
18334 }
18335 else
18336 {
18337 /* A multi-byte character. Assume that the display width of the
18338 character is the width of the character multiplied by the
18339 width of the font. */
18340
18341 /* If we found a font, this font should give us the right
18342 metrics. If we didn't find a font, use the frame's
18343 default font and calculate the width of the character
18344 from the charset width; this is what old redisplay code
18345 did. */
18346
18347 pcm = rif->per_char_metric (font, &char2b,
18348 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
18349
18350 if (font_not_found_p || !pcm)
18351 {
18352 int charset = CHAR_CHARSET (it->char_to_display);
18353
18354 it->glyph_not_available_p = 1;
18355 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
18356 * CHARSET_WIDTH (charset));
18357 it->phys_ascent = FONT_BASE (font) + boff;
18358 it->phys_descent = FONT_DESCENT (font) - boff;
18359 }
18360 else
18361 {
18362 it->pixel_width = pcm->width;
18363 it->phys_ascent = pcm->ascent + boff;
18364 it->phys_descent = pcm->descent - boff;
18365 if (it->glyph_row
18366 && (pcm->lbearing < 0
18367 || pcm->rbearing > pcm->width))
18368 it->glyph_row->contains_overlapping_glyphs_p = 1;
18369 }
18370 it->nglyphs = 1;
18371 it->ascent = FONT_BASE (font) + boff;
18372 it->descent = FONT_DESCENT (font) - boff;
18373 if (face->box != FACE_NO_BOX)
18374 {
18375 int thick = face->box_line_width;
18376
18377 if (thick > 0)
18378 {
18379 it->ascent += thick;
18380 it->descent += thick;
18381 }
18382 else
18383 thick = - thick;
18384
18385 if (it->start_of_box_run_p)
18386 it->pixel_width += thick;
18387 if (it->end_of_box_run_p)
18388 it->pixel_width += thick;
18389 }
18390
18391 /* If face has an overline, add the height of the overline
18392 (1 pixel) and a 1 pixel margin to the character height. */
18393 if (face->overline_p)
18394 it->ascent += 2;
18395
18396 take_vertical_position_into_account (it);
18397
18398 if (it->glyph_row)
18399 append_glyph (it);
18400 }
18401 it->multibyte_p = saved_multibyte_p;
18402 }
18403 else if (it->what == IT_COMPOSITION)
18404 {
18405 /* Note: A composition is represented as one glyph in the
18406 glyph matrix. There are no padding glyphs. */
18407 XChar2b char2b;
18408 XFontStruct *font;
18409 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18410 XCharStruct *pcm;
18411 int font_not_found_p;
18412 struct font_info *font_info;
18413 int boff; /* baseline offset */
18414 struct composition *cmp = composition_table[it->cmp_id];
18415
18416 /* Maybe translate single-byte characters to multibyte. */
18417 it->char_to_display = it->c;
18418 if (unibyte_display_via_language_environment
18419 && SINGLE_BYTE_CHAR_P (it->c)
18420 && (it->c >= 0240
18421 || (it->c >= 0200
18422 && !NILP (Vnonascii_translation_table))))
18423 {
18424 it->char_to_display = unibyte_char_to_multibyte (it->c);
18425 }
18426
18427 /* Get face and font to use. Encode IT->char_to_display. */
18428 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
18429 face = FACE_FROM_ID (it->f, it->face_id);
18430 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
18431 &char2b, it->multibyte_p, 0);
18432 font = face->font;
18433
18434 /* When no suitable font found, use the default font. */
18435 font_not_found_p = font == NULL;
18436 if (font_not_found_p)
18437 {
18438 font = FRAME_FONT (it->f);
18439 boff = FRAME_BASELINE_OFFSET (it->f);
18440 font_info = NULL;
18441 }
18442 else
18443 {
18444 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18445 boff = font_info->baseline_offset;
18446 if (font_info->vertical_centering)
18447 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18448 }
18449
18450 /* There are no padding glyphs, so there is only one glyph to
18451 produce for the composition. Important is that pixel_width,
18452 ascent and descent are the values of what is drawn by
18453 draw_glyphs (i.e. the values of the overall glyphs composed). */
18454 it->nglyphs = 1;
18455
18456 /* If we have not yet calculated pixel size data of glyphs of
18457 the composition for the current face font, calculate them
18458 now. Theoretically, we have to check all fonts for the
18459 glyphs, but that requires much time and memory space. So,
18460 here we check only the font of the first glyph. This leads
18461 to incorrect display very rarely, and C-l (recenter) can
18462 correct the display anyway. */
18463 if (cmp->font != (void *) font)
18464 {
18465 /* Ascent and descent of the font of the first character of
18466 this composition (adjusted by baseline offset). Ascent
18467 and descent of overall glyphs should not be less than
18468 them respectively. */
18469 int font_ascent = FONT_BASE (font) + boff;
18470 int font_descent = FONT_DESCENT (font) - boff;
18471 /* Bounding box of the overall glyphs. */
18472 int leftmost, rightmost, lowest, highest;
18473 int i, width, ascent, descent;
18474
18475 cmp->font = (void *) font;
18476
18477 /* Initialize the bounding box. */
18478 if (font_info
18479 && (pcm = rif->per_char_metric (font, &char2b,
18480 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
18481 {
18482 width = pcm->width;
18483 ascent = pcm->ascent;
18484 descent = pcm->descent;
18485 }
18486 else
18487 {
18488 width = FONT_WIDTH (font);
18489 ascent = FONT_BASE (font);
18490 descent = FONT_DESCENT (font);
18491 }
18492
18493 rightmost = width;
18494 lowest = - descent + boff;
18495 highest = ascent + boff;
18496 leftmost = 0;
18497
18498 if (font_info
18499 && font_info->default_ascent
18500 && CHAR_TABLE_P (Vuse_default_ascent)
18501 && !NILP (Faref (Vuse_default_ascent,
18502 make_number (it->char_to_display))))
18503 highest = font_info->default_ascent + boff;
18504
18505 /* Draw the first glyph at the normal position. It may be
18506 shifted to right later if some other glyphs are drawn at
18507 the left. */
18508 cmp->offsets[0] = 0;
18509 cmp->offsets[1] = boff;
18510
18511 /* Set cmp->offsets for the remaining glyphs. */
18512 for (i = 1; i < cmp->glyph_len; i++)
18513 {
18514 int left, right, btm, top;
18515 int ch = COMPOSITION_GLYPH (cmp, i);
18516 int face_id = FACE_FOR_CHAR (it->f, face, ch);
18517
18518 face = FACE_FROM_ID (it->f, face_id);
18519 get_char_face_and_encoding (it->f, ch, face->id,
18520 &char2b, it->multibyte_p, 0);
18521 font = face->font;
18522 if (font == NULL)
18523 {
18524 font = FRAME_FONT (it->f);
18525 boff = FRAME_BASELINE_OFFSET (it->f);
18526 font_info = NULL;
18527 }
18528 else
18529 {
18530 font_info
18531 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
18532 boff = font_info->baseline_offset;
18533 if (font_info->vertical_centering)
18534 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
18535 }
18536
18537 if (font_info
18538 && (pcm = rif->per_char_metric (font, &char2b,
18539 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
18540 {
18541 width = pcm->width;
18542 ascent = pcm->ascent;
18543 descent = pcm->descent;
18544 }
18545 else
18546 {
18547 width = FONT_WIDTH (font);
18548 ascent = 1;
18549 descent = 0;
18550 }
18551
18552 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
18553 {
18554 /* Relative composition with or without
18555 alternate chars. */
18556 left = (leftmost + rightmost - width) / 2;
18557 btm = - descent + boff;
18558 if (font_info && font_info->relative_compose
18559 && (! CHAR_TABLE_P (Vignore_relative_composition)
18560 || NILP (Faref (Vignore_relative_composition,
18561 make_number (ch)))))
18562 {
18563
18564 if (- descent >= font_info->relative_compose)
18565 /* One extra pixel between two glyphs. */
18566 btm = highest + 1;
18567 else if (ascent <= 0)
18568 /* One extra pixel between two glyphs. */
18569 btm = lowest - 1 - ascent - descent;
18570 }
18571 }
18572 else
18573 {
18574 /* A composition rule is specified by an integer
18575 value that encodes global and new reference
18576 points (GREF and NREF). GREF and NREF are
18577 specified by numbers as below:
18578
18579 0---1---2 -- ascent
18580 | |
18581 | |
18582 | |
18583 9--10--11 -- center
18584 | |
18585 ---3---4---5--- baseline
18586 | |
18587 6---7---8 -- descent
18588 */
18589 int rule = COMPOSITION_RULE (cmp, i);
18590 int gref, nref, grefx, grefy, nrefx, nrefy;
18591
18592 COMPOSITION_DECODE_RULE (rule, gref, nref);
18593 grefx = gref % 3, nrefx = nref % 3;
18594 grefy = gref / 3, nrefy = nref / 3;
18595
18596 left = (leftmost
18597 + grefx * (rightmost - leftmost) / 2
18598 - nrefx * width / 2);
18599 btm = ((grefy == 0 ? highest
18600 : grefy == 1 ? 0
18601 : grefy == 2 ? lowest
18602 : (highest + lowest) / 2)
18603 - (nrefy == 0 ? ascent + descent
18604 : nrefy == 1 ? descent - boff
18605 : nrefy == 2 ? 0
18606 : (ascent + descent) / 2));
18607 }
18608
18609 cmp->offsets[i * 2] = left;
18610 cmp->offsets[i * 2 + 1] = btm + descent;
18611
18612 /* Update the bounding box of the overall glyphs. */
18613 right = left + width;
18614 top = btm + descent + ascent;
18615 if (left < leftmost)
18616 leftmost = left;
18617 if (right > rightmost)
18618 rightmost = right;
18619 if (top > highest)
18620 highest = top;
18621 if (btm < lowest)
18622 lowest = btm;
18623 }
18624
18625 /* If there are glyphs whose x-offsets are negative,
18626 shift all glyphs to the right and make all x-offsets
18627 non-negative. */
18628 if (leftmost < 0)
18629 {
18630 for (i = 0; i < cmp->glyph_len; i++)
18631 cmp->offsets[i * 2] -= leftmost;
18632 rightmost -= leftmost;
18633 }
18634
18635 cmp->pixel_width = rightmost;
18636 cmp->ascent = highest;
18637 cmp->descent = - lowest;
18638 if (cmp->ascent < font_ascent)
18639 cmp->ascent = font_ascent;
18640 if (cmp->descent < font_descent)
18641 cmp->descent = font_descent;
18642 }
18643
18644 it->pixel_width = cmp->pixel_width;
18645 it->ascent = it->phys_ascent = cmp->ascent;
18646 it->descent = it->phys_descent = cmp->descent;
18647
18648 if (face->box != FACE_NO_BOX)
18649 {
18650 int thick = face->box_line_width;
18651
18652 if (thick > 0)
18653 {
18654 it->ascent += thick;
18655 it->descent += thick;
18656 }
18657 else
18658 thick = - thick;
18659
18660 if (it->start_of_box_run_p)
18661 it->pixel_width += thick;
18662 if (it->end_of_box_run_p)
18663 it->pixel_width += thick;
18664 }
18665
18666 /* If face has an overline, add the height of the overline
18667 (1 pixel) and a 1 pixel margin to the character height. */
18668 if (face->overline_p)
18669 it->ascent += 2;
18670
18671 take_vertical_position_into_account (it);
18672
18673 if (it->glyph_row)
18674 append_composite_glyph (it);
18675 }
18676 else if (it->what == IT_IMAGE)
18677 produce_image_glyph (it);
18678 else if (it->what == IT_STRETCH)
18679 produce_stretch_glyph (it);
18680
18681 /* Accumulate dimensions. Note: can't assume that it->descent > 0
18682 because this isn't true for images with `:ascent 100'. */
18683 xassert (it->ascent >= 0 && it->descent >= 0);
18684 if (it->area == TEXT_AREA)
18685 it->current_x += it->pixel_width;
18686
18687 it->descent += it->extra_line_spacing;
18688
18689 it->max_ascent = max (it->max_ascent, it->ascent);
18690 it->max_descent = max (it->max_descent, it->descent);
18691 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
18692 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
18693 }
18694
18695 /* EXPORT for RIF:
18696 Output LEN glyphs starting at START at the nominal cursor position.
18697 Advance the nominal cursor over the text. The global variable
18698 updated_window contains the window being updated, updated_row is
18699 the glyph row being updated, and updated_area is the area of that
18700 row being updated. */
18701
18702 void
18703 x_write_glyphs (start, len)
18704 struct glyph *start;
18705 int len;
18706 {
18707 int x, hpos;
18708
18709 xassert (updated_window && updated_row);
18710 BLOCK_INPUT;
18711
18712 /* Write glyphs. */
18713
18714 hpos = start - updated_row->glyphs[updated_area];
18715 x = draw_glyphs (updated_window, output_cursor.x,
18716 updated_row, updated_area,
18717 hpos, hpos + len,
18718 DRAW_NORMAL_TEXT, 0);
18719
18720 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
18721 if (updated_area == TEXT_AREA
18722 && updated_window->phys_cursor_on_p
18723 && updated_window->phys_cursor.vpos == output_cursor.vpos
18724 && updated_window->phys_cursor.hpos >= hpos
18725 && updated_window->phys_cursor.hpos < hpos + len)
18726 updated_window->phys_cursor_on_p = 0;
18727
18728 UNBLOCK_INPUT;
18729
18730 /* Advance the output cursor. */
18731 output_cursor.hpos += len;
18732 output_cursor.x = x;
18733 }
18734
18735
18736 /* EXPORT for RIF:
18737 Insert LEN glyphs from START at the nominal cursor position. */
18738
18739 void
18740 x_insert_glyphs (start, len)
18741 struct glyph *start;
18742 int len;
18743 {
18744 struct frame *f;
18745 struct window *w;
18746 int line_height, shift_by_width, shifted_region_width;
18747 struct glyph_row *row;
18748 struct glyph *glyph;
18749 int frame_x, frame_y, hpos;
18750
18751 xassert (updated_window && updated_row);
18752 BLOCK_INPUT;
18753 w = updated_window;
18754 f = XFRAME (WINDOW_FRAME (w));
18755
18756 /* Get the height of the line we are in. */
18757 row = updated_row;
18758 line_height = row->height;
18759
18760 /* Get the width of the glyphs to insert. */
18761 shift_by_width = 0;
18762 for (glyph = start; glyph < start + len; ++glyph)
18763 shift_by_width += glyph->pixel_width;
18764
18765 /* Get the width of the region to shift right. */
18766 shifted_region_width = (window_box_width (w, updated_area)
18767 - output_cursor.x
18768 - shift_by_width);
18769
18770 /* Shift right. */
18771 frame_x = window_box_left (w, updated_area) + output_cursor.x;
18772 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
18773
18774 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
18775 line_height, shift_by_width);
18776
18777 /* Write the glyphs. */
18778 hpos = start - row->glyphs[updated_area];
18779 draw_glyphs (w, output_cursor.x, row, updated_area,
18780 hpos, hpos + len,
18781 DRAW_NORMAL_TEXT, 0);
18782
18783 /* Advance the output cursor. */
18784 output_cursor.hpos += len;
18785 output_cursor.x += shift_by_width;
18786 UNBLOCK_INPUT;
18787 }
18788
18789
18790 /* EXPORT for RIF:
18791 Erase the current text line from the nominal cursor position
18792 (inclusive) to pixel column TO_X (exclusive). The idea is that
18793 everything from TO_X onward is already erased.
18794
18795 TO_X is a pixel position relative to updated_area of
18796 updated_window. TO_X == -1 means clear to the end of this area. */
18797
18798 void
18799 x_clear_end_of_line (to_x)
18800 int to_x;
18801 {
18802 struct frame *f;
18803 struct window *w = updated_window;
18804 int max_x, min_y, max_y;
18805 int from_x, from_y, to_y;
18806
18807 xassert (updated_window && updated_row);
18808 f = XFRAME (w->frame);
18809
18810 if (updated_row->full_width_p)
18811 max_x = WINDOW_TOTAL_WIDTH (w);
18812 else
18813 max_x = window_box_width (w, updated_area);
18814 max_y = window_text_bottom_y (w);
18815
18816 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
18817 of window. For TO_X > 0, truncate to end of drawing area. */
18818 if (to_x == 0)
18819 return;
18820 else if (to_x < 0)
18821 to_x = max_x;
18822 else
18823 to_x = min (to_x, max_x);
18824
18825 to_y = min (max_y, output_cursor.y + updated_row->height);
18826
18827 /* Notice if the cursor will be cleared by this operation. */
18828 if (!updated_row->full_width_p)
18829 notice_overwritten_cursor (w, updated_area,
18830 output_cursor.x, -1,
18831 updated_row->y,
18832 MATRIX_ROW_BOTTOM_Y (updated_row));
18833
18834 from_x = output_cursor.x;
18835
18836 /* Translate to frame coordinates. */
18837 if (updated_row->full_width_p)
18838 {
18839 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
18840 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
18841 }
18842 else
18843 {
18844 int area_left = window_box_left (w, updated_area);
18845 from_x += area_left;
18846 to_x += area_left;
18847 }
18848
18849 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
18850 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
18851 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
18852
18853 /* Prevent inadvertently clearing to end of the X window. */
18854 if (to_x > from_x && to_y > from_y)
18855 {
18856 BLOCK_INPUT;
18857 rif->clear_frame_area (f, from_x, from_y,
18858 to_x - from_x, to_y - from_y);
18859 UNBLOCK_INPUT;
18860 }
18861 }
18862
18863 #endif /* HAVE_WINDOW_SYSTEM */
18864
18865
18866 \f
18867 /***********************************************************************
18868 Cursor types
18869 ***********************************************************************/
18870
18871 /* Value is the internal representation of the specified cursor type
18872 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
18873 of the bar cursor. */
18874
18875 static enum text_cursor_kinds
18876 get_specified_cursor_type (arg, width)
18877 Lisp_Object arg;
18878 int *width;
18879 {
18880 enum text_cursor_kinds type;
18881
18882 if (NILP (arg))
18883 return NO_CURSOR;
18884
18885 if (EQ (arg, Qbox))
18886 return FILLED_BOX_CURSOR;
18887
18888 if (EQ (arg, Qhollow))
18889 return HOLLOW_BOX_CURSOR;
18890
18891 if (EQ (arg, Qbar))
18892 {
18893 *width = 2;
18894 return BAR_CURSOR;
18895 }
18896
18897 if (CONSP (arg)
18898 && EQ (XCAR (arg), Qbar)
18899 && INTEGERP (XCDR (arg))
18900 && XINT (XCDR (arg)) >= 0)
18901 {
18902 *width = XINT (XCDR (arg));
18903 return BAR_CURSOR;
18904 }
18905
18906 if (EQ (arg, Qhbar))
18907 {
18908 *width = 2;
18909 return HBAR_CURSOR;
18910 }
18911
18912 if (CONSP (arg)
18913 && EQ (XCAR (arg), Qhbar)
18914 && INTEGERP (XCDR (arg))
18915 && XINT (XCDR (arg)) >= 0)
18916 {
18917 *width = XINT (XCDR (arg));
18918 return HBAR_CURSOR;
18919 }
18920
18921 /* Treat anything unknown as "hollow box cursor".
18922 It was bad to signal an error; people have trouble fixing
18923 .Xdefaults with Emacs, when it has something bad in it. */
18924 type = HOLLOW_BOX_CURSOR;
18925
18926 return type;
18927 }
18928
18929 /* Set the default cursor types for specified frame. */
18930 void
18931 set_frame_cursor_types (f, arg)
18932 struct frame *f;
18933 Lisp_Object arg;
18934 {
18935 int width;
18936 Lisp_Object tem;
18937
18938 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
18939 FRAME_CURSOR_WIDTH (f) = width;
18940
18941 /* By default, set up the blink-off state depending on the on-state. */
18942
18943 tem = Fassoc (arg, Vblink_cursor_alist);
18944 if (!NILP (tem))
18945 {
18946 FRAME_BLINK_OFF_CURSOR (f)
18947 = get_specified_cursor_type (XCDR (tem), &width);
18948 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
18949 }
18950 else
18951 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
18952 }
18953
18954
18955 /* Return the cursor we want to be displayed in window W. Return
18956 width of bar/hbar cursor through WIDTH arg. Return with
18957 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
18958 (i.e. if the `system caret' should track this cursor).
18959
18960 In a mini-buffer window, we want the cursor only to appear if we
18961 are reading input from this window. For the selected window, we
18962 want the cursor type given by the frame parameter or buffer local
18963 setting of cursor-type. If explicitly marked off, draw no cursor.
18964 In all other cases, we want a hollow box cursor. */
18965
18966 static enum text_cursor_kinds
18967 get_window_cursor_type (w, glyph, width, active_cursor)
18968 struct window *w;
18969 struct glyph *glyph;
18970 int *width;
18971 int *active_cursor;
18972 {
18973 struct frame *f = XFRAME (w->frame);
18974 struct buffer *b = XBUFFER (w->buffer);
18975 int cursor_type = DEFAULT_CURSOR;
18976 Lisp_Object alt_cursor;
18977 int non_selected = 0;
18978
18979 *active_cursor = 1;
18980
18981 /* Echo area */
18982 if (cursor_in_echo_area
18983 && FRAME_HAS_MINIBUF_P (f)
18984 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
18985 {
18986 if (w == XWINDOW (echo_area_window))
18987 {
18988 *width = FRAME_CURSOR_WIDTH (f);
18989 return FRAME_DESIRED_CURSOR (f);
18990 }
18991
18992 *active_cursor = 0;
18993 non_selected = 1;
18994 }
18995
18996 /* Nonselected window or nonselected frame. */
18997 else if (w != XWINDOW (f->selected_window)
18998 #ifdef HAVE_WINDOW_SYSTEM
18999 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
19000 #endif
19001 )
19002 {
19003 *active_cursor = 0;
19004
19005 if (MINI_WINDOW_P (w) && minibuf_level == 0)
19006 return NO_CURSOR;
19007
19008 non_selected = 1;
19009 }
19010
19011 /* Never display a cursor in a window in which cursor-type is nil. */
19012 if (NILP (b->cursor_type))
19013 return NO_CURSOR;
19014
19015 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
19016 if (non_selected)
19017 {
19018 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
19019 return get_specified_cursor_type (alt_cursor, width);
19020 }
19021
19022 /* Get the normal cursor type for this window. */
19023 if (EQ (b->cursor_type, Qt))
19024 {
19025 cursor_type = FRAME_DESIRED_CURSOR (f);
19026 *width = FRAME_CURSOR_WIDTH (f);
19027 }
19028 else
19029 cursor_type = get_specified_cursor_type (b->cursor_type, width);
19030
19031 /* Use normal cursor if not blinked off. */
19032 if (!w->cursor_off_p)
19033 {
19034 if (glyph->type == IMAGE_GLYPH) {
19035 if (cursor_type == FILLED_BOX_CURSOR)
19036 cursor_type = HOLLOW_BOX_CURSOR;
19037 }
19038 return cursor_type;
19039 }
19040
19041 /* Cursor is blinked off, so determine how to "toggle" it. */
19042
19043 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
19044 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
19045 return get_specified_cursor_type (XCDR (alt_cursor), width);
19046
19047 /* Then see if frame has specified a specific blink off cursor type. */
19048 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
19049 {
19050 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
19051 return FRAME_BLINK_OFF_CURSOR (f);
19052 }
19053
19054 #if 0
19055 /* Some people liked having a permanently visible blinking cursor,
19056 while others had very strong opinions against it. So it was
19057 decided to remove it. KFS 2003-09-03 */
19058
19059 /* Finally perform built-in cursor blinking:
19060 filled box <-> hollow box
19061 wide [h]bar <-> narrow [h]bar
19062 narrow [h]bar <-> no cursor
19063 other type <-> no cursor */
19064
19065 if (cursor_type == FILLED_BOX_CURSOR)
19066 return HOLLOW_BOX_CURSOR;
19067
19068 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
19069 {
19070 *width = 1;
19071 return cursor_type;
19072 }
19073 #endif
19074
19075 return NO_CURSOR;
19076 }
19077
19078
19079 #ifdef HAVE_WINDOW_SYSTEM
19080
19081 /* Notice when the text cursor of window W has been completely
19082 overwritten by a drawing operation that outputs glyphs in AREA
19083 starting at X0 and ending at X1 in the line starting at Y0 and
19084 ending at Y1. X coordinates are area-relative. X1 < 0 means all
19085 the rest of the line after X0 has been written. Y coordinates
19086 are window-relative. */
19087
19088 static void
19089 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
19090 struct window *w;
19091 enum glyph_row_area area;
19092 int x0, y0, x1, y1;
19093 {
19094 int cx0, cx1, cy0, cy1;
19095 struct glyph_row *row;
19096
19097 if (!w->phys_cursor_on_p)
19098 return;
19099 if (area != TEXT_AREA)
19100 return;
19101
19102 row = w->current_matrix->rows + w->phys_cursor.vpos;
19103 if (!row->displays_text_p)
19104 return;
19105
19106 if (row->cursor_in_fringe_p)
19107 {
19108 row->cursor_in_fringe_p = 0;
19109 draw_fringe_bitmap (w, row, 0);
19110 w->phys_cursor_on_p = 0;
19111 return;
19112 }
19113
19114 cx0 = w->phys_cursor.x;
19115 cx1 = cx0 + w->phys_cursor_width;
19116 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
19117 return;
19118
19119 /* The cursor image will be completely removed from the
19120 screen if the output area intersects the cursor area in
19121 y-direction. When we draw in [y0 y1[, and some part of
19122 the cursor is at y < y0, that part must have been drawn
19123 before. When scrolling, the cursor is erased before
19124 actually scrolling, so we don't come here. When not
19125 scrolling, the rows above the old cursor row must have
19126 changed, and in this case these rows must have written
19127 over the cursor image.
19128
19129 Likewise if part of the cursor is below y1, with the
19130 exception of the cursor being in the first blank row at
19131 the buffer and window end because update_text_area
19132 doesn't draw that row. (Except when it does, but
19133 that's handled in update_text_area.) */
19134
19135 cy0 = w->phys_cursor.y;
19136 cy1 = cy0 + w->phys_cursor_height;
19137 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
19138 return;
19139
19140 w->phys_cursor_on_p = 0;
19141 }
19142
19143 #endif /* HAVE_WINDOW_SYSTEM */
19144
19145 \f
19146 /************************************************************************
19147 Mouse Face
19148 ************************************************************************/
19149
19150 #ifdef HAVE_WINDOW_SYSTEM
19151
19152 /* EXPORT for RIF:
19153 Fix the display of area AREA of overlapping row ROW in window W. */
19154
19155 void
19156 x_fix_overlapping_area (w, row, area)
19157 struct window *w;
19158 struct glyph_row *row;
19159 enum glyph_row_area area;
19160 {
19161 int i, x;
19162
19163 BLOCK_INPUT;
19164
19165 x = 0;
19166 for (i = 0; i < row->used[area];)
19167 {
19168 if (row->glyphs[area][i].overlaps_vertically_p)
19169 {
19170 int start = i, start_x = x;
19171
19172 do
19173 {
19174 x += row->glyphs[area][i].pixel_width;
19175 ++i;
19176 }
19177 while (i < row->used[area]
19178 && row->glyphs[area][i].overlaps_vertically_p);
19179
19180 draw_glyphs (w, start_x, row, area,
19181 start, i,
19182 DRAW_NORMAL_TEXT, 1);
19183 }
19184 else
19185 {
19186 x += row->glyphs[area][i].pixel_width;
19187 ++i;
19188 }
19189 }
19190
19191 UNBLOCK_INPUT;
19192 }
19193
19194
19195 /* EXPORT:
19196 Draw the cursor glyph of window W in glyph row ROW. See the
19197 comment of draw_glyphs for the meaning of HL. */
19198
19199 void
19200 draw_phys_cursor_glyph (w, row, hl)
19201 struct window *w;
19202 struct glyph_row *row;
19203 enum draw_glyphs_face hl;
19204 {
19205 /* If cursor hpos is out of bounds, don't draw garbage. This can
19206 happen in mini-buffer windows when switching between echo area
19207 glyphs and mini-buffer. */
19208 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
19209 {
19210 int on_p = w->phys_cursor_on_p;
19211 int x1;
19212 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
19213 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
19214 hl, 0);
19215 w->phys_cursor_on_p = on_p;
19216
19217 if (hl == DRAW_CURSOR)
19218 w->phys_cursor_width = x1 - w->phys_cursor.x;
19219 /* When we erase the cursor, and ROW is overlapped by other
19220 rows, make sure that these overlapping parts of other rows
19221 are redrawn. */
19222 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
19223 {
19224 if (row > w->current_matrix->rows
19225 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
19226 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
19227
19228 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
19229 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
19230 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
19231 }
19232 }
19233 }
19234
19235
19236 /* EXPORT:
19237 Erase the image of a cursor of window W from the screen. */
19238
19239 void
19240 erase_phys_cursor (w)
19241 struct window *w;
19242 {
19243 struct frame *f = XFRAME (w->frame);
19244 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
19245 int hpos = w->phys_cursor.hpos;
19246 int vpos = w->phys_cursor.vpos;
19247 int mouse_face_here_p = 0;
19248 struct glyph_matrix *active_glyphs = w->current_matrix;
19249 struct glyph_row *cursor_row;
19250 struct glyph *cursor_glyph;
19251 enum draw_glyphs_face hl;
19252
19253 /* No cursor displayed or row invalidated => nothing to do on the
19254 screen. */
19255 if (w->phys_cursor_type == NO_CURSOR)
19256 goto mark_cursor_off;
19257
19258 /* VPOS >= active_glyphs->nrows means that window has been resized.
19259 Don't bother to erase the cursor. */
19260 if (vpos >= active_glyphs->nrows)
19261 goto mark_cursor_off;
19262
19263 /* If row containing cursor is marked invalid, there is nothing we
19264 can do. */
19265 cursor_row = MATRIX_ROW (active_glyphs, vpos);
19266 if (!cursor_row->enabled_p)
19267 goto mark_cursor_off;
19268
19269 /* If row is completely invisible, don't attempt to delete a cursor which
19270 isn't there. This can happen if cursor is at top of a window, and
19271 we switch to a buffer with a header line in that window. */
19272 if (cursor_row->visible_height <= 0)
19273 goto mark_cursor_off;
19274
19275 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
19276 if (cursor_row->cursor_in_fringe_p)
19277 {
19278 cursor_row->cursor_in_fringe_p = 0;
19279 draw_fringe_bitmap (w, cursor_row, 0);
19280 goto mark_cursor_off;
19281 }
19282
19283 /* This can happen when the new row is shorter than the old one.
19284 In this case, either draw_glyphs or clear_end_of_line
19285 should have cleared the cursor. Note that we wouldn't be
19286 able to erase the cursor in this case because we don't have a
19287 cursor glyph at hand. */
19288 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
19289 goto mark_cursor_off;
19290
19291 /* If the cursor is in the mouse face area, redisplay that when
19292 we clear the cursor. */
19293 if (! NILP (dpyinfo->mouse_face_window)
19294 && w == XWINDOW (dpyinfo->mouse_face_window)
19295 && (vpos > dpyinfo->mouse_face_beg_row
19296 || (vpos == dpyinfo->mouse_face_beg_row
19297 && hpos >= dpyinfo->mouse_face_beg_col))
19298 && (vpos < dpyinfo->mouse_face_end_row
19299 || (vpos == dpyinfo->mouse_face_end_row
19300 && hpos < dpyinfo->mouse_face_end_col))
19301 /* Don't redraw the cursor's spot in mouse face if it is at the
19302 end of a line (on a newline). The cursor appears there, but
19303 mouse highlighting does not. */
19304 && cursor_row->used[TEXT_AREA] > hpos)
19305 mouse_face_here_p = 1;
19306
19307 /* Maybe clear the display under the cursor. */
19308 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
19309 {
19310 int x, y;
19311 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
19312
19313 cursor_glyph = get_phys_cursor_glyph (w);
19314 if (cursor_glyph == NULL)
19315 goto mark_cursor_off;
19316
19317 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
19318 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
19319
19320 rif->clear_frame_area (f, x, y,
19321 cursor_glyph->pixel_width, cursor_row->visible_height);
19322 }
19323
19324 /* Erase the cursor by redrawing the character underneath it. */
19325 if (mouse_face_here_p)
19326 hl = DRAW_MOUSE_FACE;
19327 else
19328 hl = DRAW_NORMAL_TEXT;
19329 draw_phys_cursor_glyph (w, cursor_row, hl);
19330
19331 mark_cursor_off:
19332 w->phys_cursor_on_p = 0;
19333 w->phys_cursor_type = NO_CURSOR;
19334 }
19335
19336
19337 /* EXPORT:
19338 Display or clear cursor of window W. If ON is zero, clear the
19339 cursor. If it is non-zero, display the cursor. If ON is nonzero,
19340 where to put the cursor is specified by HPOS, VPOS, X and Y. */
19341
19342 void
19343 display_and_set_cursor (w, on, hpos, vpos, x, y)
19344 struct window *w;
19345 int on, hpos, vpos, x, y;
19346 {
19347 struct frame *f = XFRAME (w->frame);
19348 int new_cursor_type;
19349 int new_cursor_width;
19350 int active_cursor;
19351 struct glyph_matrix *current_glyphs;
19352 struct glyph_row *glyph_row;
19353 struct glyph *glyph;
19354
19355 /* This is pointless on invisible frames, and dangerous on garbaged
19356 windows and frames; in the latter case, the frame or window may
19357 be in the midst of changing its size, and x and y may be off the
19358 window. */
19359 if (! FRAME_VISIBLE_P (f)
19360 || FRAME_GARBAGED_P (f)
19361 || vpos >= w->current_matrix->nrows
19362 || hpos >= w->current_matrix->matrix_w)
19363 return;
19364
19365 /* If cursor is off and we want it off, return quickly. */
19366 if (!on && !w->phys_cursor_on_p)
19367 return;
19368
19369 current_glyphs = w->current_matrix;
19370 glyph_row = MATRIX_ROW (current_glyphs, vpos);
19371 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
19372
19373 /* If cursor row is not enabled, we don't really know where to
19374 display the cursor. */
19375 if (!glyph_row->enabled_p)
19376 {
19377 w->phys_cursor_on_p = 0;
19378 return;
19379 }
19380
19381 xassert (interrupt_input_blocked);
19382
19383 /* Set new_cursor_type to the cursor we want to be displayed. */
19384 new_cursor_type = get_window_cursor_type (w, glyph,
19385 &new_cursor_width, &active_cursor);
19386
19387 /* If cursor is currently being shown and we don't want it to be or
19388 it is in the wrong place, or the cursor type is not what we want,
19389 erase it. */
19390 if (w->phys_cursor_on_p
19391 && (!on
19392 || w->phys_cursor.x != x
19393 || w->phys_cursor.y != y
19394 || new_cursor_type != w->phys_cursor_type
19395 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
19396 && new_cursor_width != w->phys_cursor_width)))
19397 erase_phys_cursor (w);
19398
19399 /* Don't check phys_cursor_on_p here because that flag is only set
19400 to zero in some cases where we know that the cursor has been
19401 completely erased, to avoid the extra work of erasing the cursor
19402 twice. In other words, phys_cursor_on_p can be 1 and the cursor
19403 still not be visible, or it has only been partly erased. */
19404 if (on)
19405 {
19406 w->phys_cursor_ascent = glyph_row->ascent;
19407 w->phys_cursor_height = glyph_row->height;
19408
19409 /* Set phys_cursor_.* before x_draw_.* is called because some
19410 of them may need the information. */
19411 w->phys_cursor.x = x;
19412 w->phys_cursor.y = glyph_row->y;
19413 w->phys_cursor.hpos = hpos;
19414 w->phys_cursor.vpos = vpos;
19415 }
19416
19417 rif->draw_window_cursor (w, glyph_row, x, y,
19418 new_cursor_type, new_cursor_width,
19419 on, active_cursor);
19420 }
19421
19422
19423 /* Switch the display of W's cursor on or off, according to the value
19424 of ON. */
19425
19426 static void
19427 update_window_cursor (w, on)
19428 struct window *w;
19429 int on;
19430 {
19431 /* Don't update cursor in windows whose frame is in the process
19432 of being deleted. */
19433 if (w->current_matrix)
19434 {
19435 BLOCK_INPUT;
19436 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
19437 w->phys_cursor.x, w->phys_cursor.y);
19438 UNBLOCK_INPUT;
19439 }
19440 }
19441
19442
19443 /* Call update_window_cursor with parameter ON_P on all leaf windows
19444 in the window tree rooted at W. */
19445
19446 static void
19447 update_cursor_in_window_tree (w, on_p)
19448 struct window *w;
19449 int on_p;
19450 {
19451 while (w)
19452 {
19453 if (!NILP (w->hchild))
19454 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
19455 else if (!NILP (w->vchild))
19456 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
19457 else
19458 update_window_cursor (w, on_p);
19459
19460 w = NILP (w->next) ? 0 : XWINDOW (w->next);
19461 }
19462 }
19463
19464
19465 /* EXPORT:
19466 Display the cursor on window W, or clear it, according to ON_P.
19467 Don't change the cursor's position. */
19468
19469 void
19470 x_update_cursor (f, on_p)
19471 struct frame *f;
19472 int on_p;
19473 {
19474 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
19475 }
19476
19477
19478 /* EXPORT:
19479 Clear the cursor of window W to background color, and mark the
19480 cursor as not shown. This is used when the text where the cursor
19481 is is about to be rewritten. */
19482
19483 void
19484 x_clear_cursor (w)
19485 struct window *w;
19486 {
19487 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
19488 update_window_cursor (w, 0);
19489 }
19490
19491
19492 /* EXPORT:
19493 Display the active region described by mouse_face_* according to DRAW. */
19494
19495 void
19496 show_mouse_face (dpyinfo, draw)
19497 Display_Info *dpyinfo;
19498 enum draw_glyphs_face draw;
19499 {
19500 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
19501 struct frame *f = XFRAME (WINDOW_FRAME (w));
19502
19503 if (/* If window is in the process of being destroyed, don't bother
19504 to do anything. */
19505 w->current_matrix != NULL
19506 /* Don't update mouse highlight if hidden */
19507 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
19508 /* Recognize when we are called to operate on rows that don't exist
19509 anymore. This can happen when a window is split. */
19510 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
19511 {
19512 int phys_cursor_on_p = w->phys_cursor_on_p;
19513 struct glyph_row *row, *first, *last;
19514
19515 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
19516 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
19517
19518 for (row = first; row <= last && row->enabled_p; ++row)
19519 {
19520 int start_hpos, end_hpos, start_x;
19521
19522 /* For all but the first row, the highlight starts at column 0. */
19523 if (row == first)
19524 {
19525 start_hpos = dpyinfo->mouse_face_beg_col;
19526 start_x = dpyinfo->mouse_face_beg_x;
19527 }
19528 else
19529 {
19530 start_hpos = 0;
19531 start_x = 0;
19532 }
19533
19534 if (row == last)
19535 end_hpos = dpyinfo->mouse_face_end_col;
19536 else
19537 end_hpos = row->used[TEXT_AREA];
19538
19539 if (end_hpos > start_hpos)
19540 {
19541 draw_glyphs (w, start_x, row, TEXT_AREA,
19542 start_hpos, end_hpos,
19543 draw, 0);
19544
19545 row->mouse_face_p
19546 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
19547 }
19548 }
19549
19550 /* When we've written over the cursor, arrange for it to
19551 be displayed again. */
19552 if (phys_cursor_on_p && !w->phys_cursor_on_p)
19553 {
19554 BLOCK_INPUT;
19555 display_and_set_cursor (w, 1,
19556 w->phys_cursor.hpos, w->phys_cursor.vpos,
19557 w->phys_cursor.x, w->phys_cursor.y);
19558 UNBLOCK_INPUT;
19559 }
19560 }
19561
19562 /* Change the mouse cursor. */
19563 if (draw == DRAW_NORMAL_TEXT)
19564 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
19565 else if (draw == DRAW_MOUSE_FACE)
19566 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
19567 else
19568 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
19569 }
19570
19571 /* EXPORT:
19572 Clear out the mouse-highlighted active region.
19573 Redraw it un-highlighted first. Value is non-zero if mouse
19574 face was actually drawn unhighlighted. */
19575
19576 int
19577 clear_mouse_face (dpyinfo)
19578 Display_Info *dpyinfo;
19579 {
19580 int cleared = 0;
19581
19582 if (!NILP (dpyinfo->mouse_face_window))
19583 {
19584 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
19585 cleared = 1;
19586 }
19587
19588 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
19589 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
19590 dpyinfo->mouse_face_window = Qnil;
19591 dpyinfo->mouse_face_overlay = Qnil;
19592 return cleared;
19593 }
19594
19595
19596 /* EXPORT:
19597 Non-zero if physical cursor of window W is within mouse face. */
19598
19599 int
19600 cursor_in_mouse_face_p (w)
19601 struct window *w;
19602 {
19603 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
19604 int in_mouse_face = 0;
19605
19606 if (WINDOWP (dpyinfo->mouse_face_window)
19607 && XWINDOW (dpyinfo->mouse_face_window) == w)
19608 {
19609 int hpos = w->phys_cursor.hpos;
19610 int vpos = w->phys_cursor.vpos;
19611
19612 if (vpos >= dpyinfo->mouse_face_beg_row
19613 && vpos <= dpyinfo->mouse_face_end_row
19614 && (vpos > dpyinfo->mouse_face_beg_row
19615 || hpos >= dpyinfo->mouse_face_beg_col)
19616 && (vpos < dpyinfo->mouse_face_end_row
19617 || hpos < dpyinfo->mouse_face_end_col
19618 || dpyinfo->mouse_face_past_end))
19619 in_mouse_face = 1;
19620 }
19621
19622 return in_mouse_face;
19623 }
19624
19625
19626
19627 \f
19628 /* Find the glyph matrix position of buffer position CHARPOS in window
19629 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
19630 current glyphs must be up to date. If CHARPOS is above window
19631 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
19632 of last line in W. In the row containing CHARPOS, stop before glyphs
19633 having STOP as object. */
19634
19635 #if 1 /* This is a version of fast_find_position that's more correct
19636 in the presence of hscrolling, for example. I didn't install
19637 it right away because the problem fixed is minor, it failed
19638 in 20.x as well, and I think it's too risky to install
19639 so near the release of 21.1. 2001-09-25 gerd. */
19640
19641 static int
19642 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
19643 struct window *w;
19644 int charpos;
19645 int *hpos, *vpos, *x, *y;
19646 Lisp_Object stop;
19647 {
19648 struct glyph_row *row, *first;
19649 struct glyph *glyph, *end;
19650 int past_end = 0;
19651
19652 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19653 row = row_containing_pos (w, charpos, first, NULL, 0);
19654 if (row == NULL)
19655 {
19656 if (charpos < MATRIX_ROW_START_CHARPOS (first))
19657 {
19658 *x = *y = *hpos = *vpos = 0;
19659 return 0;
19660 }
19661 else
19662 {
19663 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
19664 past_end = 1;
19665 }
19666 }
19667
19668 *x = row->x;
19669 *y = row->y;
19670 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19671
19672 glyph = row->glyphs[TEXT_AREA];
19673 end = glyph + row->used[TEXT_AREA];
19674
19675 /* Skip over glyphs not having an object at the start of the row.
19676 These are special glyphs like truncation marks on terminal
19677 frames. */
19678 if (row->displays_text_p)
19679 while (glyph < end
19680 && INTEGERP (glyph->object)
19681 && !EQ (stop, glyph->object)
19682 && glyph->charpos < 0)
19683 {
19684 *x += glyph->pixel_width;
19685 ++glyph;
19686 }
19687
19688 while (glyph < end
19689 && !INTEGERP (glyph->object)
19690 && !EQ (stop, glyph->object)
19691 && (!BUFFERP (glyph->object)
19692 || glyph->charpos < charpos))
19693 {
19694 *x += glyph->pixel_width;
19695 ++glyph;
19696 }
19697
19698 *hpos = glyph - row->glyphs[TEXT_AREA];
19699 return past_end;
19700 }
19701
19702 #else /* not 1 */
19703
19704 static int
19705 fast_find_position (w, pos, hpos, vpos, x, y, stop)
19706 struct window *w;
19707 int pos;
19708 int *hpos, *vpos, *x, *y;
19709 Lisp_Object stop;
19710 {
19711 int i;
19712 int lastcol;
19713 int maybe_next_line_p = 0;
19714 int line_start_position;
19715 int yb = window_text_bottom_y (w);
19716 struct glyph_row *row, *best_row;
19717 int row_vpos, best_row_vpos;
19718 int current_x;
19719
19720 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19721 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
19722
19723 while (row->y < yb)
19724 {
19725 if (row->used[TEXT_AREA])
19726 line_start_position = row->glyphs[TEXT_AREA]->charpos;
19727 else
19728 line_start_position = 0;
19729
19730 if (line_start_position > pos)
19731 break;
19732 /* If the position sought is the end of the buffer,
19733 don't include the blank lines at the bottom of the window. */
19734 else if (line_start_position == pos
19735 && pos == BUF_ZV (XBUFFER (w->buffer)))
19736 {
19737 maybe_next_line_p = 1;
19738 break;
19739 }
19740 else if (line_start_position > 0)
19741 {
19742 best_row = row;
19743 best_row_vpos = row_vpos;
19744 }
19745
19746 if (row->y + row->height >= yb)
19747 break;
19748
19749 ++row;
19750 ++row_vpos;
19751 }
19752
19753 /* Find the right column within BEST_ROW. */
19754 lastcol = 0;
19755 current_x = best_row->x;
19756 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
19757 {
19758 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
19759 int charpos = glyph->charpos;
19760
19761 if (BUFFERP (glyph->object))
19762 {
19763 if (charpos == pos)
19764 {
19765 *hpos = i;
19766 *vpos = best_row_vpos;
19767 *x = current_x;
19768 *y = best_row->y;
19769 return 1;
19770 }
19771 else if (charpos > pos)
19772 break;
19773 }
19774 else if (EQ (glyph->object, stop))
19775 break;
19776
19777 if (charpos > 0)
19778 lastcol = i;
19779 current_x += glyph->pixel_width;
19780 }
19781
19782 /* If we're looking for the end of the buffer,
19783 and we didn't find it in the line we scanned,
19784 use the start of the following line. */
19785 if (maybe_next_line_p)
19786 {
19787 ++best_row;
19788 ++best_row_vpos;
19789 lastcol = 0;
19790 current_x = best_row->x;
19791 }
19792
19793 *vpos = best_row_vpos;
19794 *hpos = lastcol + 1;
19795 *x = current_x;
19796 *y = best_row->y;
19797 return 0;
19798 }
19799
19800 #endif /* not 1 */
19801
19802
19803 /* Find the position of the glyph for position POS in OBJECT in
19804 window W's current matrix, and return in *X, *Y the pixel
19805 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
19806
19807 RIGHT_P non-zero means return the position of the right edge of the
19808 glyph, RIGHT_P zero means return the left edge position.
19809
19810 If no glyph for POS exists in the matrix, return the position of
19811 the glyph with the next smaller position that is in the matrix, if
19812 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
19813 exists in the matrix, return the position of the glyph with the
19814 next larger position in OBJECT.
19815
19816 Value is non-zero if a glyph was found. */
19817
19818 static int
19819 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
19820 struct window *w;
19821 int pos;
19822 Lisp_Object object;
19823 int *hpos, *vpos, *x, *y;
19824 int right_p;
19825 {
19826 int yb = window_text_bottom_y (w);
19827 struct glyph_row *r;
19828 struct glyph *best_glyph = NULL;
19829 struct glyph_row *best_row = NULL;
19830 int best_x = 0;
19831
19832 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
19833 r->enabled_p && r->y < yb;
19834 ++r)
19835 {
19836 struct glyph *g = r->glyphs[TEXT_AREA];
19837 struct glyph *e = g + r->used[TEXT_AREA];
19838 int gx;
19839
19840 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
19841 if (EQ (g->object, object))
19842 {
19843 if (g->charpos == pos)
19844 {
19845 best_glyph = g;
19846 best_x = gx;
19847 best_row = r;
19848 goto found;
19849 }
19850 else if (best_glyph == NULL
19851 || ((abs (g->charpos - pos)
19852 < abs (best_glyph->charpos - pos))
19853 && (right_p
19854 ? g->charpos < pos
19855 : g->charpos > pos)))
19856 {
19857 best_glyph = g;
19858 best_x = gx;
19859 best_row = r;
19860 }
19861 }
19862 }
19863
19864 found:
19865
19866 if (best_glyph)
19867 {
19868 *x = best_x;
19869 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
19870
19871 if (right_p)
19872 {
19873 *x += best_glyph->pixel_width;
19874 ++*hpos;
19875 }
19876
19877 *y = best_row->y;
19878 *vpos = best_row - w->current_matrix->rows;
19879 }
19880
19881 return best_glyph != NULL;
19882 }
19883
19884
19885 /* See if position X, Y is within a hot-spot of an image. */
19886
19887 static int
19888 on_hot_spot_p (hot_spot, x, y)
19889 Lisp_Object hot_spot;
19890 int x, y;
19891 {
19892 if (!CONSP (hot_spot))
19893 return 0;
19894
19895 if (EQ (XCAR (hot_spot), Qrect))
19896 {
19897 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
19898 Lisp_Object rect = XCDR (hot_spot);
19899 Lisp_Object tem;
19900 if (!CONSP (rect))
19901 return 0;
19902 if (!CONSP (XCAR (rect)))
19903 return 0;
19904 if (!CONSP (XCDR (rect)))
19905 return 0;
19906 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
19907 return 0;
19908 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
19909 return 0;
19910 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
19911 return 0;
19912 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
19913 return 0;
19914 return 1;
19915 }
19916 else if (EQ (XCAR (hot_spot), Qcircle))
19917 {
19918 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
19919 Lisp_Object circ = XCDR (hot_spot);
19920 Lisp_Object lr, lx0, ly0;
19921 if (CONSP (circ)
19922 && CONSP (XCAR (circ))
19923 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
19924 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
19925 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
19926 {
19927 double r = XFLOATINT (lr);
19928 double dx = XINT (lx0) - x;
19929 double dy = XINT (ly0) - y;
19930 return (dx * dx + dy * dy <= r * r);
19931 }
19932 }
19933 else if (EQ (XCAR (hot_spot), Qpoly))
19934 {
19935 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
19936 if (VECTORP (XCDR (hot_spot)))
19937 {
19938 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
19939 Lisp_Object *poly = v->contents;
19940 int n = v->size;
19941 int i;
19942 int inside = 0;
19943 Lisp_Object lx, ly;
19944 int x0, y0;
19945
19946 /* Need an even number of coordinates, and at least 3 edges. */
19947 if (n < 6 || n & 1)
19948 return 0;
19949
19950 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
19951 If count is odd, we are inside polygon. Pixels on edges
19952 may or may not be included depending on actual geometry of the
19953 polygon. */
19954 if ((lx = poly[n-2], !INTEGERP (lx))
19955 || (ly = poly[n-1], !INTEGERP (lx)))
19956 return 0;
19957 x0 = XINT (lx), y0 = XINT (ly);
19958 for (i = 0; i < n; i += 2)
19959 {
19960 int x1 = x0, y1 = y0;
19961 if ((lx = poly[i], !INTEGERP (lx))
19962 || (ly = poly[i+1], !INTEGERP (ly)))
19963 return 0;
19964 x0 = XINT (lx), y0 = XINT (ly);
19965
19966 /* Does this segment cross the X line? */
19967 if (x0 >= x)
19968 {
19969 if (x1 >= x)
19970 continue;
19971 }
19972 else if (x1 < x)
19973 continue;
19974 if (y > y0 && y > y1)
19975 continue;
19976 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
19977 inside = !inside;
19978 }
19979 return inside;
19980 }
19981 }
19982 else
19983 return 0;
19984 }
19985
19986 Lisp_Object
19987 find_hot_spot (map, x, y)
19988 Lisp_Object map;
19989 int x, y;
19990 {
19991 while (CONSP (map))
19992 {
19993 if (CONSP (XCAR (map))
19994 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
19995 return XCAR (map);
19996 map = XCDR (map);
19997 }
19998
19999 return Qnil;
20000 }
20001
20002 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
20003 3, 3, 0,
20004 doc: /* Lookup in image map MAP coordinates X and Y.
20005 An image map is an alist where each element has the format (AREA ID PLIST).
20006 An AREA is specified as either a rectangle, a circle, or a polygon:
20007 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
20008 pixel coordinates of the upper left and bottom right corners.
20009 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
20010 and the radius of the circle; r may be a float or integer.
20011 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
20012 vector describes one corner in the polygon.
20013 Returns the alist element for the first matching AREA in MAP. */)
20014 (map, x, y)
20015 Lisp_Object map;
20016 Lisp_Object x, y;
20017 {
20018 int ix, iy;
20019 if (NILP (map))
20020 return Qnil;
20021
20022 CHECK_NUMBER (x);
20023 CHECK_NUMBER (y);
20024
20025 return find_hot_spot (map, XINT (x), XINT (y));
20026 }
20027
20028
20029 /* Display frame CURSOR, optionally using shape defined by POINTER. */
20030 static void
20031 define_frame_cursor1 (f, cursor, pointer)
20032 struct frame *f;
20033 Cursor cursor;
20034 Lisp_Object pointer;
20035 {
20036 if (!NILP (pointer))
20037 {
20038 if (EQ (pointer, Qarrow))
20039 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20040 else if (EQ (pointer, Qhand))
20041 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
20042 else if (EQ (pointer, Qtext))
20043 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20044 else if (EQ (pointer, intern ("hdrag")))
20045 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20046 #ifdef HAVE_X_WINDOWS
20047 else if (EQ (pointer, intern ("vdrag")))
20048 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
20049 #endif
20050 else if (EQ (pointer, intern ("hourglass")))
20051 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
20052 else if (EQ (pointer, Qmodeline))
20053 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
20054 else
20055 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20056 }
20057
20058 #ifndef HAVE_CARBON
20059 if (cursor != No_Cursor)
20060 #else
20061 if (bcmp (&cursor, &No_Cursor, sizeof (Cursor)))
20062 #endif
20063 rif->define_frame_cursor (f, cursor);
20064 }
20065
20066 /* Take proper action when mouse has moved to the mode or header line
20067 or marginal area AREA of window W, x-position X and y-position Y.
20068 X is relative to the start of the text display area of W, so the
20069 width of bitmap areas and scroll bars must be subtracted to get a
20070 position relative to the start of the mode line. */
20071
20072 static void
20073 note_mode_line_or_margin_highlight (w, x, y, area)
20074 struct window *w;
20075 int x, y;
20076 enum window_part area;
20077 {
20078 struct frame *f = XFRAME (w->frame);
20079 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20080 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20081 Lisp_Object pointer = Qnil;
20082 int charpos, dx, dy, width, height;
20083 Lisp_Object string, object = Qnil;
20084 Lisp_Object pos, help, image;
20085
20086 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
20087 string = mode_line_string (w, area, &x, &y, &charpos,
20088 &object, &dx, &dy, &width, &height);
20089 else
20090 {
20091 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
20092 string = marginal_area_string (w, area, &x, &y, &charpos,
20093 &object, &dx, &dy, &width, &height);
20094 }
20095
20096 help = Qnil;
20097
20098 if (IMAGEP (object))
20099 {
20100 Lisp_Object image_map, hotspot;
20101 if ((image_map = Fplist_get (XCDR (object), QCmap),
20102 !NILP (image_map))
20103 && (hotspot = find_hot_spot (image_map, dx, dy),
20104 CONSP (hotspot))
20105 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20106 {
20107 Lisp_Object area_id, plist;
20108
20109 area_id = XCAR (hotspot);
20110 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20111 If so, we could look for mouse-enter, mouse-leave
20112 properties in PLIST (and do something...). */
20113 if ((plist = XCDR (hotspot), CONSP (plist)))
20114 {
20115 pointer = Fplist_get (plist, Qpointer);
20116 if (NILP (pointer))
20117 pointer = Qhand;
20118 help = Fplist_get (plist, Qhelp_echo);
20119 if (!NILP (help))
20120 {
20121 help_echo_string = help;
20122 /* Is this correct? ++kfs */
20123 XSETWINDOW (help_echo_window, w);
20124 help_echo_object = w->buffer;
20125 help_echo_pos = charpos;
20126 }
20127 }
20128 if (NILP (pointer))
20129 pointer = Fplist_get (XCDR (object), QCpointer);
20130 }
20131 }
20132
20133 if (STRINGP (string))
20134 {
20135 pos = make_number (charpos);
20136 /* If we're on a string with `help-echo' text property, arrange
20137 for the help to be displayed. This is done by setting the
20138 global variable help_echo_string to the help string. */
20139 help = Fget_text_property (pos, Qhelp_echo, string);
20140 if (!NILP (help))
20141 {
20142 help_echo_string = help;
20143 XSETWINDOW (help_echo_window, w);
20144 help_echo_object = string;
20145 help_echo_pos = charpos;
20146 }
20147
20148 if (NILP (pointer))
20149 pointer = Fget_text_property (pos, Qpointer, string);
20150
20151 /* Change the mouse pointer according to what is under X/Y. */
20152 if (NILP (pointer) && area == ON_MODE_LINE)
20153 {
20154 Lisp_Object map;
20155 map = Fget_text_property (pos, Qlocal_map, string);
20156 if (!KEYMAPP (map))
20157 map = Fget_text_property (pos, Qkeymap, string);
20158 if (!KEYMAPP (map))
20159 cursor = dpyinfo->vertical_scroll_bar_cursor;
20160 }
20161 }
20162
20163 define_frame_cursor1 (f, cursor, pointer);
20164 }
20165
20166
20167 /* EXPORT:
20168 Take proper action when the mouse has moved to position X, Y on
20169 frame F as regards highlighting characters that have mouse-face
20170 properties. Also de-highlighting chars where the mouse was before.
20171 X and Y can be negative or out of range. */
20172
20173 void
20174 note_mouse_highlight (f, x, y)
20175 struct frame *f;
20176 int x, y;
20177 {
20178 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20179 enum window_part part;
20180 Lisp_Object window;
20181 struct window *w;
20182 Cursor cursor = No_Cursor;
20183 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
20184 struct buffer *b;
20185
20186 /* When a menu is active, don't highlight because this looks odd. */
20187 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
20188 if (popup_activated ())
20189 return;
20190 #endif
20191
20192 if (NILP (Vmouse_highlight)
20193 || !f->glyphs_initialized_p)
20194 return;
20195
20196 dpyinfo->mouse_face_mouse_x = x;
20197 dpyinfo->mouse_face_mouse_y = y;
20198 dpyinfo->mouse_face_mouse_frame = f;
20199
20200 if (dpyinfo->mouse_face_defer)
20201 return;
20202
20203 if (gc_in_progress)
20204 {
20205 dpyinfo->mouse_face_deferred_gc = 1;
20206 return;
20207 }
20208
20209 /* Which window is that in? */
20210 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
20211
20212 /* If we were displaying active text in another window, clear that. */
20213 if (! EQ (window, dpyinfo->mouse_face_window))
20214 clear_mouse_face (dpyinfo);
20215
20216 /* Not on a window -> return. */
20217 if (!WINDOWP (window))
20218 return;
20219
20220 /* Reset help_echo_string. It will get recomputed below. */
20221 help_echo_string = Qnil;
20222
20223 /* Convert to window-relative pixel coordinates. */
20224 w = XWINDOW (window);
20225 frame_to_window_pixel_xy (w, &x, &y);
20226
20227 /* Handle tool-bar window differently since it doesn't display a
20228 buffer. */
20229 if (EQ (window, f->tool_bar_window))
20230 {
20231 note_tool_bar_highlight (f, x, y);
20232 return;
20233 }
20234
20235 /* Mouse is on the mode, header line or margin? */
20236 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
20237 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
20238 {
20239 note_mode_line_or_margin_highlight (w, x, y, part);
20240 return;
20241 }
20242
20243 if (part == ON_VERTICAL_BORDER)
20244 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
20245 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE)
20246 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20247 else
20248 cursor = FRAME_X_OUTPUT (f)->text_cursor;
20249
20250 /* Are we in a window whose display is up to date?
20251 And verify the buffer's text has not changed. */
20252 b = XBUFFER (w->buffer);
20253 if (part == ON_TEXT
20254 && EQ (w->window_end_valid, w->buffer)
20255 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
20256 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
20257 {
20258 int hpos, vpos, pos, i, dx, dy, area;
20259 struct glyph *glyph;
20260 Lisp_Object object;
20261 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
20262 Lisp_Object *overlay_vec = NULL;
20263 int len, noverlays;
20264 struct buffer *obuf;
20265 int obegv, ozv, same_region;
20266
20267 /* Find the glyph under X/Y. */
20268 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
20269
20270 /* Look for :pointer property on image. */
20271 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
20272 {
20273 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
20274 if (img != NULL && IMAGEP (img->spec))
20275 {
20276 Lisp_Object image_map, hotspot;
20277 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
20278 !NILP (image_map))
20279 && (hotspot = find_hot_spot (image_map, dx, dy),
20280 CONSP (hotspot))
20281 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
20282 {
20283 Lisp_Object area_id, plist;
20284
20285 area_id = XCAR (hotspot);
20286 /* Could check AREA_ID to see if we enter/leave this hot-spot.
20287 If so, we could look for mouse-enter, mouse-leave
20288 properties in PLIST (and do something...). */
20289 if ((plist = XCDR (hotspot), CONSP (plist)))
20290 {
20291 pointer = Fplist_get (plist, Qpointer);
20292 if (NILP (pointer))
20293 pointer = Qhand;
20294 help_echo_string = Fplist_get (plist, Qhelp_echo);
20295 if (!NILP (help_echo_string))
20296 {
20297 help_echo_window = window;
20298 help_echo_object = glyph->object;
20299 help_echo_pos = glyph->charpos;
20300 }
20301 }
20302 }
20303 if (NILP (pointer))
20304 pointer = Fplist_get (XCDR (img->spec), QCpointer);
20305 }
20306 }
20307
20308 /* Clear mouse face if X/Y not over text. */
20309 if (glyph == NULL
20310 || area != TEXT_AREA
20311 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
20312 {
20313 if (clear_mouse_face (dpyinfo))
20314 cursor = No_Cursor;
20315 if (NILP (pointer))
20316 {
20317 if (area != TEXT_AREA)
20318 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
20319 else
20320 pointer = Vvoid_text_area_pointer;
20321 }
20322 goto set_cursor;
20323 }
20324
20325 pos = glyph->charpos;
20326 object = glyph->object;
20327 if (!STRINGP (object) && !BUFFERP (object))
20328 goto set_cursor;
20329
20330 /* If we get an out-of-range value, return now; avoid an error. */
20331 if (BUFFERP (object) && pos > BUF_Z (b))
20332 goto set_cursor;
20333
20334 /* Make the window's buffer temporarily current for
20335 overlays_at and compute_char_face. */
20336 obuf = current_buffer;
20337 current_buffer = b;
20338 obegv = BEGV;
20339 ozv = ZV;
20340 BEGV = BEG;
20341 ZV = Z;
20342
20343 /* Is this char mouse-active or does it have help-echo? */
20344 position = make_number (pos);
20345
20346 if (BUFFERP (object))
20347 {
20348 /* Put all the overlays we want in a vector in overlay_vec.
20349 Store the length in len. If there are more than 10, make
20350 enough space for all, and try again. */
20351 len = 10;
20352 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20353 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL, 0);
20354 if (noverlays > len)
20355 {
20356 len = noverlays;
20357 overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
20358 noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL,0);
20359 }
20360
20361 /* Sort overlays into increasing priority order. */
20362 noverlays = sort_overlays (overlay_vec, noverlays, w);
20363 }
20364 else
20365 noverlays = 0;
20366
20367 same_region = (EQ (window, dpyinfo->mouse_face_window)
20368 && vpos >= dpyinfo->mouse_face_beg_row
20369 && vpos <= dpyinfo->mouse_face_end_row
20370 && (vpos > dpyinfo->mouse_face_beg_row
20371 || hpos >= dpyinfo->mouse_face_beg_col)
20372 && (vpos < dpyinfo->mouse_face_end_row
20373 || hpos < dpyinfo->mouse_face_end_col
20374 || dpyinfo->mouse_face_past_end));
20375
20376 if (same_region)
20377 cursor = No_Cursor;
20378
20379 /* Check mouse-face highlighting. */
20380 if (! same_region
20381 /* If there exists an overlay with mouse-face overlapping
20382 the one we are currently highlighting, we have to
20383 check if we enter the overlapping overlay, and then
20384 highlight only that. */
20385 || (OVERLAYP (dpyinfo->mouse_face_overlay)
20386 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
20387 {
20388 /* Find the highest priority overlay that has a mouse-face
20389 property. */
20390 overlay = Qnil;
20391 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
20392 {
20393 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
20394 if (!NILP (mouse_face))
20395 overlay = overlay_vec[i];
20396 }
20397
20398 /* If we're actually highlighting the same overlay as
20399 before, there's no need to do that again. */
20400 if (!NILP (overlay)
20401 && EQ (overlay, dpyinfo->mouse_face_overlay))
20402 goto check_help_echo;
20403
20404 dpyinfo->mouse_face_overlay = overlay;
20405
20406 /* Clear the display of the old active region, if any. */
20407 if (clear_mouse_face (dpyinfo))
20408 cursor = No_Cursor;
20409
20410 /* If no overlay applies, get a text property. */
20411 if (NILP (overlay))
20412 mouse_face = Fget_text_property (position, Qmouse_face, object);
20413
20414 /* Handle the overlay case. */
20415 if (!NILP (overlay))
20416 {
20417 /* Find the range of text around this char that
20418 should be active. */
20419 Lisp_Object before, after;
20420 int ignore;
20421
20422 before = Foverlay_start (overlay);
20423 after = Foverlay_end (overlay);
20424 /* Record this as the current active region. */
20425 fast_find_position (w, XFASTINT (before),
20426 &dpyinfo->mouse_face_beg_col,
20427 &dpyinfo->mouse_face_beg_row,
20428 &dpyinfo->mouse_face_beg_x,
20429 &dpyinfo->mouse_face_beg_y, Qnil);
20430
20431 dpyinfo->mouse_face_past_end
20432 = !fast_find_position (w, XFASTINT (after),
20433 &dpyinfo->mouse_face_end_col,
20434 &dpyinfo->mouse_face_end_row,
20435 &dpyinfo->mouse_face_end_x,
20436 &dpyinfo->mouse_face_end_y, Qnil);
20437 dpyinfo->mouse_face_window = window;
20438
20439 dpyinfo->mouse_face_face_id
20440 = face_at_buffer_position (w, pos, 0, 0,
20441 &ignore, pos + 1,
20442 !dpyinfo->mouse_face_hidden);
20443
20444 /* Display it as active. */
20445 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20446 cursor = No_Cursor;
20447 }
20448 /* Handle the text property case. */
20449 else if (!NILP (mouse_face) && BUFFERP (object))
20450 {
20451 /* Find the range of text around this char that
20452 should be active. */
20453 Lisp_Object before, after, beginning, end;
20454 int ignore;
20455
20456 beginning = Fmarker_position (w->start);
20457 end = make_number (BUF_Z (XBUFFER (object))
20458 - XFASTINT (w->window_end_pos));
20459 before
20460 = Fprevious_single_property_change (make_number (pos + 1),
20461 Qmouse_face,
20462 object, beginning);
20463 after
20464 = Fnext_single_property_change (position, Qmouse_face,
20465 object, end);
20466
20467 /* Record this as the current active region. */
20468 fast_find_position (w, XFASTINT (before),
20469 &dpyinfo->mouse_face_beg_col,
20470 &dpyinfo->mouse_face_beg_row,
20471 &dpyinfo->mouse_face_beg_x,
20472 &dpyinfo->mouse_face_beg_y, Qnil);
20473 dpyinfo->mouse_face_past_end
20474 = !fast_find_position (w, XFASTINT (after),
20475 &dpyinfo->mouse_face_end_col,
20476 &dpyinfo->mouse_face_end_row,
20477 &dpyinfo->mouse_face_end_x,
20478 &dpyinfo->mouse_face_end_y, Qnil);
20479 dpyinfo->mouse_face_window = window;
20480
20481 if (BUFFERP (object))
20482 dpyinfo->mouse_face_face_id
20483 = face_at_buffer_position (w, pos, 0, 0,
20484 &ignore, pos + 1,
20485 !dpyinfo->mouse_face_hidden);
20486
20487 /* Display it as active. */
20488 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20489 cursor = No_Cursor;
20490 }
20491 else if (!NILP (mouse_face) && STRINGP (object))
20492 {
20493 Lisp_Object b, e;
20494 int ignore;
20495
20496 b = Fprevious_single_property_change (make_number (pos + 1),
20497 Qmouse_face,
20498 object, Qnil);
20499 e = Fnext_single_property_change (position, Qmouse_face,
20500 object, Qnil);
20501 if (NILP (b))
20502 b = make_number (0);
20503 if (NILP (e))
20504 e = make_number (SCHARS (object) - 1);
20505 fast_find_string_pos (w, XINT (b), object,
20506 &dpyinfo->mouse_face_beg_col,
20507 &dpyinfo->mouse_face_beg_row,
20508 &dpyinfo->mouse_face_beg_x,
20509 &dpyinfo->mouse_face_beg_y, 0);
20510 fast_find_string_pos (w, XINT (e), object,
20511 &dpyinfo->mouse_face_end_col,
20512 &dpyinfo->mouse_face_end_row,
20513 &dpyinfo->mouse_face_end_x,
20514 &dpyinfo->mouse_face_end_y, 1);
20515 dpyinfo->mouse_face_past_end = 0;
20516 dpyinfo->mouse_face_window = window;
20517 dpyinfo->mouse_face_face_id
20518 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
20519 glyph->face_id, 1);
20520 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20521 cursor = No_Cursor;
20522 }
20523 else if (STRINGP (object) && NILP (mouse_face))
20524 {
20525 /* A string which doesn't have mouse-face, but
20526 the text ``under'' it might have. */
20527 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
20528 int start = MATRIX_ROW_START_CHARPOS (r);
20529
20530 pos = string_buffer_position (w, object, start);
20531 if (pos > 0)
20532 mouse_face = get_char_property_and_overlay (make_number (pos),
20533 Qmouse_face,
20534 w->buffer,
20535 &overlay);
20536 if (!NILP (mouse_face) && !NILP (overlay))
20537 {
20538 Lisp_Object before = Foverlay_start (overlay);
20539 Lisp_Object after = Foverlay_end (overlay);
20540 int ignore;
20541
20542 /* Note that we might not be able to find position
20543 BEFORE in the glyph matrix if the overlay is
20544 entirely covered by a `display' property. In
20545 this case, we overshoot. So let's stop in
20546 the glyph matrix before glyphs for OBJECT. */
20547 fast_find_position (w, XFASTINT (before),
20548 &dpyinfo->mouse_face_beg_col,
20549 &dpyinfo->mouse_face_beg_row,
20550 &dpyinfo->mouse_face_beg_x,
20551 &dpyinfo->mouse_face_beg_y,
20552 object);
20553
20554 dpyinfo->mouse_face_past_end
20555 = !fast_find_position (w, XFASTINT (after),
20556 &dpyinfo->mouse_face_end_col,
20557 &dpyinfo->mouse_face_end_row,
20558 &dpyinfo->mouse_face_end_x,
20559 &dpyinfo->mouse_face_end_y,
20560 Qnil);
20561 dpyinfo->mouse_face_window = window;
20562 dpyinfo->mouse_face_face_id
20563 = face_at_buffer_position (w, pos, 0, 0,
20564 &ignore, pos + 1,
20565 !dpyinfo->mouse_face_hidden);
20566
20567 /* Display it as active. */
20568 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
20569 cursor = No_Cursor;
20570 }
20571 }
20572 }
20573
20574 check_help_echo:
20575
20576 /* Look for a `help-echo' property. */
20577 if (NILP (help_echo_string)) {
20578 Lisp_Object help, overlay;
20579
20580 /* Check overlays first. */
20581 help = overlay = Qnil;
20582 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
20583 {
20584 overlay = overlay_vec[i];
20585 help = Foverlay_get (overlay, Qhelp_echo);
20586 }
20587
20588 if (!NILP (help))
20589 {
20590 help_echo_string = help;
20591 help_echo_window = window;
20592 help_echo_object = overlay;
20593 help_echo_pos = pos;
20594 }
20595 else
20596 {
20597 Lisp_Object object = glyph->object;
20598 int charpos = glyph->charpos;
20599
20600 /* Try text properties. */
20601 if (STRINGP (object)
20602 && charpos >= 0
20603 && charpos < SCHARS (object))
20604 {
20605 help = Fget_text_property (make_number (charpos),
20606 Qhelp_echo, object);
20607 if (NILP (help))
20608 {
20609 /* If the string itself doesn't specify a help-echo,
20610 see if the buffer text ``under'' it does. */
20611 struct glyph_row *r
20612 = MATRIX_ROW (w->current_matrix, vpos);
20613 int start = MATRIX_ROW_START_CHARPOS (r);
20614 int pos = string_buffer_position (w, object, start);
20615 if (pos > 0)
20616 {
20617 help = Fget_char_property (make_number (pos),
20618 Qhelp_echo, w->buffer);
20619 if (!NILP (help))
20620 {
20621 charpos = pos;
20622 object = w->buffer;
20623 }
20624 }
20625 }
20626 }
20627 else if (BUFFERP (object)
20628 && charpos >= BEGV
20629 && charpos < ZV)
20630 help = Fget_text_property (make_number (charpos), Qhelp_echo,
20631 object);
20632
20633 if (!NILP (help))
20634 {
20635 help_echo_string = help;
20636 help_echo_window = window;
20637 help_echo_object = object;
20638 help_echo_pos = charpos;
20639 }
20640 }
20641 }
20642
20643 /* Look for a `pointer' property. */
20644 if (NILP (pointer))
20645 {
20646 /* Check overlays first. */
20647 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
20648 pointer = Foverlay_get (overlay_vec[i], Qpointer);
20649
20650 if (NILP (pointer))
20651 {
20652 Lisp_Object object = glyph->object;
20653 int charpos = glyph->charpos;
20654
20655 /* Try text properties. */
20656 if (STRINGP (object)
20657 && charpos >= 0
20658 && charpos < SCHARS (object))
20659 {
20660 pointer = Fget_text_property (make_number (charpos),
20661 Qpointer, object);
20662 if (NILP (pointer))
20663 {
20664 /* If the string itself doesn't specify a pointer,
20665 see if the buffer text ``under'' it does. */
20666 struct glyph_row *r
20667 = MATRIX_ROW (w->current_matrix, vpos);
20668 int start = MATRIX_ROW_START_CHARPOS (r);
20669 int pos = string_buffer_position (w, object, start);
20670 if (pos > 0)
20671 pointer = Fget_char_property (make_number (pos),
20672 Qpointer, w->buffer);
20673 }
20674 }
20675 else if (BUFFERP (object)
20676 && charpos >= BEGV
20677 && charpos < ZV)
20678 pointer = Fget_text_property (make_number (charpos),
20679 Qpointer, object);
20680 }
20681 }
20682
20683 BEGV = obegv;
20684 ZV = ozv;
20685 current_buffer = obuf;
20686 }
20687
20688 set_cursor:
20689
20690 define_frame_cursor1 (f, cursor, pointer);
20691 }
20692
20693
20694 /* EXPORT for RIF:
20695 Clear any mouse-face on window W. This function is part of the
20696 redisplay interface, and is called from try_window_id and similar
20697 functions to ensure the mouse-highlight is off. */
20698
20699 void
20700 x_clear_window_mouse_face (w)
20701 struct window *w;
20702 {
20703 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20704 Lisp_Object window;
20705
20706 BLOCK_INPUT;
20707 XSETWINDOW (window, w);
20708 if (EQ (window, dpyinfo->mouse_face_window))
20709 clear_mouse_face (dpyinfo);
20710 UNBLOCK_INPUT;
20711 }
20712
20713
20714 /* EXPORT:
20715 Just discard the mouse face information for frame F, if any.
20716 This is used when the size of F is changed. */
20717
20718 void
20719 cancel_mouse_face (f)
20720 struct frame *f;
20721 {
20722 Lisp_Object window;
20723 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20724
20725 window = dpyinfo->mouse_face_window;
20726 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
20727 {
20728 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20729 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20730 dpyinfo->mouse_face_window = Qnil;
20731 }
20732 }
20733
20734
20735 #endif /* HAVE_WINDOW_SYSTEM */
20736
20737 \f
20738 /***********************************************************************
20739 Exposure Events
20740 ***********************************************************************/
20741
20742 #ifdef HAVE_WINDOW_SYSTEM
20743
20744 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
20745 which intersects rectangle R. R is in window-relative coordinates. */
20746
20747 static void
20748 expose_area (w, row, r, area)
20749 struct window *w;
20750 struct glyph_row *row;
20751 XRectangle *r;
20752 enum glyph_row_area area;
20753 {
20754 struct glyph *first = row->glyphs[area];
20755 struct glyph *end = row->glyphs[area] + row->used[area];
20756 struct glyph *last;
20757 int first_x, start_x, x;
20758
20759 if (area == TEXT_AREA && row->fill_line_p)
20760 /* If row extends face to end of line write the whole line. */
20761 draw_glyphs (w, 0, row, area,
20762 0, row->used[area],
20763 DRAW_NORMAL_TEXT, 0);
20764 else
20765 {
20766 /* Set START_X to the window-relative start position for drawing glyphs of
20767 AREA. The first glyph of the text area can be partially visible.
20768 The first glyphs of other areas cannot. */
20769 start_x = window_box_left_offset (w, area);
20770 x = start_x;
20771 if (area == TEXT_AREA)
20772 x += row->x;
20773
20774 /* Find the first glyph that must be redrawn. */
20775 while (first < end
20776 && x + first->pixel_width < r->x)
20777 {
20778 x += first->pixel_width;
20779 ++first;
20780 }
20781
20782 /* Find the last one. */
20783 last = first;
20784 first_x = x;
20785 while (last < end
20786 && x < r->x + r->width)
20787 {
20788 x += last->pixel_width;
20789 ++last;
20790 }
20791
20792 /* Repaint. */
20793 if (last > first)
20794 draw_glyphs (w, first_x - start_x, row, area,
20795 first - row->glyphs[area], last - row->glyphs[area],
20796 DRAW_NORMAL_TEXT, 0);
20797 }
20798 }
20799
20800
20801 /* Redraw the parts of the glyph row ROW on window W intersecting
20802 rectangle R. R is in window-relative coordinates. Value is
20803 non-zero if mouse-face was overwritten. */
20804
20805 static int
20806 expose_line (w, row, r)
20807 struct window *w;
20808 struct glyph_row *row;
20809 XRectangle *r;
20810 {
20811 xassert (row->enabled_p);
20812
20813 if (row->mode_line_p || w->pseudo_window_p)
20814 draw_glyphs (w, 0, row, TEXT_AREA,
20815 0, row->used[TEXT_AREA],
20816 DRAW_NORMAL_TEXT, 0);
20817 else
20818 {
20819 if (row->used[LEFT_MARGIN_AREA])
20820 expose_area (w, row, r, LEFT_MARGIN_AREA);
20821 if (row->used[TEXT_AREA])
20822 expose_area (w, row, r, TEXT_AREA);
20823 if (row->used[RIGHT_MARGIN_AREA])
20824 expose_area (w, row, r, RIGHT_MARGIN_AREA);
20825 draw_row_fringe_bitmaps (w, row);
20826 }
20827
20828 return row->mouse_face_p;
20829 }
20830
20831
20832 /* Redraw those parts of glyphs rows during expose event handling that
20833 overlap other rows. Redrawing of an exposed line writes over parts
20834 of lines overlapping that exposed line; this function fixes that.
20835
20836 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
20837 row in W's current matrix that is exposed and overlaps other rows.
20838 LAST_OVERLAPPING_ROW is the last such row. */
20839
20840 static void
20841 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
20842 struct window *w;
20843 struct glyph_row *first_overlapping_row;
20844 struct glyph_row *last_overlapping_row;
20845 {
20846 struct glyph_row *row;
20847
20848 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
20849 if (row->overlapping_p)
20850 {
20851 xassert (row->enabled_p && !row->mode_line_p);
20852
20853 if (row->used[LEFT_MARGIN_AREA])
20854 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
20855
20856 if (row->used[TEXT_AREA])
20857 x_fix_overlapping_area (w, row, TEXT_AREA);
20858
20859 if (row->used[RIGHT_MARGIN_AREA])
20860 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
20861 }
20862 }
20863
20864
20865 /* Return non-zero if W's cursor intersects rectangle R. */
20866
20867 static int
20868 phys_cursor_in_rect_p (w, r)
20869 struct window *w;
20870 XRectangle *r;
20871 {
20872 XRectangle cr, result;
20873 struct glyph *cursor_glyph;
20874
20875 cursor_glyph = get_phys_cursor_glyph (w);
20876 if (cursor_glyph)
20877 {
20878 /* r is relative to W's box, but w->phys_cursor.x is relative
20879 to left edge of W's TEXT area. Adjust it. */
20880 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
20881 cr.y = w->phys_cursor.y;
20882 cr.width = cursor_glyph->pixel_width;
20883 cr.height = w->phys_cursor_height;
20884 /* ++KFS: W32 version used W32-specific IntersectRect here, but
20885 I assume the effect is the same -- and this is portable. */
20886 return x_intersect_rectangles (&cr, r, &result);
20887 }
20888 else
20889 return 0;
20890 }
20891
20892
20893 /* EXPORT:
20894 Draw a vertical window border to the right of window W if W doesn't
20895 have vertical scroll bars. */
20896
20897 void
20898 x_draw_vertical_border (w)
20899 struct window *w;
20900 {
20901 /* We could do better, if we knew what type of scroll-bar the adjacent
20902 windows (on either side) have... But we don't :-(
20903 However, I think this works ok. ++KFS 2003-04-25 */
20904
20905 /* Redraw borders between horizontally adjacent windows. Don't
20906 do it for frames with vertical scroll bars because either the
20907 right scroll bar of a window, or the left scroll bar of its
20908 neighbor will suffice as a border. */
20909 if (!WINDOW_RIGHTMOST_P (w)
20910 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
20911 {
20912 int x0, x1, y0, y1;
20913
20914 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20915 y1 -= 1;
20916
20917 rif->draw_vertical_window_border (w, x1, y0, y1);
20918 }
20919 else if (!WINDOW_LEFTMOST_P (w)
20920 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
20921 {
20922 int x0, x1, y0, y1;
20923
20924 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
20925 y1 -= 1;
20926
20927 rif->draw_vertical_window_border (w, x0, y0, y1);
20928 }
20929 }
20930
20931
20932 /* Redraw the part of window W intersection rectangle FR. Pixel
20933 coordinates in FR are frame-relative. Call this function with
20934 input blocked. Value is non-zero if the exposure overwrites
20935 mouse-face. */
20936
20937 static int
20938 expose_window (w, fr)
20939 struct window *w;
20940 XRectangle *fr;
20941 {
20942 struct frame *f = XFRAME (w->frame);
20943 XRectangle wr, r;
20944 int mouse_face_overwritten_p = 0;
20945
20946 /* If window is not yet fully initialized, do nothing. This can
20947 happen when toolkit scroll bars are used and a window is split.
20948 Reconfiguring the scroll bar will generate an expose for a newly
20949 created window. */
20950 if (w->current_matrix == NULL)
20951 return 0;
20952
20953 /* When we're currently updating the window, display and current
20954 matrix usually don't agree. Arrange for a thorough display
20955 later. */
20956 if (w == updated_window)
20957 {
20958 SET_FRAME_GARBAGED (f);
20959 return 0;
20960 }
20961
20962 /* Frame-relative pixel rectangle of W. */
20963 wr.x = WINDOW_LEFT_EDGE_X (w);
20964 wr.y = WINDOW_TOP_EDGE_Y (w);
20965 wr.width = WINDOW_TOTAL_WIDTH (w);
20966 wr.height = WINDOW_TOTAL_HEIGHT (w);
20967
20968 if (x_intersect_rectangles (fr, &wr, &r))
20969 {
20970 int yb = window_text_bottom_y (w);
20971 struct glyph_row *row;
20972 int cursor_cleared_p;
20973 struct glyph_row *first_overlapping_row, *last_overlapping_row;
20974
20975 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
20976 r.x, r.y, r.width, r.height));
20977
20978 /* Convert to window coordinates. */
20979 r.x -= WINDOW_LEFT_EDGE_X (w);
20980 r.y -= WINDOW_TOP_EDGE_Y (w);
20981
20982 /* Turn off the cursor. */
20983 if (!w->pseudo_window_p
20984 && phys_cursor_in_rect_p (w, &r))
20985 {
20986 x_clear_cursor (w);
20987 cursor_cleared_p = 1;
20988 }
20989 else
20990 cursor_cleared_p = 0;
20991
20992 /* Update lines intersecting rectangle R. */
20993 first_overlapping_row = last_overlapping_row = NULL;
20994 for (row = w->current_matrix->rows;
20995 row->enabled_p;
20996 ++row)
20997 {
20998 int y0 = row->y;
20999 int y1 = MATRIX_ROW_BOTTOM_Y (row);
21000
21001 if ((y0 >= r.y && y0 < r.y + r.height)
21002 || (y1 > r.y && y1 < r.y + r.height)
21003 || (r.y >= y0 && r.y < y1)
21004 || (r.y + r.height > y0 && r.y + r.height < y1))
21005 {
21006 if (row->overlapping_p)
21007 {
21008 if (first_overlapping_row == NULL)
21009 first_overlapping_row = row;
21010 last_overlapping_row = row;
21011 }
21012
21013 if (expose_line (w, row, &r))
21014 mouse_face_overwritten_p = 1;
21015 }
21016
21017 if (y1 >= yb)
21018 break;
21019 }
21020
21021 /* Display the mode line if there is one. */
21022 if (WINDOW_WANTS_MODELINE_P (w)
21023 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
21024 row->enabled_p)
21025 && row->y < r.y + r.height)
21026 {
21027 if (expose_line (w, row, &r))
21028 mouse_face_overwritten_p = 1;
21029 }
21030
21031 if (!w->pseudo_window_p)
21032 {
21033 /* Fix the display of overlapping rows. */
21034 if (first_overlapping_row)
21035 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
21036
21037 /* Draw border between windows. */
21038 x_draw_vertical_border (w);
21039
21040 /* Turn the cursor on again. */
21041 if (cursor_cleared_p)
21042 update_window_cursor (w, 1);
21043 }
21044 }
21045
21046 #ifdef HAVE_CARBON
21047 /* Display scroll bar for this window. */
21048 if (!NILP (w->vertical_scroll_bar))
21049 {
21050 /* ++KFS:
21051 If this doesn't work here (maybe some header files are missing),
21052 make a function in macterm.c and call it to do the job! */
21053 ControlHandle ch
21054 = SCROLL_BAR_CONTROL_HANDLE (XSCROLL_BAR (w->vertical_scroll_bar));
21055
21056 Draw1Control (ch);
21057 }
21058 #endif
21059
21060 return mouse_face_overwritten_p;
21061 }
21062
21063
21064
21065 /* Redraw (parts) of all windows in the window tree rooted at W that
21066 intersect R. R contains frame pixel coordinates. Value is
21067 non-zero if the exposure overwrites mouse-face. */
21068
21069 static int
21070 expose_window_tree (w, r)
21071 struct window *w;
21072 XRectangle *r;
21073 {
21074 struct frame *f = XFRAME (w->frame);
21075 int mouse_face_overwritten_p = 0;
21076
21077 while (w && !FRAME_GARBAGED_P (f))
21078 {
21079 if (!NILP (w->hchild))
21080 mouse_face_overwritten_p
21081 |= expose_window_tree (XWINDOW (w->hchild), r);
21082 else if (!NILP (w->vchild))
21083 mouse_face_overwritten_p
21084 |= expose_window_tree (XWINDOW (w->vchild), r);
21085 else
21086 mouse_face_overwritten_p |= expose_window (w, r);
21087
21088 w = NILP (w->next) ? NULL : XWINDOW (w->next);
21089 }
21090
21091 return mouse_face_overwritten_p;
21092 }
21093
21094
21095 /* EXPORT:
21096 Redisplay an exposed area of frame F. X and Y are the upper-left
21097 corner of the exposed rectangle. W and H are width and height of
21098 the exposed area. All are pixel values. W or H zero means redraw
21099 the entire frame. */
21100
21101 void
21102 expose_frame (f, x, y, w, h)
21103 struct frame *f;
21104 int x, y, w, h;
21105 {
21106 XRectangle r;
21107 int mouse_face_overwritten_p = 0;
21108
21109 TRACE ((stderr, "expose_frame "));
21110
21111 /* No need to redraw if frame will be redrawn soon. */
21112 if (FRAME_GARBAGED_P (f))
21113 {
21114 TRACE ((stderr, " garbaged\n"));
21115 return;
21116 }
21117
21118 #ifdef HAVE_CARBON
21119 /* MAC_TODO: this is a kludge, but if scroll bars are not activated
21120 or deactivated here, for unknown reasons, activated scroll bars
21121 are shown in deactivated frames in some instances. */
21122 if (f == FRAME_MAC_DISPLAY_INFO (f)->x_focus_frame)
21123 activate_scroll_bars (f);
21124 else
21125 deactivate_scroll_bars (f);
21126 #endif
21127
21128 /* If basic faces haven't been realized yet, there is no point in
21129 trying to redraw anything. This can happen when we get an expose
21130 event while Emacs is starting, e.g. by moving another window. */
21131 if (FRAME_FACE_CACHE (f) == NULL
21132 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
21133 {
21134 TRACE ((stderr, " no faces\n"));
21135 return;
21136 }
21137
21138 if (w == 0 || h == 0)
21139 {
21140 r.x = r.y = 0;
21141 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
21142 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
21143 }
21144 else
21145 {
21146 r.x = x;
21147 r.y = y;
21148 r.width = w;
21149 r.height = h;
21150 }
21151
21152 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
21153 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
21154
21155 if (WINDOWP (f->tool_bar_window))
21156 mouse_face_overwritten_p
21157 |= expose_window (XWINDOW (f->tool_bar_window), &r);
21158
21159 #ifdef HAVE_X_WINDOWS
21160 #ifndef MSDOS
21161 #ifndef USE_X_TOOLKIT
21162 if (WINDOWP (f->menu_bar_window))
21163 mouse_face_overwritten_p
21164 |= expose_window (XWINDOW (f->menu_bar_window), &r);
21165 #endif /* not USE_X_TOOLKIT */
21166 #endif
21167 #endif
21168
21169 /* Some window managers support a focus-follows-mouse style with
21170 delayed raising of frames. Imagine a partially obscured frame,
21171 and moving the mouse into partially obscured mouse-face on that
21172 frame. The visible part of the mouse-face will be highlighted,
21173 then the WM raises the obscured frame. With at least one WM, KDE
21174 2.1, Emacs is not getting any event for the raising of the frame
21175 (even tried with SubstructureRedirectMask), only Expose events.
21176 These expose events will draw text normally, i.e. not
21177 highlighted. Which means we must redo the highlight here.
21178 Subsume it under ``we love X''. --gerd 2001-08-15 */
21179 /* Included in Windows version because Windows most likely does not
21180 do the right thing if any third party tool offers
21181 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
21182 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
21183 {
21184 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21185 if (f == dpyinfo->mouse_face_mouse_frame)
21186 {
21187 int x = dpyinfo->mouse_face_mouse_x;
21188 int y = dpyinfo->mouse_face_mouse_y;
21189 clear_mouse_face (dpyinfo);
21190 note_mouse_highlight (f, x, y);
21191 }
21192 }
21193 }
21194
21195
21196 /* EXPORT:
21197 Determine the intersection of two rectangles R1 and R2. Return
21198 the intersection in *RESULT. Value is non-zero if RESULT is not
21199 empty. */
21200
21201 int
21202 x_intersect_rectangles (r1, r2, result)
21203 XRectangle *r1, *r2, *result;
21204 {
21205 XRectangle *left, *right;
21206 XRectangle *upper, *lower;
21207 int intersection_p = 0;
21208
21209 /* Rearrange so that R1 is the left-most rectangle. */
21210 if (r1->x < r2->x)
21211 left = r1, right = r2;
21212 else
21213 left = r2, right = r1;
21214
21215 /* X0 of the intersection is right.x0, if this is inside R1,
21216 otherwise there is no intersection. */
21217 if (right->x <= left->x + left->width)
21218 {
21219 result->x = right->x;
21220
21221 /* The right end of the intersection is the minimum of the
21222 the right ends of left and right. */
21223 result->width = (min (left->x + left->width, right->x + right->width)
21224 - result->x);
21225
21226 /* Same game for Y. */
21227 if (r1->y < r2->y)
21228 upper = r1, lower = r2;
21229 else
21230 upper = r2, lower = r1;
21231
21232 /* The upper end of the intersection is lower.y0, if this is inside
21233 of upper. Otherwise, there is no intersection. */
21234 if (lower->y <= upper->y + upper->height)
21235 {
21236 result->y = lower->y;
21237
21238 /* The lower end of the intersection is the minimum of the lower
21239 ends of upper and lower. */
21240 result->height = (min (lower->y + lower->height,
21241 upper->y + upper->height)
21242 - result->y);
21243 intersection_p = 1;
21244 }
21245 }
21246
21247 return intersection_p;
21248 }
21249
21250 #endif /* HAVE_WINDOW_SYSTEM */
21251
21252 \f
21253 /***********************************************************************
21254 Initialization
21255 ***********************************************************************/
21256
21257 void
21258 syms_of_xdisp ()
21259 {
21260 Vwith_echo_area_save_vector = Qnil;
21261 staticpro (&Vwith_echo_area_save_vector);
21262
21263 Vmessage_stack = Qnil;
21264 staticpro (&Vmessage_stack);
21265
21266 Qinhibit_redisplay = intern ("inhibit-redisplay");
21267 staticpro (&Qinhibit_redisplay);
21268
21269 message_dolog_marker1 = Fmake_marker ();
21270 staticpro (&message_dolog_marker1);
21271 message_dolog_marker2 = Fmake_marker ();
21272 staticpro (&message_dolog_marker2);
21273 message_dolog_marker3 = Fmake_marker ();
21274 staticpro (&message_dolog_marker3);
21275
21276 #if GLYPH_DEBUG
21277 defsubr (&Sdump_frame_glyph_matrix);
21278 defsubr (&Sdump_glyph_matrix);
21279 defsubr (&Sdump_glyph_row);
21280 defsubr (&Sdump_tool_bar_row);
21281 defsubr (&Strace_redisplay);
21282 defsubr (&Strace_to_stderr);
21283 #endif
21284 #ifdef HAVE_WINDOW_SYSTEM
21285 defsubr (&Stool_bar_lines_needed);
21286 defsubr (&Slookup_image_map);
21287 #endif
21288 defsubr (&Sformat_mode_line);
21289
21290 staticpro (&Qmenu_bar_update_hook);
21291 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
21292
21293 staticpro (&Qoverriding_terminal_local_map);
21294 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
21295
21296 staticpro (&Qoverriding_local_map);
21297 Qoverriding_local_map = intern ("overriding-local-map");
21298
21299 staticpro (&Qwindow_scroll_functions);
21300 Qwindow_scroll_functions = intern ("window-scroll-functions");
21301
21302 staticpro (&Qredisplay_end_trigger_functions);
21303 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
21304
21305 staticpro (&Qinhibit_point_motion_hooks);
21306 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
21307
21308 QCdata = intern (":data");
21309 staticpro (&QCdata);
21310 Qdisplay = intern ("display");
21311 staticpro (&Qdisplay);
21312 Qspace_width = intern ("space-width");
21313 staticpro (&Qspace_width);
21314 Qraise = intern ("raise");
21315 staticpro (&Qraise);
21316 Qspace = intern ("space");
21317 staticpro (&Qspace);
21318 Qmargin = intern ("margin");
21319 staticpro (&Qmargin);
21320 Qpointer = intern ("pointer");
21321 staticpro (&Qpointer);
21322 Qleft_margin = intern ("left-margin");
21323 staticpro (&Qleft_margin);
21324 Qright_margin = intern ("right-margin");
21325 staticpro (&Qright_margin);
21326 QCalign_to = intern (":align-to");
21327 staticpro (&QCalign_to);
21328 QCrelative_width = intern (":relative-width");
21329 staticpro (&QCrelative_width);
21330 QCrelative_height = intern (":relative-height");
21331 staticpro (&QCrelative_height);
21332 QCeval = intern (":eval");
21333 staticpro (&QCeval);
21334 QCpropertize = intern (":propertize");
21335 staticpro (&QCpropertize);
21336 QCfile = intern (":file");
21337 staticpro (&QCfile);
21338 Qfontified = intern ("fontified");
21339 staticpro (&Qfontified);
21340 Qfontification_functions = intern ("fontification-functions");
21341 staticpro (&Qfontification_functions);
21342 Qtrailing_whitespace = intern ("trailing-whitespace");
21343 staticpro (&Qtrailing_whitespace);
21344 Qimage = intern ("image");
21345 staticpro (&Qimage);
21346 QCmap = intern (":map");
21347 staticpro (&QCmap);
21348 QCpointer = intern (":pointer");
21349 staticpro (&QCpointer);
21350 Qrect = intern ("rect");
21351 staticpro (&Qrect);
21352 Qcircle = intern ("circle");
21353 staticpro (&Qcircle);
21354 Qpoly = intern ("poly");
21355 staticpro (&Qpoly);
21356 Qmessage_truncate_lines = intern ("message-truncate-lines");
21357 staticpro (&Qmessage_truncate_lines);
21358 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
21359 staticpro (&Qcursor_in_non_selected_windows);
21360 Qgrow_only = intern ("grow-only");
21361 staticpro (&Qgrow_only);
21362 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
21363 staticpro (&Qinhibit_menubar_update);
21364 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
21365 staticpro (&Qinhibit_eval_during_redisplay);
21366 Qposition = intern ("position");
21367 staticpro (&Qposition);
21368 Qbuffer_position = intern ("buffer-position");
21369 staticpro (&Qbuffer_position);
21370 Qobject = intern ("object");
21371 staticpro (&Qobject);
21372 Qbar = intern ("bar");
21373 staticpro (&Qbar);
21374 Qhbar = intern ("hbar");
21375 staticpro (&Qhbar);
21376 Qbox = intern ("box");
21377 staticpro (&Qbox);
21378 Qhollow = intern ("hollow");
21379 staticpro (&Qhollow);
21380 Qhand = intern ("hand");
21381 staticpro (&Qhand);
21382 Qarrow = intern ("arrow");
21383 staticpro (&Qarrow);
21384 Qtext = intern ("text");
21385 staticpro (&Qtext);
21386 Qrisky_local_variable = intern ("risky-local-variable");
21387 staticpro (&Qrisky_local_variable);
21388 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
21389 staticpro (&Qinhibit_free_realized_faces);
21390
21391 list_of_error = Fcons (intern ("error"), Qnil);
21392 staticpro (&list_of_error);
21393
21394 last_arrow_position = Qnil;
21395 last_arrow_string = Qnil;
21396 staticpro (&last_arrow_position);
21397 staticpro (&last_arrow_string);
21398
21399 echo_buffer[0] = echo_buffer[1] = Qnil;
21400 staticpro (&echo_buffer[0]);
21401 staticpro (&echo_buffer[1]);
21402
21403 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
21404 staticpro (&echo_area_buffer[0]);
21405 staticpro (&echo_area_buffer[1]);
21406
21407 Vmessages_buffer_name = build_string ("*Messages*");
21408 staticpro (&Vmessages_buffer_name);
21409
21410 mode_line_proptrans_alist = Qnil;
21411 staticpro (&mode_line_proptrans_alist);
21412
21413 mode_line_string_list = Qnil;
21414 staticpro (&mode_line_string_list);
21415
21416 help_echo_string = Qnil;
21417 staticpro (&help_echo_string);
21418 help_echo_object = Qnil;
21419 staticpro (&help_echo_object);
21420 help_echo_window = Qnil;
21421 staticpro (&help_echo_window);
21422 previous_help_echo_string = Qnil;
21423 staticpro (&previous_help_echo_string);
21424 help_echo_pos = -1;
21425
21426 #ifdef HAVE_WINDOW_SYSTEM
21427 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
21428 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
21429 For example, if a block cursor is over a tab, it will be drawn as
21430 wide as that tab on the display. */);
21431 x_stretch_cursor_p = 0;
21432 #endif
21433
21434 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
21435 doc: /* *Non-nil means highlight trailing whitespace.
21436 The face used for trailing whitespace is `trailing-whitespace'. */);
21437 Vshow_trailing_whitespace = Qnil;
21438
21439 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
21440 doc: /* *The pointer shape to show in void text areas.
21441 Nil means to show the text pointer. Other options are `arrow', `text',
21442 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
21443 Vvoid_text_area_pointer = Qarrow;
21444
21445 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
21446 doc: /* Non-nil means don't actually do any redisplay.
21447 This is used for internal purposes. */);
21448 Vinhibit_redisplay = Qnil;
21449
21450 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
21451 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
21452 Vglobal_mode_string = Qnil;
21453
21454 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
21455 doc: /* Marker for where to display an arrow on top of the buffer text.
21456 This must be the beginning of a line in order to work.
21457 See also `overlay-arrow-string'. */);
21458 Voverlay_arrow_position = Qnil;
21459
21460 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
21461 doc: /* String to display as an arrow. See also `overlay-arrow-position'. */);
21462 Voverlay_arrow_string = Qnil;
21463
21464 DEFVAR_INT ("scroll-step", &scroll_step,
21465 doc: /* *The number of lines to try scrolling a window by when point moves out.
21466 If that fails to bring point back on frame, point is centered instead.
21467 If this is zero, point is always centered after it moves off frame.
21468 If you want scrolling to always be a line at a time, you should set
21469 `scroll-conservatively' to a large value rather than set this to 1. */);
21470
21471 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
21472 doc: /* *Scroll up to this many lines, to bring point back on screen.
21473 A value of zero means to scroll the text to center point vertically
21474 in the window. */);
21475 scroll_conservatively = 0;
21476
21477 DEFVAR_INT ("scroll-margin", &scroll_margin,
21478 doc: /* *Number of lines of margin at the top and bottom of a window.
21479 Recenter the window whenever point gets within this many lines
21480 of the top or bottom of the window. */);
21481 scroll_margin = 0;
21482
21483 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
21484 doc: /* Pixels per inch on current display.
21485 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
21486 Vdisplay_pixels_per_inch = make_float (72.0);
21487
21488 #if GLYPH_DEBUG
21489 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
21490 #endif
21491
21492 DEFVAR_BOOL ("truncate-partial-width-windows",
21493 &truncate_partial_width_windows,
21494 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
21495 truncate_partial_width_windows = 1;
21496
21497 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
21498 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
21499 Any other value means to use the appropriate face, `mode-line',
21500 `header-line', or `menu' respectively. */);
21501 mode_line_inverse_video = 1;
21502
21503 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
21504 doc: /* *Maximum buffer size for which line number should be displayed.
21505 If the buffer is bigger than this, the line number does not appear
21506 in the mode line. A value of nil means no limit. */);
21507 Vline_number_display_limit = Qnil;
21508
21509 DEFVAR_INT ("line-number-display-limit-width",
21510 &line_number_display_limit_width,
21511 doc: /* *Maximum line width (in characters) for line number display.
21512 If the average length of the lines near point is bigger than this, then the
21513 line number may be omitted from the mode line. */);
21514 line_number_display_limit_width = 200;
21515
21516 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
21517 doc: /* *Non-nil means highlight region even in nonselected windows. */);
21518 highlight_nonselected_windows = 0;
21519
21520 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
21521 doc: /* Non-nil if more than one frame is visible on this display.
21522 Minibuffer-only frames don't count, but iconified frames do.
21523 This variable is not guaranteed to be accurate except while processing
21524 `frame-title-format' and `icon-title-format'. */);
21525
21526 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
21527 doc: /* Template for displaying the title bar of visible frames.
21528 \(Assuming the window manager supports this feature.)
21529 This variable has the same structure as `mode-line-format' (which see),
21530 and is used only on frames for which no explicit name has been set
21531 \(see `modify-frame-parameters'). */);
21532
21533 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
21534 doc: /* Template for displaying the title bar of an iconified frame.
21535 \(Assuming the window manager supports this feature.)
21536 This variable has the same structure as `mode-line-format' (which see),
21537 and is used only on frames for which no explicit name has been set
21538 \(see `modify-frame-parameters'). */);
21539 Vicon_title_format
21540 = Vframe_title_format
21541 = Fcons (intern ("multiple-frames"),
21542 Fcons (build_string ("%b"),
21543 Fcons (Fcons (empty_string,
21544 Fcons (intern ("invocation-name"),
21545 Fcons (build_string ("@"),
21546 Fcons (intern ("system-name"),
21547 Qnil)))),
21548 Qnil)));
21549
21550 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
21551 doc: /* Maximum number of lines to keep in the message log buffer.
21552 If nil, disable message logging. If t, log messages but don't truncate
21553 the buffer when it becomes large. */);
21554 Vmessage_log_max = make_number (50);
21555
21556 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
21557 doc: /* Functions called before redisplay, if window sizes have changed.
21558 The value should be a list of functions that take one argument.
21559 Just before redisplay, for each frame, if any of its windows have changed
21560 size since the last redisplay, or have been split or deleted,
21561 all the functions in the list are called, with the frame as argument. */);
21562 Vwindow_size_change_functions = Qnil;
21563
21564 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
21565 doc: /* List of Functions to call before redisplaying a window with scrolling.
21566 Each function is called with two arguments, the window
21567 and its new display-start position. Note that the value of `window-end'
21568 is not valid when these functions are called. */);
21569 Vwindow_scroll_functions = Qnil;
21570
21571 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
21572 doc: /* *Non-nil means autoselect window with mouse pointer. */);
21573 mouse_autoselect_window = 0;
21574
21575 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
21576 doc: /* *Non-nil means automatically resize tool-bars.
21577 This increases a tool-bar's height if not all tool-bar items are visible.
21578 It decreases a tool-bar's height when it would display blank lines
21579 otherwise. */);
21580 auto_resize_tool_bars_p = 1;
21581
21582 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
21583 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
21584 auto_raise_tool_bar_buttons_p = 1;
21585
21586 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
21587 doc: /* *Margin around tool-bar buttons in pixels.
21588 If an integer, use that for both horizontal and vertical margins.
21589 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
21590 HORZ specifying the horizontal margin, and VERT specifying the
21591 vertical margin. */);
21592 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
21593
21594 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
21595 doc: /* *Relief thickness of tool-bar buttons. */);
21596 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
21597
21598 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
21599 doc: /* List of functions to call to fontify regions of text.
21600 Each function is called with one argument POS. Functions must
21601 fontify a region starting at POS in the current buffer, and give
21602 fontified regions the property `fontified'. */);
21603 Vfontification_functions = Qnil;
21604 Fmake_variable_buffer_local (Qfontification_functions);
21605
21606 DEFVAR_BOOL ("unibyte-display-via-language-environment",
21607 &unibyte_display_via_language_environment,
21608 doc: /* *Non-nil means display unibyte text according to language environment.
21609 Specifically this means that unibyte non-ASCII characters
21610 are displayed by converting them to the equivalent multibyte characters
21611 according to the current language environment. As a result, they are
21612 displayed according to the current fontset. */);
21613 unibyte_display_via_language_environment = 0;
21614
21615 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
21616 doc: /* *Maximum height for resizing mini-windows.
21617 If a float, it specifies a fraction of the mini-window frame's height.
21618 If an integer, it specifies a number of lines. */);
21619 Vmax_mini_window_height = make_float (0.25);
21620
21621 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
21622 doc: /* *How to resize mini-windows.
21623 A value of nil means don't automatically resize mini-windows.
21624 A value of t means resize them to fit the text displayed in them.
21625 A value of `grow-only', the default, means let mini-windows grow
21626 only, until their display becomes empty, at which point the windows
21627 go back to their normal size. */);
21628 Vresize_mini_windows = Qgrow_only;
21629
21630 DEFVAR_LISP ("cursor-in-non-selected-windows",
21631 &Vcursor_in_non_selected_windows,
21632 doc: /* *Cursor type to display in non-selected windows.
21633 t means to use hollow box cursor. See `cursor-type' for other values. */);
21634 Vcursor_in_non_selected_windows = Qt;
21635
21636 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
21637 doc: /* Alist specifying how to blink the cursor off.
21638 Each element has the form (ON-STATE . OFF-STATE). Whenever the
21639 `cursor-type' frame-parameter or variable equals ON-STATE,
21640 comparing using `equal', Emacs uses OFF-STATE to specify
21641 how to blink it off. */);
21642 Vblink_cursor_alist = Qnil;
21643
21644 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
21645 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
21646 automatic_hscrolling_p = 1;
21647
21648 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
21649 doc: /* *How many columns away from the window edge point is allowed to get
21650 before automatic hscrolling will horizontally scroll the window. */);
21651 hscroll_margin = 5;
21652
21653 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
21654 doc: /* *How many columns to scroll the window when point gets too close to the edge.
21655 When point is less than `automatic-hscroll-margin' columns from the window
21656 edge, automatic hscrolling will scroll the window by the amount of columns
21657 determined by this variable. If its value is a positive integer, scroll that
21658 many columns. If it's a positive floating-point number, it specifies the
21659 fraction of the window's width to scroll. If it's nil or zero, point will be
21660 centered horizontally after the scroll. Any other value, including negative
21661 numbers, are treated as if the value were zero.
21662
21663 Automatic hscrolling always moves point outside the scroll margin, so if
21664 point was more than scroll step columns inside the margin, the window will
21665 scroll more than the value given by the scroll step.
21666
21667 Note that the lower bound for automatic hscrolling specified by `scroll-left'
21668 and `scroll-right' overrides this variable's effect. */);
21669 Vhscroll_step = make_number (0);
21670
21671 DEFVAR_LISP ("image-types", &Vimage_types,
21672 doc: /* List of supported image types.
21673 Each element of the list is a symbol for a supported image type. */);
21674 Vimage_types = Qnil;
21675
21676 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
21677 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
21678 Bind this around calls to `message' to let it take effect. */);
21679 message_truncate_lines = 0;
21680
21681 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
21682 doc: /* Normal hook run for clicks on menu bar, before displaying a submenu.
21683 Can be used to update submenus whose contents should vary. */);
21684 Vmenu_bar_update_hook = Qnil;
21685
21686 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
21687 doc: /* Non-nil means don't update menu bars. Internal use only. */);
21688 inhibit_menubar_update = 0;
21689
21690 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
21691 doc: /* Non-nil means don't eval Lisp during redisplay. */);
21692 inhibit_eval_during_redisplay = 0;
21693
21694 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
21695 doc: /* Non-nil means don't free realized faces. Internal use only. */);
21696 inhibit_free_realized_faces = 0;
21697
21698 #if GLYPH_DEBUG
21699 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
21700 doc: /* Inhibit try_window_id display optimization. */);
21701 inhibit_try_window_id = 0;
21702
21703 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
21704 doc: /* Inhibit try_window_reusing display optimization. */);
21705 inhibit_try_window_reusing = 0;
21706
21707 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
21708 doc: /* Inhibit try_cursor_movement display optimization. */);
21709 inhibit_try_cursor_movement = 0;
21710 #endif /* GLYPH_DEBUG */
21711 }
21712
21713
21714 /* Initialize this module when Emacs starts. */
21715
21716 void
21717 init_xdisp ()
21718 {
21719 Lisp_Object root_window;
21720 struct window *mini_w;
21721
21722 current_header_line_height = current_mode_line_height = -1;
21723
21724 CHARPOS (this_line_start_pos) = 0;
21725
21726 mini_w = XWINDOW (minibuf_window);
21727 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
21728
21729 if (!noninteractive)
21730 {
21731 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
21732 int i;
21733
21734 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
21735 set_window_height (root_window,
21736 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
21737 0);
21738 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
21739 set_window_height (minibuf_window, 1, 0);
21740
21741 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
21742 mini_w->total_cols = make_number (FRAME_COLS (f));
21743
21744 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
21745 scratch_glyph_row.glyphs[TEXT_AREA + 1]
21746 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
21747
21748 /* The default ellipsis glyphs `...'. */
21749 for (i = 0; i < 3; ++i)
21750 default_invis_vector[i] = make_number ('.');
21751 }
21752
21753 {
21754 /* Allocate the buffer for frame titles.
21755 Also used for `format-mode-line'. */
21756 int size = 100;
21757 frame_title_buf = (char *) xmalloc (size);
21758 frame_title_buf_end = frame_title_buf + size;
21759 frame_title_ptr = NULL;
21760 }
21761
21762 help_echo_showing_p = 0;
21763 }
21764
21765
21766 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
21767 (do not change this comment) */