]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(pos_visible_p): Fix X value in last line of buffer.
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
125
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
131
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
138
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
146
147
148 Frame matrices.
149
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
156
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
168
169 #include <config.h>
170 #include <stdio.h>
171
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
192
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201 #endif
202
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
206
207 #define INFINITY 10000000
208
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
214
215 extern int interrupt_input;
216 extern int command_loop_level;
217
218 extern Lisp_Object do_mouse_tracking;
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 /* Non-zero means to reposition window if cursor line is only partially visible. */
268
269 int make_cursor_line_fully_visible_p;
270
271 /* Margin around tool bar buttons in pixels. */
272
273 Lisp_Object Vtool_bar_button_margin;
274
275 /* Thickness of shadow to draw around tool bar buttons. */
276
277 EMACS_INT tool_bar_button_relief;
278
279 /* Non-zero means automatically resize tool-bars so that all tool-bar
280 items are visible, and no blank lines remain. */
281
282 int auto_resize_tool_bars_p;
283
284 /* Non-zero means draw block and hollow cursor as wide as the glyph
285 under it. For example, if a block cursor is over a tab, it will be
286 drawn as wide as that tab on the display. */
287
288 int x_stretch_cursor_p;
289
290 /* Non-nil means don't actually do any redisplay. */
291
292 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
293
294 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
295
296 int inhibit_eval_during_redisplay;
297
298 /* Names of text properties relevant for redisplay. */
299
300 Lisp_Object Qdisplay;
301 extern Lisp_Object Qface, Qinvisible, Qwidth;
302
303 /* Symbols used in text property values. */
304
305 Lisp_Object Vdisplay_pixels_per_inch;
306 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
307 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
308 Lisp_Object Qslice;
309 Lisp_Object Qcenter;
310 Lisp_Object Qmargin, Qpointer;
311 Lisp_Object Qline_height;
312 extern Lisp_Object Qheight;
313 extern Lisp_Object QCwidth, QCheight, QCascent;
314 extern Lisp_Object Qscroll_bar;
315 extern Lisp_Object Qcursor;
316
317 /* Non-nil means highlight trailing whitespace. */
318
319 Lisp_Object Vshow_trailing_whitespace;
320
321 /* Non-nil means escape non-break space and hyphens. */
322
323 Lisp_Object Vshow_nonbreak_escape;
324
325 #ifdef HAVE_WINDOW_SYSTEM
326 extern Lisp_Object Voverflow_newline_into_fringe;
327
328 /* Test if overflow newline into fringe. Called with iterator IT
329 at or past right window margin, and with IT->current_x set. */
330
331 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
332 (!NILP (Voverflow_newline_into_fringe) \
333 && FRAME_WINDOW_P (it->f) \
334 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
335 && it->current_x == it->last_visible_x)
336
337 #endif /* HAVE_WINDOW_SYSTEM */
338
339 /* Non-nil means show the text cursor in void text areas
340 i.e. in blank areas after eol and eob. This used to be
341 the default in 21.3. */
342
343 Lisp_Object Vvoid_text_area_pointer;
344
345 /* Name of the face used to highlight trailing whitespace. */
346
347 Lisp_Object Qtrailing_whitespace;
348
349 /* Name and number of the face used to highlight escape glyphs. */
350
351 Lisp_Object Qescape_glyph;
352
353 /* The symbol `image' which is the car of the lists used to represent
354 images in Lisp. */
355
356 Lisp_Object Qimage;
357
358 /* The image map types. */
359 Lisp_Object QCmap, QCpointer;
360 Lisp_Object Qrect, Qcircle, Qpoly;
361
362 /* Non-zero means print newline to stdout before next mini-buffer
363 message. */
364
365 int noninteractive_need_newline;
366
367 /* Non-zero means print newline to message log before next message. */
368
369 static int message_log_need_newline;
370
371 /* Three markers that message_dolog uses.
372 It could allocate them itself, but that causes trouble
373 in handling memory-full errors. */
374 static Lisp_Object message_dolog_marker1;
375 static Lisp_Object message_dolog_marker2;
376 static Lisp_Object message_dolog_marker3;
377 \f
378 /* The buffer position of the first character appearing entirely or
379 partially on the line of the selected window which contains the
380 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
381 redisplay optimization in redisplay_internal. */
382
383 static struct text_pos this_line_start_pos;
384
385 /* Number of characters past the end of the line above, including the
386 terminating newline. */
387
388 static struct text_pos this_line_end_pos;
389
390 /* The vertical positions and the height of this line. */
391
392 static int this_line_vpos;
393 static int this_line_y;
394 static int this_line_pixel_height;
395
396 /* X position at which this display line starts. Usually zero;
397 negative if first character is partially visible. */
398
399 static int this_line_start_x;
400
401 /* Buffer that this_line_.* variables are referring to. */
402
403 static struct buffer *this_line_buffer;
404
405 /* Nonzero means truncate lines in all windows less wide than the
406 frame. */
407
408 int truncate_partial_width_windows;
409
410 /* A flag to control how to display unibyte 8-bit character. */
411
412 int unibyte_display_via_language_environment;
413
414 /* Nonzero means we have more than one non-mini-buffer-only frame.
415 Not guaranteed to be accurate except while parsing
416 frame-title-format. */
417
418 int multiple_frames;
419
420 Lisp_Object Vglobal_mode_string;
421
422
423 /* List of variables (symbols) which hold markers for overlay arrows.
424 The symbols on this list are examined during redisplay to determine
425 where to display overlay arrows. */
426
427 Lisp_Object Voverlay_arrow_variable_list;
428
429 /* Marker for where to display an arrow on top of the buffer text. */
430
431 Lisp_Object Voverlay_arrow_position;
432
433 /* String to display for the arrow. Only used on terminal frames. */
434
435 Lisp_Object Voverlay_arrow_string;
436
437 /* Values of those variables at last redisplay are stored as
438 properties on `overlay-arrow-position' symbol. However, if
439 Voverlay_arrow_position is a marker, last-arrow-position is its
440 numerical position. */
441
442 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
443
444 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
445 properties on a symbol in overlay-arrow-variable-list. */
446
447 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
448
449 /* Like mode-line-format, but for the title bar on a visible frame. */
450
451 Lisp_Object Vframe_title_format;
452
453 /* Like mode-line-format, but for the title bar on an iconified frame. */
454
455 Lisp_Object Vicon_title_format;
456
457 /* List of functions to call when a window's size changes. These
458 functions get one arg, a frame on which one or more windows' sizes
459 have changed. */
460
461 static Lisp_Object Vwindow_size_change_functions;
462
463 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
464
465 /* Nonzero if overlay arrow has been displayed once in this window. */
466
467 static int overlay_arrow_seen;
468
469 /* Nonzero means highlight the region even in nonselected windows. */
470
471 int highlight_nonselected_windows;
472
473 /* If cursor motion alone moves point off frame, try scrolling this
474 many lines up or down if that will bring it back. */
475
476 static EMACS_INT scroll_step;
477
478 /* Nonzero means scroll just far enough to bring point back on the
479 screen, when appropriate. */
480
481 static EMACS_INT scroll_conservatively;
482
483 /* Recenter the window whenever point gets within this many lines of
484 the top or bottom of the window. This value is translated into a
485 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
486 that there is really a fixed pixel height scroll margin. */
487
488 EMACS_INT scroll_margin;
489
490 /* Number of windows showing the buffer of the selected window (or
491 another buffer with the same base buffer). keyboard.c refers to
492 this. */
493
494 int buffer_shared;
495
496 /* Vector containing glyphs for an ellipsis `...'. */
497
498 static Lisp_Object default_invis_vector[3];
499
500 /* Zero means display the mode-line/header-line/menu-bar in the default face
501 (this slightly odd definition is for compatibility with previous versions
502 of emacs), non-zero means display them using their respective faces.
503
504 This variable is deprecated. */
505
506 int mode_line_inverse_video;
507
508 /* Prompt to display in front of the mini-buffer contents. */
509
510 Lisp_Object minibuf_prompt;
511
512 /* Width of current mini-buffer prompt. Only set after display_line
513 of the line that contains the prompt. */
514
515 int minibuf_prompt_width;
516
517 /* This is the window where the echo area message was displayed. It
518 is always a mini-buffer window, but it may not be the same window
519 currently active as a mini-buffer. */
520
521 Lisp_Object echo_area_window;
522
523 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
524 pushes the current message and the value of
525 message_enable_multibyte on the stack, the function restore_message
526 pops the stack and displays MESSAGE again. */
527
528 Lisp_Object Vmessage_stack;
529
530 /* Nonzero means multibyte characters were enabled when the echo area
531 message was specified. */
532
533 int message_enable_multibyte;
534
535 /* Nonzero if we should redraw the mode lines on the next redisplay. */
536
537 int update_mode_lines;
538
539 /* Nonzero if window sizes or contents have changed since last
540 redisplay that finished. */
541
542 int windows_or_buffers_changed;
543
544 /* Nonzero means a frame's cursor type has been changed. */
545
546 int cursor_type_changed;
547
548 /* Nonzero after display_mode_line if %l was used and it displayed a
549 line number. */
550
551 int line_number_displayed;
552
553 /* Maximum buffer size for which to display line numbers. */
554
555 Lisp_Object Vline_number_display_limit;
556
557 /* Line width to consider when repositioning for line number display. */
558
559 static EMACS_INT line_number_display_limit_width;
560
561 /* Number of lines to keep in the message log buffer. t means
562 infinite. nil means don't log at all. */
563
564 Lisp_Object Vmessage_log_max;
565
566 /* The name of the *Messages* buffer, a string. */
567
568 static Lisp_Object Vmessages_buffer_name;
569
570 /* Current, index 0, and last displayed echo area message. Either
571 buffers from echo_buffers, or nil to indicate no message. */
572
573 Lisp_Object echo_area_buffer[2];
574
575 /* The buffers referenced from echo_area_buffer. */
576
577 static Lisp_Object echo_buffer[2];
578
579 /* A vector saved used in with_area_buffer to reduce consing. */
580
581 static Lisp_Object Vwith_echo_area_save_vector;
582
583 /* Non-zero means display_echo_area should display the last echo area
584 message again. Set by redisplay_preserve_echo_area. */
585
586 static int display_last_displayed_message_p;
587
588 /* Nonzero if echo area is being used by print; zero if being used by
589 message. */
590
591 int message_buf_print;
592
593 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
594
595 Lisp_Object Qinhibit_menubar_update;
596 int inhibit_menubar_update;
597
598 /* Maximum height for resizing mini-windows. Either a float
599 specifying a fraction of the available height, or an integer
600 specifying a number of lines. */
601
602 Lisp_Object Vmax_mini_window_height;
603
604 /* Non-zero means messages should be displayed with truncated
605 lines instead of being continued. */
606
607 int message_truncate_lines;
608 Lisp_Object Qmessage_truncate_lines;
609
610 /* Set to 1 in clear_message to make redisplay_internal aware
611 of an emptied echo area. */
612
613 static int message_cleared_p;
614
615 /* Non-zero means we want a hollow cursor in windows that are not
616 selected. Zero means there's no cursor in such windows. */
617
618 Lisp_Object Vcursor_in_non_selected_windows;
619 Lisp_Object Qcursor_in_non_selected_windows;
620
621 /* How to blink the default frame cursor off. */
622 Lisp_Object Vblink_cursor_alist;
623
624 /* A scratch glyph row with contents used for generating truncation
625 glyphs. Also used in direct_output_for_insert. */
626
627 #define MAX_SCRATCH_GLYPHS 100
628 struct glyph_row scratch_glyph_row;
629 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
630
631 /* Ascent and height of the last line processed by move_it_to. */
632
633 static int last_max_ascent, last_height;
634
635 /* Non-zero if there's a help-echo in the echo area. */
636
637 int help_echo_showing_p;
638
639 /* If >= 0, computed, exact values of mode-line and header-line height
640 to use in the macros CURRENT_MODE_LINE_HEIGHT and
641 CURRENT_HEADER_LINE_HEIGHT. */
642
643 int current_mode_line_height, current_header_line_height;
644
645 /* The maximum distance to look ahead for text properties. Values
646 that are too small let us call compute_char_face and similar
647 functions too often which is expensive. Values that are too large
648 let us call compute_char_face and alike too often because we
649 might not be interested in text properties that far away. */
650
651 #define TEXT_PROP_DISTANCE_LIMIT 100
652
653 #if GLYPH_DEBUG
654
655 /* Variables to turn off display optimizations from Lisp. */
656
657 int inhibit_try_window_id, inhibit_try_window_reusing;
658 int inhibit_try_cursor_movement;
659
660 /* Non-zero means print traces of redisplay if compiled with
661 GLYPH_DEBUG != 0. */
662
663 int trace_redisplay_p;
664
665 #endif /* GLYPH_DEBUG */
666
667 #ifdef DEBUG_TRACE_MOVE
668 /* Non-zero means trace with TRACE_MOVE to stderr. */
669 int trace_move;
670
671 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
672 #else
673 #define TRACE_MOVE(x) (void) 0
674 #endif
675
676 /* Non-zero means automatically scroll windows horizontally to make
677 point visible. */
678
679 int automatic_hscrolling_p;
680
681 /* How close to the margin can point get before the window is scrolled
682 horizontally. */
683 EMACS_INT hscroll_margin;
684
685 /* How much to scroll horizontally when point is inside the above margin. */
686 Lisp_Object Vhscroll_step;
687
688 /* The variable `resize-mini-windows'. If nil, don't resize
689 mini-windows. If t, always resize them to fit the text they
690 display. If `grow-only', let mini-windows grow only until they
691 become empty. */
692
693 Lisp_Object Vresize_mini_windows;
694
695 /* Buffer being redisplayed -- for redisplay_window_error. */
696
697 struct buffer *displayed_buffer;
698
699 /* Value returned from text property handlers (see below). */
700
701 enum prop_handled
702 {
703 HANDLED_NORMALLY,
704 HANDLED_RECOMPUTE_PROPS,
705 HANDLED_OVERLAY_STRING_CONSUMED,
706 HANDLED_RETURN
707 };
708
709 /* A description of text properties that redisplay is interested
710 in. */
711
712 struct props
713 {
714 /* The name of the property. */
715 Lisp_Object *name;
716
717 /* A unique index for the property. */
718 enum prop_idx idx;
719
720 /* A handler function called to set up iterator IT from the property
721 at IT's current position. Value is used to steer handle_stop. */
722 enum prop_handled (*handler) P_ ((struct it *it));
723 };
724
725 static enum prop_handled handle_face_prop P_ ((struct it *));
726 static enum prop_handled handle_invisible_prop P_ ((struct it *));
727 static enum prop_handled handle_display_prop P_ ((struct it *));
728 static enum prop_handled handle_composition_prop P_ ((struct it *));
729 static enum prop_handled handle_overlay_change P_ ((struct it *));
730 static enum prop_handled handle_fontified_prop P_ ((struct it *));
731
732 /* Properties handled by iterators. */
733
734 static struct props it_props[] =
735 {
736 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
737 /* Handle `face' before `display' because some sub-properties of
738 `display' need to know the face. */
739 {&Qface, FACE_PROP_IDX, handle_face_prop},
740 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
741 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
742 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
743 {NULL, 0, NULL}
744 };
745
746 /* Value is the position described by X. If X is a marker, value is
747 the marker_position of X. Otherwise, value is X. */
748
749 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
750
751 /* Enumeration returned by some move_it_.* functions internally. */
752
753 enum move_it_result
754 {
755 /* Not used. Undefined value. */
756 MOVE_UNDEFINED,
757
758 /* Move ended at the requested buffer position or ZV. */
759 MOVE_POS_MATCH_OR_ZV,
760
761 /* Move ended at the requested X pixel position. */
762 MOVE_X_REACHED,
763
764 /* Move within a line ended at the end of a line that must be
765 continued. */
766 MOVE_LINE_CONTINUED,
767
768 /* Move within a line ended at the end of a line that would
769 be displayed truncated. */
770 MOVE_LINE_TRUNCATED,
771
772 /* Move within a line ended at a line end. */
773 MOVE_NEWLINE_OR_CR
774 };
775
776 /* This counter is used to clear the face cache every once in a while
777 in redisplay_internal. It is incremented for each redisplay.
778 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
779 cleared. */
780
781 #define CLEAR_FACE_CACHE_COUNT 500
782 static int clear_face_cache_count;
783
784 /* Similarly for the image cache. */
785
786 #ifdef HAVE_WINDOW_SYSTEM
787 #define CLEAR_IMAGE_CACHE_COUNT 101
788 static int clear_image_cache_count;
789 #endif
790
791 /* Record the previous terminal frame we displayed. */
792
793 static struct frame *previous_terminal_frame;
794
795 /* Non-zero while redisplay_internal is in progress. */
796
797 int redisplaying_p;
798
799 /* Non-zero means don't free realized faces. Bound while freeing
800 realized faces is dangerous because glyph matrices might still
801 reference them. */
802
803 int inhibit_free_realized_faces;
804 Lisp_Object Qinhibit_free_realized_faces;
805
806 /* If a string, XTread_socket generates an event to display that string.
807 (The display is done in read_char.) */
808
809 Lisp_Object help_echo_string;
810 Lisp_Object help_echo_window;
811 Lisp_Object help_echo_object;
812 int help_echo_pos;
813
814 /* Temporary variable for XTread_socket. */
815
816 Lisp_Object previous_help_echo_string;
817
818 /* Null glyph slice */
819
820 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
821
822 \f
823 /* Function prototypes. */
824
825 static void setup_for_ellipsis P_ ((struct it *, int));
826 static void mark_window_display_accurate_1 P_ ((struct window *, int));
827 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
828 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
829 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
830 static int redisplay_mode_lines P_ ((Lisp_Object, int));
831 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
832
833 #if 0
834 static int invisible_text_between_p P_ ((struct it *, int, int));
835 #endif
836
837 static void pint2str P_ ((char *, int, int));
838 static void pint2hrstr P_ ((char *, int, int));
839 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
840 struct text_pos));
841 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
842 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
843 static void store_frame_title_char P_ ((char));
844 static int store_frame_title P_ ((const unsigned char *, int, int));
845 static void x_consider_frame_title P_ ((Lisp_Object));
846 static void handle_stop P_ ((struct it *));
847 static int tool_bar_lines_needed P_ ((struct frame *));
848 static int single_display_spec_intangible_p P_ ((Lisp_Object));
849 static void ensure_echo_area_buffers P_ ((void));
850 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
851 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
852 static int with_echo_area_buffer P_ ((struct window *, int,
853 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
854 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
855 static void clear_garbaged_frames P_ ((void));
856 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
857 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
858 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
859 static int display_echo_area P_ ((struct window *));
860 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
861 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
862 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
863 static int string_char_and_length P_ ((const unsigned char *, int, int *));
864 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
865 struct text_pos));
866 static int compute_window_start_on_continuation_line P_ ((struct window *));
867 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
868 static void insert_left_trunc_glyphs P_ ((struct it *));
869 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
870 Lisp_Object));
871 static void extend_face_to_end_of_line P_ ((struct it *));
872 static int append_space_for_newline P_ ((struct it *, int));
873 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
874 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
875 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
876 static int trailing_whitespace_p P_ ((int));
877 static int message_log_check_duplicate P_ ((int, int, int, int));
878 static void push_it P_ ((struct it *));
879 static void pop_it P_ ((struct it *));
880 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
881 static void select_frame_for_redisplay P_ ((Lisp_Object));
882 static void redisplay_internal P_ ((int));
883 static int echo_area_display P_ ((int));
884 static void redisplay_windows P_ ((Lisp_Object));
885 static void redisplay_window P_ ((Lisp_Object, int));
886 static Lisp_Object redisplay_window_error ();
887 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
888 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
889 static void update_menu_bar P_ ((struct frame *, int));
890 static int try_window_reusing_current_matrix P_ ((struct window *));
891 static int try_window_id P_ ((struct window *));
892 static int display_line P_ ((struct it *));
893 static int display_mode_lines P_ ((struct window *));
894 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
895 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
896 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
897 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
898 static void display_menu_bar P_ ((struct window *));
899 static int display_count_lines P_ ((int, int, int, int, int *));
900 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
901 int, int, struct it *, int, int, int, int));
902 static void compute_line_metrics P_ ((struct it *));
903 static void run_redisplay_end_trigger_hook P_ ((struct it *));
904 static int get_overlay_strings P_ ((struct it *, int));
905 static void next_overlay_string P_ ((struct it *));
906 static void reseat P_ ((struct it *, struct text_pos, int));
907 static void reseat_1 P_ ((struct it *, struct text_pos, int));
908 static void back_to_previous_visible_line_start P_ ((struct it *));
909 void reseat_at_previous_visible_line_start P_ ((struct it *));
910 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
911 static int next_element_from_ellipsis P_ ((struct it *));
912 static int next_element_from_display_vector P_ ((struct it *));
913 static int next_element_from_string P_ ((struct it *));
914 static int next_element_from_c_string P_ ((struct it *));
915 static int next_element_from_buffer P_ ((struct it *));
916 static int next_element_from_composition P_ ((struct it *));
917 static int next_element_from_image P_ ((struct it *));
918 static int next_element_from_stretch P_ ((struct it *));
919 static void load_overlay_strings P_ ((struct it *, int));
920 static int init_from_display_pos P_ ((struct it *, struct window *,
921 struct display_pos *));
922 static void reseat_to_string P_ ((struct it *, unsigned char *,
923 Lisp_Object, int, int, int, int));
924 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
925 int, int, int));
926 void move_it_vertically_backward P_ ((struct it *, int));
927 static void init_to_row_start P_ ((struct it *, struct window *,
928 struct glyph_row *));
929 static int init_to_row_end P_ ((struct it *, struct window *,
930 struct glyph_row *));
931 static void back_to_previous_line_start P_ ((struct it *));
932 static int forward_to_next_line_start P_ ((struct it *, int *));
933 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
934 Lisp_Object, int));
935 static struct text_pos string_pos P_ ((int, Lisp_Object));
936 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
937 static int number_of_chars P_ ((unsigned char *, int));
938 static void compute_stop_pos P_ ((struct it *));
939 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
940 Lisp_Object));
941 static int face_before_or_after_it_pos P_ ((struct it *, int));
942 static int next_overlay_change P_ ((int));
943 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
944 Lisp_Object, struct text_pos *,
945 int));
946 static int underlying_face_id P_ ((struct it *));
947 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
948 struct window *));
949
950 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
951 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
952
953 #ifdef HAVE_WINDOW_SYSTEM
954
955 static void update_tool_bar P_ ((struct frame *, int));
956 static void build_desired_tool_bar_string P_ ((struct frame *f));
957 static int redisplay_tool_bar P_ ((struct frame *));
958 static void display_tool_bar_line P_ ((struct it *));
959 static void notice_overwritten_cursor P_ ((struct window *,
960 enum glyph_row_area,
961 int, int, int, int));
962
963
964
965 #endif /* HAVE_WINDOW_SYSTEM */
966
967 \f
968 /***********************************************************************
969 Window display dimensions
970 ***********************************************************************/
971
972 /* Return the bottom boundary y-position for text lines in window W.
973 This is the first y position at which a line cannot start.
974 It is relative to the top of the window.
975
976 This is the height of W minus the height of a mode line, if any. */
977
978 INLINE int
979 window_text_bottom_y (w)
980 struct window *w;
981 {
982 int height = WINDOW_TOTAL_HEIGHT (w);
983
984 if (WINDOW_WANTS_MODELINE_P (w))
985 height -= CURRENT_MODE_LINE_HEIGHT (w);
986 return height;
987 }
988
989 /* Return the pixel width of display area AREA of window W. AREA < 0
990 means return the total width of W, not including fringes to
991 the left and right of the window. */
992
993 INLINE int
994 window_box_width (w, area)
995 struct window *w;
996 int area;
997 {
998 int cols = XFASTINT (w->total_cols);
999 int pixels = 0;
1000
1001 if (!w->pseudo_window_p)
1002 {
1003 cols -= WINDOW_SCROLL_BAR_COLS (w);
1004
1005 if (area == TEXT_AREA)
1006 {
1007 if (INTEGERP (w->left_margin_cols))
1008 cols -= XFASTINT (w->left_margin_cols);
1009 if (INTEGERP (w->right_margin_cols))
1010 cols -= XFASTINT (w->right_margin_cols);
1011 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1012 }
1013 else if (area == LEFT_MARGIN_AREA)
1014 {
1015 cols = (INTEGERP (w->left_margin_cols)
1016 ? XFASTINT (w->left_margin_cols) : 0);
1017 pixels = 0;
1018 }
1019 else if (area == RIGHT_MARGIN_AREA)
1020 {
1021 cols = (INTEGERP (w->right_margin_cols)
1022 ? XFASTINT (w->right_margin_cols) : 0);
1023 pixels = 0;
1024 }
1025 }
1026
1027 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1028 }
1029
1030
1031 /* Return the pixel height of the display area of window W, not
1032 including mode lines of W, if any. */
1033
1034 INLINE int
1035 window_box_height (w)
1036 struct window *w;
1037 {
1038 struct frame *f = XFRAME (w->frame);
1039 int height = WINDOW_TOTAL_HEIGHT (w);
1040
1041 xassert (height >= 0);
1042
1043 /* Note: the code below that determines the mode-line/header-line
1044 height is essentially the same as that contained in the macro
1045 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1046 the appropriate glyph row has its `mode_line_p' flag set,
1047 and if it doesn't, uses estimate_mode_line_height instead. */
1048
1049 if (WINDOW_WANTS_MODELINE_P (w))
1050 {
1051 struct glyph_row *ml_row
1052 = (w->current_matrix && w->current_matrix->rows
1053 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1054 : 0);
1055 if (ml_row && ml_row->mode_line_p)
1056 height -= ml_row->height;
1057 else
1058 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1059 }
1060
1061 if (WINDOW_WANTS_HEADER_LINE_P (w))
1062 {
1063 struct glyph_row *hl_row
1064 = (w->current_matrix && w->current_matrix->rows
1065 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1066 : 0);
1067 if (hl_row && hl_row->mode_line_p)
1068 height -= hl_row->height;
1069 else
1070 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1071 }
1072
1073 /* With a very small font and a mode-line that's taller than
1074 default, we might end up with a negative height. */
1075 return max (0, height);
1076 }
1077
1078 /* Return the window-relative coordinate of the left edge of display
1079 area AREA of window W. AREA < 0 means return the left edge of the
1080 whole window, to the right of the left fringe of W. */
1081
1082 INLINE int
1083 window_box_left_offset (w, area)
1084 struct window *w;
1085 int area;
1086 {
1087 int x;
1088
1089 if (w->pseudo_window_p)
1090 return 0;
1091
1092 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1093
1094 if (area == TEXT_AREA)
1095 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1096 + window_box_width (w, LEFT_MARGIN_AREA));
1097 else if (area == RIGHT_MARGIN_AREA)
1098 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1099 + window_box_width (w, LEFT_MARGIN_AREA)
1100 + window_box_width (w, TEXT_AREA)
1101 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1102 ? 0
1103 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1104 else if (area == LEFT_MARGIN_AREA
1105 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1106 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1107
1108 return x;
1109 }
1110
1111
1112 /* Return the window-relative coordinate of the right edge of display
1113 area AREA of window W. AREA < 0 means return the left edge of the
1114 whole window, to the left of the right fringe of W. */
1115
1116 INLINE int
1117 window_box_right_offset (w, area)
1118 struct window *w;
1119 int area;
1120 {
1121 return window_box_left_offset (w, area) + window_box_width (w, area);
1122 }
1123
1124 /* Return the frame-relative coordinate of the left edge of display
1125 area AREA of window W. AREA < 0 means return the left edge of the
1126 whole window, to the right of the left fringe of W. */
1127
1128 INLINE int
1129 window_box_left (w, area)
1130 struct window *w;
1131 int area;
1132 {
1133 struct frame *f = XFRAME (w->frame);
1134 int x;
1135
1136 if (w->pseudo_window_p)
1137 return FRAME_INTERNAL_BORDER_WIDTH (f);
1138
1139 x = (WINDOW_LEFT_EDGE_X (w)
1140 + window_box_left_offset (w, area));
1141
1142 return x;
1143 }
1144
1145
1146 /* Return the frame-relative coordinate of the right edge of display
1147 area AREA of window W. AREA < 0 means return the left edge of the
1148 whole window, to the left of the right fringe of W. */
1149
1150 INLINE int
1151 window_box_right (w, area)
1152 struct window *w;
1153 int area;
1154 {
1155 return window_box_left (w, area) + window_box_width (w, area);
1156 }
1157
1158 /* Get the bounding box of the display area AREA of window W, without
1159 mode lines, in frame-relative coordinates. AREA < 0 means the
1160 whole window, not including the left and right fringes of
1161 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1162 coordinates of the upper-left corner of the box. Return in
1163 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1164
1165 INLINE void
1166 window_box (w, area, box_x, box_y, box_width, box_height)
1167 struct window *w;
1168 int area;
1169 int *box_x, *box_y, *box_width, *box_height;
1170 {
1171 if (box_width)
1172 *box_width = window_box_width (w, area);
1173 if (box_height)
1174 *box_height = window_box_height (w);
1175 if (box_x)
1176 *box_x = window_box_left (w, area);
1177 if (box_y)
1178 {
1179 *box_y = WINDOW_TOP_EDGE_Y (w);
1180 if (WINDOW_WANTS_HEADER_LINE_P (w))
1181 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1182 }
1183 }
1184
1185
1186 /* Get the bounding box of the display area AREA of window W, without
1187 mode lines. AREA < 0 means the whole window, not including the
1188 left and right fringe of the window. Return in *TOP_LEFT_X
1189 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1190 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1191 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1192 box. */
1193
1194 INLINE void
1195 window_box_edges (w, area, top_left_x, top_left_y,
1196 bottom_right_x, bottom_right_y)
1197 struct window *w;
1198 int area;
1199 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1200 {
1201 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1202 bottom_right_y);
1203 *bottom_right_x += *top_left_x;
1204 *bottom_right_y += *top_left_y;
1205 }
1206
1207
1208 \f
1209 /***********************************************************************
1210 Utilities
1211 ***********************************************************************/
1212
1213 /* Return the bottom y-position of the line the iterator IT is in.
1214 This can modify IT's settings. */
1215
1216 int
1217 line_bottom_y (it)
1218 struct it *it;
1219 {
1220 int line_height = it->max_ascent + it->max_descent;
1221 int line_top_y = it->current_y;
1222
1223 if (line_height == 0)
1224 {
1225 if (last_height)
1226 line_height = last_height;
1227 else if (IT_CHARPOS (*it) < ZV)
1228 {
1229 move_it_by_lines (it, 1, 1);
1230 line_height = (it->max_ascent || it->max_descent
1231 ? it->max_ascent + it->max_descent
1232 : last_height);
1233 }
1234 else
1235 {
1236 struct glyph_row *row = it->glyph_row;
1237
1238 /* Use the default character height. */
1239 it->glyph_row = NULL;
1240 it->what = IT_CHARACTER;
1241 it->c = ' ';
1242 it->len = 1;
1243 PRODUCE_GLYPHS (it);
1244 line_height = it->ascent + it->descent;
1245 it->glyph_row = row;
1246 }
1247 }
1248
1249 return line_top_y + line_height;
1250 }
1251
1252
1253 /* Return 1 if position CHARPOS is visible in window W.
1254 If visible, set *X and *Y to pixel coordinates of top left corner.
1255 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1256 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1257 and header-lines heights. */
1258
1259 int
1260 pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1261 struct window *w;
1262 int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
1263 {
1264 struct it it;
1265 struct text_pos top;
1266 int visible_p = 0;
1267 struct buffer *old_buffer = NULL;
1268
1269 if (noninteractive)
1270 return visible_p;
1271
1272 if (XBUFFER (w->buffer) != current_buffer)
1273 {
1274 old_buffer = current_buffer;
1275 set_buffer_internal_1 (XBUFFER (w->buffer));
1276 }
1277
1278 SET_TEXT_POS_FROM_MARKER (top, w->start);
1279
1280 /* Compute exact mode line heights, if requested. */
1281 if (exact_mode_line_heights_p)
1282 {
1283 if (WINDOW_WANTS_MODELINE_P (w))
1284 current_mode_line_height
1285 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1286 current_buffer->mode_line_format);
1287
1288 if (WINDOW_WANTS_HEADER_LINE_P (w))
1289 current_header_line_height
1290 = display_mode_line (w, HEADER_LINE_FACE_ID,
1291 current_buffer->header_line_format);
1292 }
1293
1294 start_display (&it, w, top);
1295 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1296 MOVE_TO_POS | MOVE_TO_Y);
1297
1298 /* Note that we may overshoot because of invisible text. */
1299 if (IT_CHARPOS (it) >= charpos)
1300 {
1301 int top_x = it.current_x;
1302 int top_y = it.current_y;
1303 int bottom_y = (last_height = 0, line_bottom_y (&it));
1304 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1305
1306 if (top_y < window_top_y)
1307 visible_p = bottom_y > window_top_y;
1308 else if (top_y < it.last_visible_y)
1309 visible_p = 1;
1310 if (visible_p)
1311 {
1312 *x = top_x;
1313 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1314 *rtop = max (0, window_top_y - top_y);
1315 *rbot = max (0, bottom_y - it.last_visible_y);
1316 }
1317 }
1318 else
1319 {
1320 struct it it2;
1321
1322 it2 = it;
1323 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1324 move_it_by_lines (&it, 1, 0);
1325 if (charpos < IT_CHARPOS (it))
1326 {
1327 visible_p = 1;
1328 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1329 *x = it2.current_x;
1330 *y = it2.current_y + it2.max_ascent - it2.ascent;
1331 *rtop = max (0, -it2.current_y);
1332 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1333 - it.last_visible_y));
1334 }
1335 }
1336
1337 if (old_buffer)
1338 set_buffer_internal_1 (old_buffer);
1339
1340 current_header_line_height = current_mode_line_height = -1;
1341
1342 return visible_p;
1343 }
1344
1345
1346 /* Return the next character from STR which is MAXLEN bytes long.
1347 Return in *LEN the length of the character. This is like
1348 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1349 we find one, we return a `?', but with the length of the invalid
1350 character. */
1351
1352 static INLINE int
1353 string_char_and_length (str, maxlen, len)
1354 const unsigned char *str;
1355 int maxlen, *len;
1356 {
1357 int c;
1358
1359 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1360 if (!CHAR_VALID_P (c, 1))
1361 /* We may not change the length here because other places in Emacs
1362 don't use this function, i.e. they silently accept invalid
1363 characters. */
1364 c = '?';
1365
1366 return c;
1367 }
1368
1369
1370
1371 /* Given a position POS containing a valid character and byte position
1372 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1373
1374 static struct text_pos
1375 string_pos_nchars_ahead (pos, string, nchars)
1376 struct text_pos pos;
1377 Lisp_Object string;
1378 int nchars;
1379 {
1380 xassert (STRINGP (string) && nchars >= 0);
1381
1382 if (STRING_MULTIBYTE (string))
1383 {
1384 int rest = SBYTES (string) - BYTEPOS (pos);
1385 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1386 int len;
1387
1388 while (nchars--)
1389 {
1390 string_char_and_length (p, rest, &len);
1391 p += len, rest -= len;
1392 xassert (rest >= 0);
1393 CHARPOS (pos) += 1;
1394 BYTEPOS (pos) += len;
1395 }
1396 }
1397 else
1398 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1399
1400 return pos;
1401 }
1402
1403
1404 /* Value is the text position, i.e. character and byte position,
1405 for character position CHARPOS in STRING. */
1406
1407 static INLINE struct text_pos
1408 string_pos (charpos, string)
1409 int charpos;
1410 Lisp_Object string;
1411 {
1412 struct text_pos pos;
1413 xassert (STRINGP (string));
1414 xassert (charpos >= 0);
1415 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1416 return pos;
1417 }
1418
1419
1420 /* Value is a text position, i.e. character and byte position, for
1421 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1422 means recognize multibyte characters. */
1423
1424 static struct text_pos
1425 c_string_pos (charpos, s, multibyte_p)
1426 int charpos;
1427 unsigned char *s;
1428 int multibyte_p;
1429 {
1430 struct text_pos pos;
1431
1432 xassert (s != NULL);
1433 xassert (charpos >= 0);
1434
1435 if (multibyte_p)
1436 {
1437 int rest = strlen (s), len;
1438
1439 SET_TEXT_POS (pos, 0, 0);
1440 while (charpos--)
1441 {
1442 string_char_and_length (s, rest, &len);
1443 s += len, rest -= len;
1444 xassert (rest >= 0);
1445 CHARPOS (pos) += 1;
1446 BYTEPOS (pos) += len;
1447 }
1448 }
1449 else
1450 SET_TEXT_POS (pos, charpos, charpos);
1451
1452 return pos;
1453 }
1454
1455
1456 /* Value is the number of characters in C string S. MULTIBYTE_P
1457 non-zero means recognize multibyte characters. */
1458
1459 static int
1460 number_of_chars (s, multibyte_p)
1461 unsigned char *s;
1462 int multibyte_p;
1463 {
1464 int nchars;
1465
1466 if (multibyte_p)
1467 {
1468 int rest = strlen (s), len;
1469 unsigned char *p = (unsigned char *) s;
1470
1471 for (nchars = 0; rest > 0; ++nchars)
1472 {
1473 string_char_and_length (p, rest, &len);
1474 rest -= len, p += len;
1475 }
1476 }
1477 else
1478 nchars = strlen (s);
1479
1480 return nchars;
1481 }
1482
1483
1484 /* Compute byte position NEWPOS->bytepos corresponding to
1485 NEWPOS->charpos. POS is a known position in string STRING.
1486 NEWPOS->charpos must be >= POS.charpos. */
1487
1488 static void
1489 compute_string_pos (newpos, pos, string)
1490 struct text_pos *newpos, pos;
1491 Lisp_Object string;
1492 {
1493 xassert (STRINGP (string));
1494 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1495
1496 if (STRING_MULTIBYTE (string))
1497 *newpos = string_pos_nchars_ahead (pos, string,
1498 CHARPOS (*newpos) - CHARPOS (pos));
1499 else
1500 BYTEPOS (*newpos) = CHARPOS (*newpos);
1501 }
1502
1503 /* EXPORT:
1504 Return an estimation of the pixel height of mode or top lines on
1505 frame F. FACE_ID specifies what line's height to estimate. */
1506
1507 int
1508 estimate_mode_line_height (f, face_id)
1509 struct frame *f;
1510 enum face_id face_id;
1511 {
1512 #ifdef HAVE_WINDOW_SYSTEM
1513 if (FRAME_WINDOW_P (f))
1514 {
1515 int height = FONT_HEIGHT (FRAME_FONT (f));
1516
1517 /* This function is called so early when Emacs starts that the face
1518 cache and mode line face are not yet initialized. */
1519 if (FRAME_FACE_CACHE (f))
1520 {
1521 struct face *face = FACE_FROM_ID (f, face_id);
1522 if (face)
1523 {
1524 if (face->font)
1525 height = FONT_HEIGHT (face->font);
1526 if (face->box_line_width > 0)
1527 height += 2 * face->box_line_width;
1528 }
1529 }
1530
1531 return height;
1532 }
1533 #endif
1534
1535 return 1;
1536 }
1537
1538 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1539 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1540 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1541 not force the value into range. */
1542
1543 void
1544 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1545 FRAME_PTR f;
1546 register int pix_x, pix_y;
1547 int *x, *y;
1548 NativeRectangle *bounds;
1549 int noclip;
1550 {
1551
1552 #ifdef HAVE_WINDOW_SYSTEM
1553 if (FRAME_WINDOW_P (f))
1554 {
1555 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1556 even for negative values. */
1557 if (pix_x < 0)
1558 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1559 if (pix_y < 0)
1560 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1561
1562 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1563 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1564
1565 if (bounds)
1566 STORE_NATIVE_RECT (*bounds,
1567 FRAME_COL_TO_PIXEL_X (f, pix_x),
1568 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1569 FRAME_COLUMN_WIDTH (f) - 1,
1570 FRAME_LINE_HEIGHT (f) - 1);
1571
1572 if (!noclip)
1573 {
1574 if (pix_x < 0)
1575 pix_x = 0;
1576 else if (pix_x > FRAME_TOTAL_COLS (f))
1577 pix_x = FRAME_TOTAL_COLS (f);
1578
1579 if (pix_y < 0)
1580 pix_y = 0;
1581 else if (pix_y > FRAME_LINES (f))
1582 pix_y = FRAME_LINES (f);
1583 }
1584 }
1585 #endif
1586
1587 *x = pix_x;
1588 *y = pix_y;
1589 }
1590
1591
1592 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1593 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1594 can't tell the positions because W's display is not up to date,
1595 return 0. */
1596
1597 int
1598 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1599 struct window *w;
1600 int hpos, vpos;
1601 int *frame_x, *frame_y;
1602 {
1603 #ifdef HAVE_WINDOW_SYSTEM
1604 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1605 {
1606 int success_p;
1607
1608 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1609 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1610
1611 if (display_completed)
1612 {
1613 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1614 struct glyph *glyph = row->glyphs[TEXT_AREA];
1615 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1616
1617 hpos = row->x;
1618 vpos = row->y;
1619 while (glyph < end)
1620 {
1621 hpos += glyph->pixel_width;
1622 ++glyph;
1623 }
1624
1625 /* If first glyph is partially visible, its first visible position is still 0. */
1626 if (hpos < 0)
1627 hpos = 0;
1628
1629 success_p = 1;
1630 }
1631 else
1632 {
1633 hpos = vpos = 0;
1634 success_p = 0;
1635 }
1636
1637 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1638 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1639 return success_p;
1640 }
1641 #endif
1642
1643 *frame_x = hpos;
1644 *frame_y = vpos;
1645 return 1;
1646 }
1647
1648
1649 #ifdef HAVE_WINDOW_SYSTEM
1650
1651 /* Find the glyph under window-relative coordinates X/Y in window W.
1652 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1653 strings. Return in *HPOS and *VPOS the row and column number of
1654 the glyph found. Return in *AREA the glyph area containing X.
1655 Value is a pointer to the glyph found or null if X/Y is not on
1656 text, or we can't tell because W's current matrix is not up to
1657 date. */
1658
1659 static struct glyph *
1660 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1661 struct window *w;
1662 int x, y;
1663 int *hpos, *vpos, *dx, *dy, *area;
1664 {
1665 struct glyph *glyph, *end;
1666 struct glyph_row *row = NULL;
1667 int x0, i;
1668
1669 /* Find row containing Y. Give up if some row is not enabled. */
1670 for (i = 0; i < w->current_matrix->nrows; ++i)
1671 {
1672 row = MATRIX_ROW (w->current_matrix, i);
1673 if (!row->enabled_p)
1674 return NULL;
1675 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1676 break;
1677 }
1678
1679 *vpos = i;
1680 *hpos = 0;
1681
1682 /* Give up if Y is not in the window. */
1683 if (i == w->current_matrix->nrows)
1684 return NULL;
1685
1686 /* Get the glyph area containing X. */
1687 if (w->pseudo_window_p)
1688 {
1689 *area = TEXT_AREA;
1690 x0 = 0;
1691 }
1692 else
1693 {
1694 if (x < window_box_left_offset (w, TEXT_AREA))
1695 {
1696 *area = LEFT_MARGIN_AREA;
1697 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1698 }
1699 else if (x < window_box_right_offset (w, TEXT_AREA))
1700 {
1701 *area = TEXT_AREA;
1702 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1703 }
1704 else
1705 {
1706 *area = RIGHT_MARGIN_AREA;
1707 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1708 }
1709 }
1710
1711 /* Find glyph containing X. */
1712 glyph = row->glyphs[*area];
1713 end = glyph + row->used[*area];
1714 x -= x0;
1715 while (glyph < end && x >= glyph->pixel_width)
1716 {
1717 x -= glyph->pixel_width;
1718 ++glyph;
1719 }
1720
1721 if (glyph == end)
1722 return NULL;
1723
1724 if (dx)
1725 {
1726 *dx = x;
1727 *dy = y - (row->y + row->ascent - glyph->ascent);
1728 }
1729
1730 *hpos = glyph - row->glyphs[*area];
1731 return glyph;
1732 }
1733
1734
1735 /* EXPORT:
1736 Convert frame-relative x/y to coordinates relative to window W.
1737 Takes pseudo-windows into account. */
1738
1739 void
1740 frame_to_window_pixel_xy (w, x, y)
1741 struct window *w;
1742 int *x, *y;
1743 {
1744 if (w->pseudo_window_p)
1745 {
1746 /* A pseudo-window is always full-width, and starts at the
1747 left edge of the frame, plus a frame border. */
1748 struct frame *f = XFRAME (w->frame);
1749 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1750 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1751 }
1752 else
1753 {
1754 *x -= WINDOW_LEFT_EDGE_X (w);
1755 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1756 }
1757 }
1758
1759 /* EXPORT:
1760 Return in *R the clipping rectangle for glyph string S. */
1761
1762 void
1763 get_glyph_string_clip_rect (s, nr)
1764 struct glyph_string *s;
1765 NativeRectangle *nr;
1766 {
1767 XRectangle r;
1768
1769 if (s->row->full_width_p)
1770 {
1771 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1772 r.x = WINDOW_LEFT_EDGE_X (s->w);
1773 r.width = WINDOW_TOTAL_WIDTH (s->w);
1774
1775 /* Unless displaying a mode or menu bar line, which are always
1776 fully visible, clip to the visible part of the row. */
1777 if (s->w->pseudo_window_p)
1778 r.height = s->row->visible_height;
1779 else
1780 r.height = s->height;
1781 }
1782 else
1783 {
1784 /* This is a text line that may be partially visible. */
1785 r.x = window_box_left (s->w, s->area);
1786 r.width = window_box_width (s->w, s->area);
1787 r.height = s->row->visible_height;
1788 }
1789
1790 if (s->clip_head)
1791 if (r.x < s->clip_head->x)
1792 {
1793 if (r.width >= s->clip_head->x - r.x)
1794 r.width -= s->clip_head->x - r.x;
1795 else
1796 r.width = 0;
1797 r.x = s->clip_head->x;
1798 }
1799 if (s->clip_tail)
1800 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1801 {
1802 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1803 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1804 else
1805 r.width = 0;
1806 }
1807
1808 /* If S draws overlapping rows, it's sufficient to use the top and
1809 bottom of the window for clipping because this glyph string
1810 intentionally draws over other lines. */
1811 if (s->for_overlaps_p)
1812 {
1813 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1814 r.height = window_text_bottom_y (s->w) - r.y;
1815 }
1816 else
1817 {
1818 /* Don't use S->y for clipping because it doesn't take partially
1819 visible lines into account. For example, it can be negative for
1820 partially visible lines at the top of a window. */
1821 if (!s->row->full_width_p
1822 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1823 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1824 else
1825 r.y = max (0, s->row->y);
1826
1827 /* If drawing a tool-bar window, draw it over the internal border
1828 at the top of the window. */
1829 if (WINDOWP (s->f->tool_bar_window)
1830 && s->w == XWINDOW (s->f->tool_bar_window))
1831 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1832 }
1833
1834 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1835
1836 /* If drawing the cursor, don't let glyph draw outside its
1837 advertised boundaries. Cleartype does this under some circumstances. */
1838 if (s->hl == DRAW_CURSOR)
1839 {
1840 struct glyph *glyph = s->first_glyph;
1841 int height, max_y;
1842
1843 if (s->x > r.x)
1844 {
1845 r.width -= s->x - r.x;
1846 r.x = s->x;
1847 }
1848 r.width = min (r.width, glyph->pixel_width);
1849
1850 /* If r.y is below window bottom, ensure that we still see a cursor. */
1851 height = min (glyph->ascent + glyph->descent,
1852 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1853 max_y = window_text_bottom_y (s->w) - height;
1854 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1855 if (s->ybase - glyph->ascent > max_y)
1856 {
1857 r.y = max_y;
1858 r.height = height;
1859 }
1860 else
1861 {
1862 /* Don't draw cursor glyph taller than our actual glyph. */
1863 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1864 if (height < r.height)
1865 {
1866 max_y = r.y + r.height;
1867 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1868 r.height = min (max_y - r.y, height);
1869 }
1870 }
1871 }
1872
1873 #ifdef CONVERT_FROM_XRECT
1874 CONVERT_FROM_XRECT (r, *nr);
1875 #else
1876 *nr = r;
1877 #endif
1878 }
1879
1880
1881 /* EXPORT:
1882 Return the position and height of the phys cursor in window W.
1883 Set w->phys_cursor_width to width of phys cursor.
1884 */
1885
1886 int
1887 get_phys_cursor_geometry (w, row, glyph, heightp)
1888 struct window *w;
1889 struct glyph_row *row;
1890 struct glyph *glyph;
1891 int *heightp;
1892 {
1893 struct frame *f = XFRAME (WINDOW_FRAME (w));
1894 int x, y, wd, h, h0, y0;
1895
1896 /* Compute the width of the rectangle to draw. If on a stretch
1897 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1898 rectangle as wide as the glyph, but use a canonical character
1899 width instead. */
1900 wd = glyph->pixel_width - 1;
1901 #ifdef HAVE_NTGUI
1902 wd++; /* Why? */
1903 #endif
1904 if (glyph->type == STRETCH_GLYPH
1905 && !x_stretch_cursor_p)
1906 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1907 w->phys_cursor_width = wd;
1908
1909 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1910
1911 /* If y is below window bottom, ensure that we still see a cursor. */
1912 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1913
1914 h = max (h0, glyph->ascent + glyph->descent);
1915 h0 = min (h0, glyph->ascent + glyph->descent);
1916
1917 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1918 if (y < y0)
1919 {
1920 h = max (h - (y0 - y) + 1, h0);
1921 y = y0 - 1;
1922 }
1923 else
1924 {
1925 y0 = window_text_bottom_y (w) - h0;
1926 if (y > y0)
1927 {
1928 h += y - y0;
1929 y = y0;
1930 }
1931 }
1932
1933 *heightp = h - 1;
1934 return WINDOW_TO_FRAME_PIXEL_Y (w, y);
1935 }
1936
1937
1938 #endif /* HAVE_WINDOW_SYSTEM */
1939
1940 \f
1941 /***********************************************************************
1942 Lisp form evaluation
1943 ***********************************************************************/
1944
1945 /* Error handler for safe_eval and safe_call. */
1946
1947 static Lisp_Object
1948 safe_eval_handler (arg)
1949 Lisp_Object arg;
1950 {
1951 add_to_log ("Error during redisplay: %s", arg, Qnil);
1952 return Qnil;
1953 }
1954
1955
1956 /* Evaluate SEXPR and return the result, or nil if something went
1957 wrong. Prevent redisplay during the evaluation. */
1958
1959 Lisp_Object
1960 safe_eval (sexpr)
1961 Lisp_Object sexpr;
1962 {
1963 Lisp_Object val;
1964
1965 if (inhibit_eval_during_redisplay)
1966 val = Qnil;
1967 else
1968 {
1969 int count = SPECPDL_INDEX ();
1970 struct gcpro gcpro1;
1971
1972 GCPRO1 (sexpr);
1973 specbind (Qinhibit_redisplay, Qt);
1974 /* Use Qt to ensure debugger does not run,
1975 so there is no possibility of wanting to redisplay. */
1976 val = internal_condition_case_1 (Feval, sexpr, Qt,
1977 safe_eval_handler);
1978 UNGCPRO;
1979 val = unbind_to (count, val);
1980 }
1981
1982 return val;
1983 }
1984
1985
1986 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1987 Return the result, or nil if something went wrong. Prevent
1988 redisplay during the evaluation. */
1989
1990 Lisp_Object
1991 safe_call (nargs, args)
1992 int nargs;
1993 Lisp_Object *args;
1994 {
1995 Lisp_Object val;
1996
1997 if (inhibit_eval_during_redisplay)
1998 val = Qnil;
1999 else
2000 {
2001 int count = SPECPDL_INDEX ();
2002 struct gcpro gcpro1;
2003
2004 GCPRO1 (args[0]);
2005 gcpro1.nvars = nargs;
2006 specbind (Qinhibit_redisplay, Qt);
2007 /* Use Qt to ensure debugger does not run,
2008 so there is no possibility of wanting to redisplay. */
2009 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2010 safe_eval_handler);
2011 UNGCPRO;
2012 val = unbind_to (count, val);
2013 }
2014
2015 return val;
2016 }
2017
2018
2019 /* Call function FN with one argument ARG.
2020 Return the result, or nil if something went wrong. */
2021
2022 Lisp_Object
2023 safe_call1 (fn, arg)
2024 Lisp_Object fn, arg;
2025 {
2026 Lisp_Object args[2];
2027 args[0] = fn;
2028 args[1] = arg;
2029 return safe_call (2, args);
2030 }
2031
2032
2033 \f
2034 /***********************************************************************
2035 Debugging
2036 ***********************************************************************/
2037
2038 #if 0
2039
2040 /* Define CHECK_IT to perform sanity checks on iterators.
2041 This is for debugging. It is too slow to do unconditionally. */
2042
2043 static void
2044 check_it (it)
2045 struct it *it;
2046 {
2047 if (it->method == GET_FROM_STRING)
2048 {
2049 xassert (STRINGP (it->string));
2050 xassert (IT_STRING_CHARPOS (*it) >= 0);
2051 }
2052 else
2053 {
2054 xassert (IT_STRING_CHARPOS (*it) < 0);
2055 if (it->method == GET_FROM_BUFFER)
2056 {
2057 /* Check that character and byte positions agree. */
2058 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2059 }
2060 }
2061
2062 if (it->dpvec)
2063 xassert (it->current.dpvec_index >= 0);
2064 else
2065 xassert (it->current.dpvec_index < 0);
2066 }
2067
2068 #define CHECK_IT(IT) check_it ((IT))
2069
2070 #else /* not 0 */
2071
2072 #define CHECK_IT(IT) (void) 0
2073
2074 #endif /* not 0 */
2075
2076
2077 #if GLYPH_DEBUG
2078
2079 /* Check that the window end of window W is what we expect it
2080 to be---the last row in the current matrix displaying text. */
2081
2082 static void
2083 check_window_end (w)
2084 struct window *w;
2085 {
2086 if (!MINI_WINDOW_P (w)
2087 && !NILP (w->window_end_valid))
2088 {
2089 struct glyph_row *row;
2090 xassert ((row = MATRIX_ROW (w->current_matrix,
2091 XFASTINT (w->window_end_vpos)),
2092 !row->enabled_p
2093 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2094 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2095 }
2096 }
2097
2098 #define CHECK_WINDOW_END(W) check_window_end ((W))
2099
2100 #else /* not GLYPH_DEBUG */
2101
2102 #define CHECK_WINDOW_END(W) (void) 0
2103
2104 #endif /* not GLYPH_DEBUG */
2105
2106
2107 \f
2108 /***********************************************************************
2109 Iterator initialization
2110 ***********************************************************************/
2111
2112 /* Initialize IT for displaying current_buffer in window W, starting
2113 at character position CHARPOS. CHARPOS < 0 means that no buffer
2114 position is specified which is useful when the iterator is assigned
2115 a position later. BYTEPOS is the byte position corresponding to
2116 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2117
2118 If ROW is not null, calls to produce_glyphs with IT as parameter
2119 will produce glyphs in that row.
2120
2121 BASE_FACE_ID is the id of a base face to use. It must be one of
2122 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2123 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2124 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2125
2126 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2127 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2128 will be initialized to use the corresponding mode line glyph row of
2129 the desired matrix of W. */
2130
2131 void
2132 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2133 struct it *it;
2134 struct window *w;
2135 int charpos, bytepos;
2136 struct glyph_row *row;
2137 enum face_id base_face_id;
2138 {
2139 int highlight_region_p;
2140
2141 /* Some precondition checks. */
2142 xassert (w != NULL && it != NULL);
2143 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2144 && charpos <= ZV));
2145
2146 /* If face attributes have been changed since the last redisplay,
2147 free realized faces now because they depend on face definitions
2148 that might have changed. Don't free faces while there might be
2149 desired matrices pending which reference these faces. */
2150 if (face_change_count && !inhibit_free_realized_faces)
2151 {
2152 face_change_count = 0;
2153 free_all_realized_faces (Qnil);
2154 }
2155
2156 /* Use one of the mode line rows of W's desired matrix if
2157 appropriate. */
2158 if (row == NULL)
2159 {
2160 if (base_face_id == MODE_LINE_FACE_ID
2161 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2162 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2163 else if (base_face_id == HEADER_LINE_FACE_ID)
2164 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2165 }
2166
2167 /* Clear IT. */
2168 bzero (it, sizeof *it);
2169 it->current.overlay_string_index = -1;
2170 it->current.dpvec_index = -1;
2171 it->base_face_id = base_face_id;
2172 it->string = Qnil;
2173 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2174
2175 /* The window in which we iterate over current_buffer: */
2176 XSETWINDOW (it->window, w);
2177 it->w = w;
2178 it->f = XFRAME (w->frame);
2179
2180 /* Extra space between lines (on window systems only). */
2181 if (base_face_id == DEFAULT_FACE_ID
2182 && FRAME_WINDOW_P (it->f))
2183 {
2184 if (NATNUMP (current_buffer->extra_line_spacing))
2185 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2186 else if (FLOATP (current_buffer->extra_line_spacing))
2187 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2188 * FRAME_LINE_HEIGHT (it->f));
2189 else if (it->f->extra_line_spacing > 0)
2190 it->extra_line_spacing = it->f->extra_line_spacing;
2191 it->max_extra_line_spacing = 0;
2192 }
2193
2194 /* If realized faces have been removed, e.g. because of face
2195 attribute changes of named faces, recompute them. When running
2196 in batch mode, the face cache of Vterminal_frame is null. If
2197 we happen to get called, make a dummy face cache. */
2198 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2199 init_frame_faces (it->f);
2200 if (FRAME_FACE_CACHE (it->f)->used == 0)
2201 recompute_basic_faces (it->f);
2202
2203 /* Current value of the `slice', `space-width', and 'height' properties. */
2204 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2205 it->space_width = Qnil;
2206 it->font_height = Qnil;
2207 it->override_ascent = -1;
2208
2209 /* Are control characters displayed as `^C'? */
2210 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2211
2212 /* -1 means everything between a CR and the following line end
2213 is invisible. >0 means lines indented more than this value are
2214 invisible. */
2215 it->selective = (INTEGERP (current_buffer->selective_display)
2216 ? XFASTINT (current_buffer->selective_display)
2217 : (!NILP (current_buffer->selective_display)
2218 ? -1 : 0));
2219 it->selective_display_ellipsis_p
2220 = !NILP (current_buffer->selective_display_ellipses);
2221
2222 /* Display table to use. */
2223 it->dp = window_display_table (w);
2224
2225 /* Are multibyte characters enabled in current_buffer? */
2226 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2227
2228 /* Non-zero if we should highlight the region. */
2229 highlight_region_p
2230 = (!NILP (Vtransient_mark_mode)
2231 && !NILP (current_buffer->mark_active)
2232 && XMARKER (current_buffer->mark)->buffer != 0);
2233
2234 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2235 start and end of a visible region in window IT->w. Set both to
2236 -1 to indicate no region. */
2237 if (highlight_region_p
2238 /* Maybe highlight only in selected window. */
2239 && (/* Either show region everywhere. */
2240 highlight_nonselected_windows
2241 /* Or show region in the selected window. */
2242 || w == XWINDOW (selected_window)
2243 /* Or show the region if we are in the mini-buffer and W is
2244 the window the mini-buffer refers to. */
2245 || (MINI_WINDOW_P (XWINDOW (selected_window))
2246 && WINDOWP (minibuf_selected_window)
2247 && w == XWINDOW (minibuf_selected_window))))
2248 {
2249 int charpos = marker_position (current_buffer->mark);
2250 it->region_beg_charpos = min (PT, charpos);
2251 it->region_end_charpos = max (PT, charpos);
2252 }
2253 else
2254 it->region_beg_charpos = it->region_end_charpos = -1;
2255
2256 /* Get the position at which the redisplay_end_trigger hook should
2257 be run, if it is to be run at all. */
2258 if (MARKERP (w->redisplay_end_trigger)
2259 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2260 it->redisplay_end_trigger_charpos
2261 = marker_position (w->redisplay_end_trigger);
2262 else if (INTEGERP (w->redisplay_end_trigger))
2263 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2264
2265 /* Correct bogus values of tab_width. */
2266 it->tab_width = XINT (current_buffer->tab_width);
2267 if (it->tab_width <= 0 || it->tab_width > 1000)
2268 it->tab_width = 8;
2269
2270 /* Are lines in the display truncated? */
2271 it->truncate_lines_p
2272 = (base_face_id != DEFAULT_FACE_ID
2273 || XINT (it->w->hscroll)
2274 || (truncate_partial_width_windows
2275 && !WINDOW_FULL_WIDTH_P (it->w))
2276 || !NILP (current_buffer->truncate_lines));
2277
2278 /* Get dimensions of truncation and continuation glyphs. These are
2279 displayed as fringe bitmaps under X, so we don't need them for such
2280 frames. */
2281 if (!FRAME_WINDOW_P (it->f))
2282 {
2283 if (it->truncate_lines_p)
2284 {
2285 /* We will need the truncation glyph. */
2286 xassert (it->glyph_row == NULL);
2287 produce_special_glyphs (it, IT_TRUNCATION);
2288 it->truncation_pixel_width = it->pixel_width;
2289 }
2290 else
2291 {
2292 /* We will need the continuation glyph. */
2293 xassert (it->glyph_row == NULL);
2294 produce_special_glyphs (it, IT_CONTINUATION);
2295 it->continuation_pixel_width = it->pixel_width;
2296 }
2297
2298 /* Reset these values to zero because the produce_special_glyphs
2299 above has changed them. */
2300 it->pixel_width = it->ascent = it->descent = 0;
2301 it->phys_ascent = it->phys_descent = 0;
2302 }
2303
2304 /* Set this after getting the dimensions of truncation and
2305 continuation glyphs, so that we don't produce glyphs when calling
2306 produce_special_glyphs, above. */
2307 it->glyph_row = row;
2308 it->area = TEXT_AREA;
2309
2310 /* Get the dimensions of the display area. The display area
2311 consists of the visible window area plus a horizontally scrolled
2312 part to the left of the window. All x-values are relative to the
2313 start of this total display area. */
2314 if (base_face_id != DEFAULT_FACE_ID)
2315 {
2316 /* Mode lines, menu bar in terminal frames. */
2317 it->first_visible_x = 0;
2318 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2319 }
2320 else
2321 {
2322 it->first_visible_x
2323 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2324 it->last_visible_x = (it->first_visible_x
2325 + window_box_width (w, TEXT_AREA));
2326
2327 /* If we truncate lines, leave room for the truncator glyph(s) at
2328 the right margin. Otherwise, leave room for the continuation
2329 glyph(s). Truncation and continuation glyphs are not inserted
2330 for window-based redisplay. */
2331 if (!FRAME_WINDOW_P (it->f))
2332 {
2333 if (it->truncate_lines_p)
2334 it->last_visible_x -= it->truncation_pixel_width;
2335 else
2336 it->last_visible_x -= it->continuation_pixel_width;
2337 }
2338
2339 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2340 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2341 }
2342
2343 /* Leave room for a border glyph. */
2344 if (!FRAME_WINDOW_P (it->f)
2345 && !WINDOW_RIGHTMOST_P (it->w))
2346 it->last_visible_x -= 1;
2347
2348 it->last_visible_y = window_text_bottom_y (w);
2349
2350 /* For mode lines and alike, arrange for the first glyph having a
2351 left box line if the face specifies a box. */
2352 if (base_face_id != DEFAULT_FACE_ID)
2353 {
2354 struct face *face;
2355
2356 it->face_id = base_face_id;
2357
2358 /* If we have a boxed mode line, make the first character appear
2359 with a left box line. */
2360 face = FACE_FROM_ID (it->f, base_face_id);
2361 if (face->box != FACE_NO_BOX)
2362 it->start_of_box_run_p = 1;
2363 }
2364
2365 /* If a buffer position was specified, set the iterator there,
2366 getting overlays and face properties from that position. */
2367 if (charpos >= BUF_BEG (current_buffer))
2368 {
2369 it->end_charpos = ZV;
2370 it->face_id = -1;
2371 IT_CHARPOS (*it) = charpos;
2372
2373 /* Compute byte position if not specified. */
2374 if (bytepos < charpos)
2375 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2376 else
2377 IT_BYTEPOS (*it) = bytepos;
2378
2379 it->start = it->current;
2380
2381 /* Compute faces etc. */
2382 reseat (it, it->current.pos, 1);
2383 }
2384
2385 CHECK_IT (it);
2386 }
2387
2388
2389 /* Initialize IT for the display of window W with window start POS. */
2390
2391 void
2392 start_display (it, w, pos)
2393 struct it *it;
2394 struct window *w;
2395 struct text_pos pos;
2396 {
2397 struct glyph_row *row;
2398 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2399
2400 row = w->desired_matrix->rows + first_vpos;
2401 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2402 it->first_vpos = first_vpos;
2403
2404 if (!it->truncate_lines_p)
2405 {
2406 int start_at_line_beg_p;
2407 int first_y = it->current_y;
2408
2409 /* If window start is not at a line start, skip forward to POS to
2410 get the correct continuation lines width. */
2411 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2412 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2413 if (!start_at_line_beg_p)
2414 {
2415 int new_x;
2416
2417 reseat_at_previous_visible_line_start (it);
2418 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2419
2420 new_x = it->current_x + it->pixel_width;
2421
2422 /* If lines are continued, this line may end in the middle
2423 of a multi-glyph character (e.g. a control character
2424 displayed as \003, or in the middle of an overlay
2425 string). In this case move_it_to above will not have
2426 taken us to the start of the continuation line but to the
2427 end of the continued line. */
2428 if (it->current_x > 0
2429 && !it->truncate_lines_p /* Lines are continued. */
2430 && (/* And glyph doesn't fit on the line. */
2431 new_x > it->last_visible_x
2432 /* Or it fits exactly and we're on a window
2433 system frame. */
2434 || (new_x == it->last_visible_x
2435 && FRAME_WINDOW_P (it->f))))
2436 {
2437 if (it->current.dpvec_index >= 0
2438 || it->current.overlay_string_index >= 0)
2439 {
2440 set_iterator_to_next (it, 1);
2441 move_it_in_display_line_to (it, -1, -1, 0);
2442 }
2443
2444 it->continuation_lines_width += it->current_x;
2445 }
2446
2447 /* We're starting a new display line, not affected by the
2448 height of the continued line, so clear the appropriate
2449 fields in the iterator structure. */
2450 it->max_ascent = it->max_descent = 0;
2451 it->max_phys_ascent = it->max_phys_descent = 0;
2452
2453 it->current_y = first_y;
2454 it->vpos = 0;
2455 it->current_x = it->hpos = 0;
2456 }
2457 }
2458
2459 #if 0 /* Don't assert the following because start_display is sometimes
2460 called intentionally with a window start that is not at a
2461 line start. Please leave this code in as a comment. */
2462
2463 /* Window start should be on a line start, now. */
2464 xassert (it->continuation_lines_width
2465 || IT_CHARPOS (it) == BEGV
2466 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2467 #endif /* 0 */
2468 }
2469
2470
2471 /* Return 1 if POS is a position in ellipses displayed for invisible
2472 text. W is the window we display, for text property lookup. */
2473
2474 static int
2475 in_ellipses_for_invisible_text_p (pos, w)
2476 struct display_pos *pos;
2477 struct window *w;
2478 {
2479 Lisp_Object prop, window;
2480 int ellipses_p = 0;
2481 int charpos = CHARPOS (pos->pos);
2482
2483 /* If POS specifies a position in a display vector, this might
2484 be for an ellipsis displayed for invisible text. We won't
2485 get the iterator set up for delivering that ellipsis unless
2486 we make sure that it gets aware of the invisible text. */
2487 if (pos->dpvec_index >= 0
2488 && pos->overlay_string_index < 0
2489 && CHARPOS (pos->string_pos) < 0
2490 && charpos > BEGV
2491 && (XSETWINDOW (window, w),
2492 prop = Fget_char_property (make_number (charpos),
2493 Qinvisible, window),
2494 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2495 {
2496 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2497 window);
2498 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2499 }
2500
2501 return ellipses_p;
2502 }
2503
2504
2505 /* Initialize IT for stepping through current_buffer in window W,
2506 starting at position POS that includes overlay string and display
2507 vector/ control character translation position information. Value
2508 is zero if there are overlay strings with newlines at POS. */
2509
2510 static int
2511 init_from_display_pos (it, w, pos)
2512 struct it *it;
2513 struct window *w;
2514 struct display_pos *pos;
2515 {
2516 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2517 int i, overlay_strings_with_newlines = 0;
2518
2519 /* If POS specifies a position in a display vector, this might
2520 be for an ellipsis displayed for invisible text. We won't
2521 get the iterator set up for delivering that ellipsis unless
2522 we make sure that it gets aware of the invisible text. */
2523 if (in_ellipses_for_invisible_text_p (pos, w))
2524 {
2525 --charpos;
2526 bytepos = 0;
2527 }
2528
2529 /* Keep in mind: the call to reseat in init_iterator skips invisible
2530 text, so we might end up at a position different from POS. This
2531 is only a problem when POS is a row start after a newline and an
2532 overlay starts there with an after-string, and the overlay has an
2533 invisible property. Since we don't skip invisible text in
2534 display_line and elsewhere immediately after consuming the
2535 newline before the row start, such a POS will not be in a string,
2536 but the call to init_iterator below will move us to the
2537 after-string. */
2538 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2539
2540 /* This only scans the current chunk -- it should scan all chunks.
2541 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2542 to 16 in 22.1 to make this a lesser problem. */
2543 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2544 {
2545 const char *s = SDATA (it->overlay_strings[i]);
2546 const char *e = s + SBYTES (it->overlay_strings[i]);
2547
2548 while (s < e && *s != '\n')
2549 ++s;
2550
2551 if (s < e)
2552 {
2553 overlay_strings_with_newlines = 1;
2554 break;
2555 }
2556 }
2557
2558 /* If position is within an overlay string, set up IT to the right
2559 overlay string. */
2560 if (pos->overlay_string_index >= 0)
2561 {
2562 int relative_index;
2563
2564 /* If the first overlay string happens to have a `display'
2565 property for an image, the iterator will be set up for that
2566 image, and we have to undo that setup first before we can
2567 correct the overlay string index. */
2568 if (it->method == GET_FROM_IMAGE)
2569 pop_it (it);
2570
2571 /* We already have the first chunk of overlay strings in
2572 IT->overlay_strings. Load more until the one for
2573 pos->overlay_string_index is in IT->overlay_strings. */
2574 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2575 {
2576 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2577 it->current.overlay_string_index = 0;
2578 while (n--)
2579 {
2580 load_overlay_strings (it, 0);
2581 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2582 }
2583 }
2584
2585 it->current.overlay_string_index = pos->overlay_string_index;
2586 relative_index = (it->current.overlay_string_index
2587 % OVERLAY_STRING_CHUNK_SIZE);
2588 it->string = it->overlay_strings[relative_index];
2589 xassert (STRINGP (it->string));
2590 it->current.string_pos = pos->string_pos;
2591 it->method = GET_FROM_STRING;
2592 }
2593
2594 #if 0 /* This is bogus because POS not having an overlay string
2595 position does not mean it's after the string. Example: A
2596 line starting with a before-string and initialization of IT
2597 to the previous row's end position. */
2598 else if (it->current.overlay_string_index >= 0)
2599 {
2600 /* If POS says we're already after an overlay string ending at
2601 POS, make sure to pop the iterator because it will be in
2602 front of that overlay string. When POS is ZV, we've thereby
2603 also ``processed'' overlay strings at ZV. */
2604 while (it->sp)
2605 pop_it (it);
2606 it->current.overlay_string_index = -1;
2607 it->method = GET_FROM_BUFFER;
2608 if (CHARPOS (pos->pos) == ZV)
2609 it->overlay_strings_at_end_processed_p = 1;
2610 }
2611 #endif /* 0 */
2612
2613 if (CHARPOS (pos->string_pos) >= 0)
2614 {
2615 /* Recorded position is not in an overlay string, but in another
2616 string. This can only be a string from a `display' property.
2617 IT should already be filled with that string. */
2618 it->current.string_pos = pos->string_pos;
2619 xassert (STRINGP (it->string));
2620 }
2621
2622 /* Restore position in display vector translations, control
2623 character translations or ellipses. */
2624 if (pos->dpvec_index >= 0)
2625 {
2626 if (it->dpvec == NULL)
2627 get_next_display_element (it);
2628 xassert (it->dpvec && it->current.dpvec_index == 0);
2629 it->current.dpvec_index = pos->dpvec_index;
2630 }
2631
2632 CHECK_IT (it);
2633 return !overlay_strings_with_newlines;
2634 }
2635
2636
2637 /* Initialize IT for stepping through current_buffer in window W
2638 starting at ROW->start. */
2639
2640 static void
2641 init_to_row_start (it, w, row)
2642 struct it *it;
2643 struct window *w;
2644 struct glyph_row *row;
2645 {
2646 init_from_display_pos (it, w, &row->start);
2647 it->start = row->start;
2648 it->continuation_lines_width = row->continuation_lines_width;
2649 CHECK_IT (it);
2650 }
2651
2652
2653 /* Initialize IT for stepping through current_buffer in window W
2654 starting in the line following ROW, i.e. starting at ROW->end.
2655 Value is zero if there are overlay strings with newlines at ROW's
2656 end position. */
2657
2658 static int
2659 init_to_row_end (it, w, row)
2660 struct it *it;
2661 struct window *w;
2662 struct glyph_row *row;
2663 {
2664 int success = 0;
2665
2666 if (init_from_display_pos (it, w, &row->end))
2667 {
2668 if (row->continued_p)
2669 it->continuation_lines_width
2670 = row->continuation_lines_width + row->pixel_width;
2671 CHECK_IT (it);
2672 success = 1;
2673 }
2674
2675 return success;
2676 }
2677
2678
2679
2680 \f
2681 /***********************************************************************
2682 Text properties
2683 ***********************************************************************/
2684
2685 /* Called when IT reaches IT->stop_charpos. Handle text property and
2686 overlay changes. Set IT->stop_charpos to the next position where
2687 to stop. */
2688
2689 static void
2690 handle_stop (it)
2691 struct it *it;
2692 {
2693 enum prop_handled handled;
2694 int handle_overlay_change_p = 1;
2695 struct props *p;
2696
2697 it->dpvec = NULL;
2698 it->current.dpvec_index = -1;
2699
2700 do
2701 {
2702 handled = HANDLED_NORMALLY;
2703
2704 /* Call text property handlers. */
2705 for (p = it_props; p->handler; ++p)
2706 {
2707 handled = p->handler (it);
2708
2709 if (handled == HANDLED_RECOMPUTE_PROPS)
2710 break;
2711 else if (handled == HANDLED_RETURN)
2712 return;
2713 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2714 handle_overlay_change_p = 0;
2715 }
2716
2717 if (handled != HANDLED_RECOMPUTE_PROPS)
2718 {
2719 /* Don't check for overlay strings below when set to deliver
2720 characters from a display vector. */
2721 if (it->method == GET_FROM_DISPLAY_VECTOR)
2722 handle_overlay_change_p = 0;
2723
2724 /* Handle overlay changes. */
2725 if (handle_overlay_change_p)
2726 handled = handle_overlay_change (it);
2727
2728 /* Determine where to stop next. */
2729 if (handled == HANDLED_NORMALLY)
2730 compute_stop_pos (it);
2731 }
2732 }
2733 while (handled == HANDLED_RECOMPUTE_PROPS);
2734 }
2735
2736
2737 /* Compute IT->stop_charpos from text property and overlay change
2738 information for IT's current position. */
2739
2740 static void
2741 compute_stop_pos (it)
2742 struct it *it;
2743 {
2744 register INTERVAL iv, next_iv;
2745 Lisp_Object object, limit, position;
2746
2747 /* If nowhere else, stop at the end. */
2748 it->stop_charpos = it->end_charpos;
2749
2750 if (STRINGP (it->string))
2751 {
2752 /* Strings are usually short, so don't limit the search for
2753 properties. */
2754 object = it->string;
2755 limit = Qnil;
2756 position = make_number (IT_STRING_CHARPOS (*it));
2757 }
2758 else
2759 {
2760 int charpos;
2761
2762 /* If next overlay change is in front of the current stop pos
2763 (which is IT->end_charpos), stop there. Note: value of
2764 next_overlay_change is point-max if no overlay change
2765 follows. */
2766 charpos = next_overlay_change (IT_CHARPOS (*it));
2767 if (charpos < it->stop_charpos)
2768 it->stop_charpos = charpos;
2769
2770 /* If showing the region, we have to stop at the region
2771 start or end because the face might change there. */
2772 if (it->region_beg_charpos > 0)
2773 {
2774 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2775 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2776 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2777 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2778 }
2779
2780 /* Set up variables for computing the stop position from text
2781 property changes. */
2782 XSETBUFFER (object, current_buffer);
2783 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2784 position = make_number (IT_CHARPOS (*it));
2785
2786 }
2787
2788 /* Get the interval containing IT's position. Value is a null
2789 interval if there isn't such an interval. */
2790 iv = validate_interval_range (object, &position, &position, 0);
2791 if (!NULL_INTERVAL_P (iv))
2792 {
2793 Lisp_Object values_here[LAST_PROP_IDX];
2794 struct props *p;
2795
2796 /* Get properties here. */
2797 for (p = it_props; p->handler; ++p)
2798 values_here[p->idx] = textget (iv->plist, *p->name);
2799
2800 /* Look for an interval following iv that has different
2801 properties. */
2802 for (next_iv = next_interval (iv);
2803 (!NULL_INTERVAL_P (next_iv)
2804 && (NILP (limit)
2805 || XFASTINT (limit) > next_iv->position));
2806 next_iv = next_interval (next_iv))
2807 {
2808 for (p = it_props; p->handler; ++p)
2809 {
2810 Lisp_Object new_value;
2811
2812 new_value = textget (next_iv->plist, *p->name);
2813 if (!EQ (values_here[p->idx], new_value))
2814 break;
2815 }
2816
2817 if (p->handler)
2818 break;
2819 }
2820
2821 if (!NULL_INTERVAL_P (next_iv))
2822 {
2823 if (INTEGERP (limit)
2824 && next_iv->position >= XFASTINT (limit))
2825 /* No text property change up to limit. */
2826 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2827 else
2828 /* Text properties change in next_iv. */
2829 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2830 }
2831 }
2832
2833 xassert (STRINGP (it->string)
2834 || (it->stop_charpos >= BEGV
2835 && it->stop_charpos >= IT_CHARPOS (*it)));
2836 }
2837
2838
2839 /* Return the position of the next overlay change after POS in
2840 current_buffer. Value is point-max if no overlay change
2841 follows. This is like `next-overlay-change' but doesn't use
2842 xmalloc. */
2843
2844 static int
2845 next_overlay_change (pos)
2846 int pos;
2847 {
2848 int noverlays;
2849 int endpos;
2850 Lisp_Object *overlays;
2851 int i;
2852
2853 /* Get all overlays at the given position. */
2854 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2855
2856 /* If any of these overlays ends before endpos,
2857 use its ending point instead. */
2858 for (i = 0; i < noverlays; ++i)
2859 {
2860 Lisp_Object oend;
2861 int oendpos;
2862
2863 oend = OVERLAY_END (overlays[i]);
2864 oendpos = OVERLAY_POSITION (oend);
2865 endpos = min (endpos, oendpos);
2866 }
2867
2868 return endpos;
2869 }
2870
2871
2872 \f
2873 /***********************************************************************
2874 Fontification
2875 ***********************************************************************/
2876
2877 /* Handle changes in the `fontified' property of the current buffer by
2878 calling hook functions from Qfontification_functions to fontify
2879 regions of text. */
2880
2881 static enum prop_handled
2882 handle_fontified_prop (it)
2883 struct it *it;
2884 {
2885 Lisp_Object prop, pos;
2886 enum prop_handled handled = HANDLED_NORMALLY;
2887
2888 /* Get the value of the `fontified' property at IT's current buffer
2889 position. (The `fontified' property doesn't have a special
2890 meaning in strings.) If the value is nil, call functions from
2891 Qfontification_functions. */
2892 if (!STRINGP (it->string)
2893 && it->s == NULL
2894 && !NILP (Vfontification_functions)
2895 && !NILP (Vrun_hooks)
2896 && (pos = make_number (IT_CHARPOS (*it)),
2897 prop = Fget_char_property (pos, Qfontified, Qnil),
2898 NILP (prop)))
2899 {
2900 int count = SPECPDL_INDEX ();
2901 Lisp_Object val;
2902
2903 val = Vfontification_functions;
2904 specbind (Qfontification_functions, Qnil);
2905
2906 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2907 safe_call1 (val, pos);
2908 else
2909 {
2910 Lisp_Object globals, fn;
2911 struct gcpro gcpro1, gcpro2;
2912
2913 globals = Qnil;
2914 GCPRO2 (val, globals);
2915
2916 for (; CONSP (val); val = XCDR (val))
2917 {
2918 fn = XCAR (val);
2919
2920 if (EQ (fn, Qt))
2921 {
2922 /* A value of t indicates this hook has a local
2923 binding; it means to run the global binding too.
2924 In a global value, t should not occur. If it
2925 does, we must ignore it to avoid an endless
2926 loop. */
2927 for (globals = Fdefault_value (Qfontification_functions);
2928 CONSP (globals);
2929 globals = XCDR (globals))
2930 {
2931 fn = XCAR (globals);
2932 if (!EQ (fn, Qt))
2933 safe_call1 (fn, pos);
2934 }
2935 }
2936 else
2937 safe_call1 (fn, pos);
2938 }
2939
2940 UNGCPRO;
2941 }
2942
2943 unbind_to (count, Qnil);
2944
2945 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2946 something. This avoids an endless loop if they failed to
2947 fontify the text for which reason ever. */
2948 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2949 handled = HANDLED_RECOMPUTE_PROPS;
2950 }
2951
2952 return handled;
2953 }
2954
2955
2956 \f
2957 /***********************************************************************
2958 Faces
2959 ***********************************************************************/
2960
2961 /* Set up iterator IT from face properties at its current position.
2962 Called from handle_stop. */
2963
2964 static enum prop_handled
2965 handle_face_prop (it)
2966 struct it *it;
2967 {
2968 int new_face_id, next_stop;
2969
2970 if (!STRINGP (it->string))
2971 {
2972 new_face_id
2973 = face_at_buffer_position (it->w,
2974 IT_CHARPOS (*it),
2975 it->region_beg_charpos,
2976 it->region_end_charpos,
2977 &next_stop,
2978 (IT_CHARPOS (*it)
2979 + TEXT_PROP_DISTANCE_LIMIT),
2980 0);
2981
2982 /* Is this a start of a run of characters with box face?
2983 Caveat: this can be called for a freshly initialized
2984 iterator; face_id is -1 in this case. We know that the new
2985 face will not change until limit, i.e. if the new face has a
2986 box, all characters up to limit will have one. But, as
2987 usual, we don't know whether limit is really the end. */
2988 if (new_face_id != it->face_id)
2989 {
2990 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2991
2992 /* If new face has a box but old face has not, this is
2993 the start of a run of characters with box, i.e. it has
2994 a shadow on the left side. The value of face_id of the
2995 iterator will be -1 if this is the initial call that gets
2996 the face. In this case, we have to look in front of IT's
2997 position and see whether there is a face != new_face_id. */
2998 it->start_of_box_run_p
2999 = (new_face->box != FACE_NO_BOX
3000 && (it->face_id >= 0
3001 || IT_CHARPOS (*it) == BEG
3002 || new_face_id != face_before_it_pos (it)));
3003 it->face_box_p = new_face->box != FACE_NO_BOX;
3004 }
3005 }
3006 else
3007 {
3008 int base_face_id, bufpos;
3009
3010 if (it->current.overlay_string_index >= 0)
3011 bufpos = IT_CHARPOS (*it);
3012 else
3013 bufpos = 0;
3014
3015 /* For strings from a buffer, i.e. overlay strings or strings
3016 from a `display' property, use the face at IT's current
3017 buffer position as the base face to merge with, so that
3018 overlay strings appear in the same face as surrounding
3019 text, unless they specify their own faces. */
3020 base_face_id = underlying_face_id (it);
3021
3022 new_face_id = face_at_string_position (it->w,
3023 it->string,
3024 IT_STRING_CHARPOS (*it),
3025 bufpos,
3026 it->region_beg_charpos,
3027 it->region_end_charpos,
3028 &next_stop,
3029 base_face_id, 0);
3030
3031 #if 0 /* This shouldn't be neccessary. Let's check it. */
3032 /* If IT is used to display a mode line we would really like to
3033 use the mode line face instead of the frame's default face. */
3034 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3035 && new_face_id == DEFAULT_FACE_ID)
3036 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3037 #endif
3038
3039 /* Is this a start of a run of characters with box? Caveat:
3040 this can be called for a freshly allocated iterator; face_id
3041 is -1 is this case. We know that the new face will not
3042 change until the next check pos, i.e. if the new face has a
3043 box, all characters up to that position will have a
3044 box. But, as usual, we don't know whether that position
3045 is really the end. */
3046 if (new_face_id != it->face_id)
3047 {
3048 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3049 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3050
3051 /* If new face has a box but old face hasn't, this is the
3052 start of a run of characters with box, i.e. it has a
3053 shadow on the left side. */
3054 it->start_of_box_run_p
3055 = new_face->box && (old_face == NULL || !old_face->box);
3056 it->face_box_p = new_face->box != FACE_NO_BOX;
3057 }
3058 }
3059
3060 it->face_id = new_face_id;
3061 return HANDLED_NORMALLY;
3062 }
3063
3064
3065 /* Return the ID of the face ``underlying'' IT's current position,
3066 which is in a string. If the iterator is associated with a
3067 buffer, return the face at IT's current buffer position.
3068 Otherwise, use the iterator's base_face_id. */
3069
3070 static int
3071 underlying_face_id (it)
3072 struct it *it;
3073 {
3074 int face_id = it->base_face_id, i;
3075
3076 xassert (STRINGP (it->string));
3077
3078 for (i = it->sp - 1; i >= 0; --i)
3079 if (NILP (it->stack[i].string))
3080 face_id = it->stack[i].face_id;
3081
3082 return face_id;
3083 }
3084
3085
3086 /* Compute the face one character before or after the current position
3087 of IT. BEFORE_P non-zero means get the face in front of IT's
3088 position. Value is the id of the face. */
3089
3090 static int
3091 face_before_or_after_it_pos (it, before_p)
3092 struct it *it;
3093 int before_p;
3094 {
3095 int face_id, limit;
3096 int next_check_charpos;
3097 struct text_pos pos;
3098
3099 xassert (it->s == NULL);
3100
3101 if (STRINGP (it->string))
3102 {
3103 int bufpos, base_face_id;
3104
3105 /* No face change past the end of the string (for the case
3106 we are padding with spaces). No face change before the
3107 string start. */
3108 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3109 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3110 return it->face_id;
3111
3112 /* Set pos to the position before or after IT's current position. */
3113 if (before_p)
3114 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3115 else
3116 /* For composition, we must check the character after the
3117 composition. */
3118 pos = (it->what == IT_COMPOSITION
3119 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3120 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3121
3122 if (it->current.overlay_string_index >= 0)
3123 bufpos = IT_CHARPOS (*it);
3124 else
3125 bufpos = 0;
3126
3127 base_face_id = underlying_face_id (it);
3128
3129 /* Get the face for ASCII, or unibyte. */
3130 face_id = face_at_string_position (it->w,
3131 it->string,
3132 CHARPOS (pos),
3133 bufpos,
3134 it->region_beg_charpos,
3135 it->region_end_charpos,
3136 &next_check_charpos,
3137 base_face_id, 0);
3138
3139 /* Correct the face for charsets different from ASCII. Do it
3140 for the multibyte case only. The face returned above is
3141 suitable for unibyte text if IT->string is unibyte. */
3142 if (STRING_MULTIBYTE (it->string))
3143 {
3144 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3145 int rest = SBYTES (it->string) - BYTEPOS (pos);
3146 int c, len;
3147 struct face *face = FACE_FROM_ID (it->f, face_id);
3148
3149 c = string_char_and_length (p, rest, &len);
3150 face_id = FACE_FOR_CHAR (it->f, face, c);
3151 }
3152 }
3153 else
3154 {
3155 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3156 || (IT_CHARPOS (*it) <= BEGV && before_p))
3157 return it->face_id;
3158
3159 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3160 pos = it->current.pos;
3161
3162 if (before_p)
3163 DEC_TEXT_POS (pos, it->multibyte_p);
3164 else
3165 {
3166 if (it->what == IT_COMPOSITION)
3167 /* For composition, we must check the position after the
3168 composition. */
3169 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3170 else
3171 INC_TEXT_POS (pos, it->multibyte_p);
3172 }
3173
3174 /* Determine face for CHARSET_ASCII, or unibyte. */
3175 face_id = face_at_buffer_position (it->w,
3176 CHARPOS (pos),
3177 it->region_beg_charpos,
3178 it->region_end_charpos,
3179 &next_check_charpos,
3180 limit, 0);
3181
3182 /* Correct the face for charsets different from ASCII. Do it
3183 for the multibyte case only. The face returned above is
3184 suitable for unibyte text if current_buffer is unibyte. */
3185 if (it->multibyte_p)
3186 {
3187 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3188 struct face *face = FACE_FROM_ID (it->f, face_id);
3189 face_id = FACE_FOR_CHAR (it->f, face, c);
3190 }
3191 }
3192
3193 return face_id;
3194 }
3195
3196
3197 \f
3198 /***********************************************************************
3199 Invisible text
3200 ***********************************************************************/
3201
3202 /* Set up iterator IT from invisible properties at its current
3203 position. Called from handle_stop. */
3204
3205 static enum prop_handled
3206 handle_invisible_prop (it)
3207 struct it *it;
3208 {
3209 enum prop_handled handled = HANDLED_NORMALLY;
3210
3211 if (STRINGP (it->string))
3212 {
3213 extern Lisp_Object Qinvisible;
3214 Lisp_Object prop, end_charpos, limit, charpos;
3215
3216 /* Get the value of the invisible text property at the
3217 current position. Value will be nil if there is no such
3218 property. */
3219 charpos = make_number (IT_STRING_CHARPOS (*it));
3220 prop = Fget_text_property (charpos, Qinvisible, it->string);
3221
3222 if (!NILP (prop)
3223 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3224 {
3225 handled = HANDLED_RECOMPUTE_PROPS;
3226
3227 /* Get the position at which the next change of the
3228 invisible text property can be found in IT->string.
3229 Value will be nil if the property value is the same for
3230 all the rest of IT->string. */
3231 XSETINT (limit, SCHARS (it->string));
3232 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3233 it->string, limit);
3234
3235 /* Text at current position is invisible. The next
3236 change in the property is at position end_charpos.
3237 Move IT's current position to that position. */
3238 if (INTEGERP (end_charpos)
3239 && XFASTINT (end_charpos) < XFASTINT (limit))
3240 {
3241 struct text_pos old;
3242 old = it->current.string_pos;
3243 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3244 compute_string_pos (&it->current.string_pos, old, it->string);
3245 }
3246 else
3247 {
3248 /* The rest of the string is invisible. If this is an
3249 overlay string, proceed with the next overlay string
3250 or whatever comes and return a character from there. */
3251 if (it->current.overlay_string_index >= 0)
3252 {
3253 next_overlay_string (it);
3254 /* Don't check for overlay strings when we just
3255 finished processing them. */
3256 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3257 }
3258 else
3259 {
3260 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3261 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3262 }
3263 }
3264 }
3265 }
3266 else
3267 {
3268 int invis_p, newpos, next_stop, start_charpos;
3269 Lisp_Object pos, prop, overlay;
3270
3271 /* First of all, is there invisible text at this position? */
3272 start_charpos = IT_CHARPOS (*it);
3273 pos = make_number (IT_CHARPOS (*it));
3274 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3275 &overlay);
3276 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3277
3278 /* If we are on invisible text, skip over it. */
3279 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3280 {
3281 /* Record whether we have to display an ellipsis for the
3282 invisible text. */
3283 int display_ellipsis_p = invis_p == 2;
3284
3285 handled = HANDLED_RECOMPUTE_PROPS;
3286
3287 /* Loop skipping over invisible text. The loop is left at
3288 ZV or with IT on the first char being visible again. */
3289 do
3290 {
3291 /* Try to skip some invisible text. Return value is the
3292 position reached which can be equal to IT's position
3293 if there is nothing invisible here. This skips both
3294 over invisible text properties and overlays with
3295 invisible property. */
3296 newpos = skip_invisible (IT_CHARPOS (*it),
3297 &next_stop, ZV, it->window);
3298
3299 /* If we skipped nothing at all we weren't at invisible
3300 text in the first place. If everything to the end of
3301 the buffer was skipped, end the loop. */
3302 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3303 invis_p = 0;
3304 else
3305 {
3306 /* We skipped some characters but not necessarily
3307 all there are. Check if we ended up on visible
3308 text. Fget_char_property returns the property of
3309 the char before the given position, i.e. if we
3310 get invis_p = 0, this means that the char at
3311 newpos is visible. */
3312 pos = make_number (newpos);
3313 prop = Fget_char_property (pos, Qinvisible, it->window);
3314 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3315 }
3316
3317 /* If we ended up on invisible text, proceed to
3318 skip starting with next_stop. */
3319 if (invis_p)
3320 IT_CHARPOS (*it) = next_stop;
3321 }
3322 while (invis_p);
3323
3324 /* The position newpos is now either ZV or on visible text. */
3325 IT_CHARPOS (*it) = newpos;
3326 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3327
3328 /* If there are before-strings at the start of invisible
3329 text, and the text is invisible because of a text
3330 property, arrange to show before-strings because 20.x did
3331 it that way. (If the text is invisible because of an
3332 overlay property instead of a text property, this is
3333 already handled in the overlay code.) */
3334 if (NILP (overlay)
3335 && get_overlay_strings (it, start_charpos))
3336 {
3337 handled = HANDLED_RECOMPUTE_PROPS;
3338 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3339 }
3340 else if (display_ellipsis_p)
3341 setup_for_ellipsis (it, 0);
3342 }
3343 }
3344
3345 return handled;
3346 }
3347
3348
3349 /* Make iterator IT return `...' next.
3350 Replaces LEN characters from buffer. */
3351
3352 static void
3353 setup_for_ellipsis (it, len)
3354 struct it *it;
3355 int len;
3356 {
3357 /* Use the display table definition for `...'. Invalid glyphs
3358 will be handled by the method returning elements from dpvec. */
3359 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3360 {
3361 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3362 it->dpvec = v->contents;
3363 it->dpend = v->contents + v->size;
3364 }
3365 else
3366 {
3367 /* Default `...'. */
3368 it->dpvec = default_invis_vector;
3369 it->dpend = default_invis_vector + 3;
3370 }
3371
3372 it->dpvec_char_len = len;
3373 it->current.dpvec_index = 0;
3374 it->dpvec_face_id = -1;
3375
3376 /* Remember the current face id in case glyphs specify faces.
3377 IT's face is restored in set_iterator_to_next. */
3378 it->saved_face_id = it->face_id;
3379 it->method = GET_FROM_DISPLAY_VECTOR;
3380 it->ellipsis_p = 1;
3381 }
3382
3383
3384 \f
3385 /***********************************************************************
3386 'display' property
3387 ***********************************************************************/
3388
3389 /* Set up iterator IT from `display' property at its current position.
3390 Called from handle_stop.
3391 We return HANDLED_RETURN if some part of the display property
3392 overrides the display of the buffer text itself.
3393 Otherwise we return HANDLED_NORMALLY. */
3394
3395 static enum prop_handled
3396 handle_display_prop (it)
3397 struct it *it;
3398 {
3399 Lisp_Object prop, object;
3400 struct text_pos *position;
3401 /* Nonzero if some property replaces the display of the text itself. */
3402 int display_replaced_p = 0;
3403
3404 if (STRINGP (it->string))
3405 {
3406 object = it->string;
3407 position = &it->current.string_pos;
3408 }
3409 else
3410 {
3411 object = it->w->buffer;
3412 position = &it->current.pos;
3413 }
3414
3415 /* Reset those iterator values set from display property values. */
3416 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3417 it->space_width = Qnil;
3418 it->font_height = Qnil;
3419 it->voffset = 0;
3420
3421 /* We don't support recursive `display' properties, i.e. string
3422 values that have a string `display' property, that have a string
3423 `display' property etc. */
3424 if (!it->string_from_display_prop_p)
3425 it->area = TEXT_AREA;
3426
3427 prop = Fget_char_property (make_number (position->charpos),
3428 Qdisplay, object);
3429 if (NILP (prop))
3430 return HANDLED_NORMALLY;
3431
3432 if (CONSP (prop)
3433 /* Simple properties. */
3434 && !EQ (XCAR (prop), Qimage)
3435 && !EQ (XCAR (prop), Qspace)
3436 && !EQ (XCAR (prop), Qwhen)
3437 && !EQ (XCAR (prop), Qslice)
3438 && !EQ (XCAR (prop), Qspace_width)
3439 && !EQ (XCAR (prop), Qheight)
3440 && !EQ (XCAR (prop), Qraise)
3441 /* Marginal area specifications. */
3442 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3443 && !EQ (XCAR (prop), Qleft_fringe)
3444 && !EQ (XCAR (prop), Qright_fringe)
3445 && !NILP (XCAR (prop)))
3446 {
3447 for (; CONSP (prop); prop = XCDR (prop))
3448 {
3449 if (handle_single_display_spec (it, XCAR (prop), object,
3450 position, display_replaced_p))
3451 display_replaced_p = 1;
3452 }
3453 }
3454 else if (VECTORP (prop))
3455 {
3456 int i;
3457 for (i = 0; i < ASIZE (prop); ++i)
3458 if (handle_single_display_spec (it, AREF (prop, i), object,
3459 position, display_replaced_p))
3460 display_replaced_p = 1;
3461 }
3462 else
3463 {
3464 if (handle_single_display_spec (it, prop, object, position, 0))
3465 display_replaced_p = 1;
3466 }
3467
3468 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3469 }
3470
3471
3472 /* Value is the position of the end of the `display' property starting
3473 at START_POS in OBJECT. */
3474
3475 static struct text_pos
3476 display_prop_end (it, object, start_pos)
3477 struct it *it;
3478 Lisp_Object object;
3479 struct text_pos start_pos;
3480 {
3481 Lisp_Object end;
3482 struct text_pos end_pos;
3483
3484 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3485 Qdisplay, object, Qnil);
3486 CHARPOS (end_pos) = XFASTINT (end);
3487 if (STRINGP (object))
3488 compute_string_pos (&end_pos, start_pos, it->string);
3489 else
3490 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3491
3492 return end_pos;
3493 }
3494
3495
3496 /* Set up IT from a single `display' specification PROP. OBJECT
3497 is the object in which the `display' property was found. *POSITION
3498 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3499 means that we previously saw a display specification which already
3500 replaced text display with something else, for example an image;
3501 we ignore such properties after the first one has been processed.
3502
3503 If PROP is a `space' or `image' specification, and in some other
3504 cases too, set *POSITION to the position where the `display'
3505 property ends.
3506
3507 Value is non-zero if something was found which replaces the display
3508 of buffer or string text. */
3509
3510 static int
3511 handle_single_display_spec (it, spec, object, position,
3512 display_replaced_before_p)
3513 struct it *it;
3514 Lisp_Object spec;
3515 Lisp_Object object;
3516 struct text_pos *position;
3517 int display_replaced_before_p;
3518 {
3519 Lisp_Object form;
3520 Lisp_Object location, value;
3521 struct text_pos start_pos;
3522 int valid_p;
3523
3524 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3525 If the result is non-nil, use VALUE instead of SPEC. */
3526 form = Qt;
3527 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3528 {
3529 spec = XCDR (spec);
3530 if (!CONSP (spec))
3531 return 0;
3532 form = XCAR (spec);
3533 spec = XCDR (spec);
3534 }
3535
3536 if (!NILP (form) && !EQ (form, Qt))
3537 {
3538 int count = SPECPDL_INDEX ();
3539 struct gcpro gcpro1;
3540
3541 /* Bind `object' to the object having the `display' property, a
3542 buffer or string. Bind `position' to the position in the
3543 object where the property was found, and `buffer-position'
3544 to the current position in the buffer. */
3545 specbind (Qobject, object);
3546 specbind (Qposition, make_number (CHARPOS (*position)));
3547 specbind (Qbuffer_position,
3548 make_number (STRINGP (object)
3549 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3550 GCPRO1 (form);
3551 form = safe_eval (form);
3552 UNGCPRO;
3553 unbind_to (count, Qnil);
3554 }
3555
3556 if (NILP (form))
3557 return 0;
3558
3559 /* Handle `(height HEIGHT)' specifications. */
3560 if (CONSP (spec)
3561 && EQ (XCAR (spec), Qheight)
3562 && CONSP (XCDR (spec)))
3563 {
3564 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3565 return 0;
3566
3567 it->font_height = XCAR (XCDR (spec));
3568 if (!NILP (it->font_height))
3569 {
3570 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3571 int new_height = -1;
3572
3573 if (CONSP (it->font_height)
3574 && (EQ (XCAR (it->font_height), Qplus)
3575 || EQ (XCAR (it->font_height), Qminus))
3576 && CONSP (XCDR (it->font_height))
3577 && INTEGERP (XCAR (XCDR (it->font_height))))
3578 {
3579 /* `(+ N)' or `(- N)' where N is an integer. */
3580 int steps = XINT (XCAR (XCDR (it->font_height)));
3581 if (EQ (XCAR (it->font_height), Qplus))
3582 steps = - steps;
3583 it->face_id = smaller_face (it->f, it->face_id, steps);
3584 }
3585 else if (FUNCTIONP (it->font_height))
3586 {
3587 /* Call function with current height as argument.
3588 Value is the new height. */
3589 Lisp_Object height;
3590 height = safe_call1 (it->font_height,
3591 face->lface[LFACE_HEIGHT_INDEX]);
3592 if (NUMBERP (height))
3593 new_height = XFLOATINT (height);
3594 }
3595 else if (NUMBERP (it->font_height))
3596 {
3597 /* Value is a multiple of the canonical char height. */
3598 struct face *face;
3599
3600 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3601 new_height = (XFLOATINT (it->font_height)
3602 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3603 }
3604 else
3605 {
3606 /* Evaluate IT->font_height with `height' bound to the
3607 current specified height to get the new height. */
3608 int count = SPECPDL_INDEX ();
3609
3610 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3611 value = safe_eval (it->font_height);
3612 unbind_to (count, Qnil);
3613
3614 if (NUMBERP (value))
3615 new_height = XFLOATINT (value);
3616 }
3617
3618 if (new_height > 0)
3619 it->face_id = face_with_height (it->f, it->face_id, new_height);
3620 }
3621
3622 return 0;
3623 }
3624
3625 /* Handle `(space_width WIDTH)'. */
3626 if (CONSP (spec)
3627 && EQ (XCAR (spec), Qspace_width)
3628 && CONSP (XCDR (spec)))
3629 {
3630 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3631 return 0;
3632
3633 value = XCAR (XCDR (spec));
3634 if (NUMBERP (value) && XFLOATINT (value) > 0)
3635 it->space_width = value;
3636
3637 return 0;
3638 }
3639
3640 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3641 if (CONSP (spec)
3642 && EQ (XCAR (spec), Qslice))
3643 {
3644 Lisp_Object tem;
3645
3646 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3647 return 0;
3648
3649 if (tem = XCDR (spec), CONSP (tem))
3650 {
3651 it->slice.x = XCAR (tem);
3652 if (tem = XCDR (tem), CONSP (tem))
3653 {
3654 it->slice.y = XCAR (tem);
3655 if (tem = XCDR (tem), CONSP (tem))
3656 {
3657 it->slice.width = XCAR (tem);
3658 if (tem = XCDR (tem), CONSP (tem))
3659 it->slice.height = XCAR (tem);
3660 }
3661 }
3662 }
3663
3664 return 0;
3665 }
3666
3667 /* Handle `(raise FACTOR)'. */
3668 if (CONSP (spec)
3669 && EQ (XCAR (spec), Qraise)
3670 && CONSP (XCDR (spec)))
3671 {
3672 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3673 return 0;
3674
3675 #ifdef HAVE_WINDOW_SYSTEM
3676 value = XCAR (XCDR (spec));
3677 if (NUMBERP (value))
3678 {
3679 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3680 it->voffset = - (XFLOATINT (value)
3681 * (FONT_HEIGHT (face->font)));
3682 }
3683 #endif /* HAVE_WINDOW_SYSTEM */
3684
3685 return 0;
3686 }
3687
3688 /* Don't handle the other kinds of display specifications
3689 inside a string that we got from a `display' property. */
3690 if (it->string_from_display_prop_p)
3691 return 0;
3692
3693 /* Characters having this form of property are not displayed, so
3694 we have to find the end of the property. */
3695 start_pos = *position;
3696 *position = display_prop_end (it, object, start_pos);
3697 value = Qnil;
3698
3699 /* Stop the scan at that end position--we assume that all
3700 text properties change there. */
3701 it->stop_charpos = position->charpos;
3702
3703 /* Handle `(left-fringe BITMAP [FACE])'
3704 and `(right-fringe BITMAP [FACE])'. */
3705 if (CONSP (spec)
3706 && (EQ (XCAR (spec), Qleft_fringe)
3707 || EQ (XCAR (spec), Qright_fringe))
3708 && CONSP (XCDR (spec)))
3709 {
3710 int face_id = DEFAULT_FACE_ID;
3711 int fringe_bitmap;
3712
3713 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3714 /* If we return here, POSITION has been advanced
3715 across the text with this property. */
3716 return 0;
3717
3718 #ifdef HAVE_WINDOW_SYSTEM
3719 value = XCAR (XCDR (spec));
3720 if (!SYMBOLP (value)
3721 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3722 /* If we return here, POSITION has been advanced
3723 across the text with this property. */
3724 return 0;
3725
3726 if (CONSP (XCDR (XCDR (spec))))
3727 {
3728 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
3729 int face_id2 = lookup_named_face (it->f, face_name, 'A', 0);
3730 if (face_id2 >= 0)
3731 face_id = face_id2;
3732 }
3733
3734 /* Save current settings of IT so that we can restore them
3735 when we are finished with the glyph property value. */
3736
3737 push_it (it);
3738
3739 it->area = TEXT_AREA;
3740 it->what = IT_IMAGE;
3741 it->image_id = -1; /* no image */
3742 it->position = start_pos;
3743 it->object = NILP (object) ? it->w->buffer : object;
3744 it->method = GET_FROM_IMAGE;
3745 it->face_id = face_id;
3746
3747 /* Say that we haven't consumed the characters with
3748 `display' property yet. The call to pop_it in
3749 set_iterator_to_next will clean this up. */
3750 *position = start_pos;
3751
3752 if (EQ (XCAR (spec), Qleft_fringe))
3753 {
3754 it->left_user_fringe_bitmap = fringe_bitmap;
3755 it->left_user_fringe_face_id = face_id;
3756 }
3757 else
3758 {
3759 it->right_user_fringe_bitmap = fringe_bitmap;
3760 it->right_user_fringe_face_id = face_id;
3761 }
3762 #endif /* HAVE_WINDOW_SYSTEM */
3763 return 1;
3764 }
3765
3766 /* Prepare to handle `((margin left-margin) ...)',
3767 `((margin right-margin) ...)' and `((margin nil) ...)'
3768 prefixes for display specifications. */
3769 location = Qunbound;
3770 if (CONSP (spec) && CONSP (XCAR (spec)))
3771 {
3772 Lisp_Object tem;
3773
3774 value = XCDR (spec);
3775 if (CONSP (value))
3776 value = XCAR (value);
3777
3778 tem = XCAR (spec);
3779 if (EQ (XCAR (tem), Qmargin)
3780 && (tem = XCDR (tem),
3781 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3782 (NILP (tem)
3783 || EQ (tem, Qleft_margin)
3784 || EQ (tem, Qright_margin))))
3785 location = tem;
3786 }
3787
3788 if (EQ (location, Qunbound))
3789 {
3790 location = Qnil;
3791 value = spec;
3792 }
3793
3794 /* After this point, VALUE is the property after any
3795 margin prefix has been stripped. It must be a string,
3796 an image specification, or `(space ...)'.
3797
3798 LOCATION specifies where to display: `left-margin',
3799 `right-margin' or nil. */
3800
3801 valid_p = (STRINGP (value)
3802 #ifdef HAVE_WINDOW_SYSTEM
3803 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3804 #endif /* not HAVE_WINDOW_SYSTEM */
3805 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3806
3807 if (valid_p && !display_replaced_before_p)
3808 {
3809 /* Save current settings of IT so that we can restore them
3810 when we are finished with the glyph property value. */
3811 push_it (it);
3812
3813 if (NILP (location))
3814 it->area = TEXT_AREA;
3815 else if (EQ (location, Qleft_margin))
3816 it->area = LEFT_MARGIN_AREA;
3817 else
3818 it->area = RIGHT_MARGIN_AREA;
3819
3820 if (STRINGP (value))
3821 {
3822 it->string = value;
3823 it->multibyte_p = STRING_MULTIBYTE (it->string);
3824 it->current.overlay_string_index = -1;
3825 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3826 it->end_charpos = it->string_nchars = SCHARS (it->string);
3827 it->method = GET_FROM_STRING;
3828 it->stop_charpos = 0;
3829 it->string_from_display_prop_p = 1;
3830 /* Say that we haven't consumed the characters with
3831 `display' property yet. The call to pop_it in
3832 set_iterator_to_next will clean this up. */
3833 *position = start_pos;
3834 }
3835 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3836 {
3837 it->method = GET_FROM_STRETCH;
3838 it->object = value;
3839 it->current.pos = it->position = start_pos;
3840 }
3841 #ifdef HAVE_WINDOW_SYSTEM
3842 else
3843 {
3844 it->what = IT_IMAGE;
3845 it->image_id = lookup_image (it->f, value);
3846 it->position = start_pos;
3847 it->object = NILP (object) ? it->w->buffer : object;
3848 it->method = GET_FROM_IMAGE;
3849
3850 /* Say that we haven't consumed the characters with
3851 `display' property yet. The call to pop_it in
3852 set_iterator_to_next will clean this up. */
3853 *position = start_pos;
3854 }
3855 #endif /* HAVE_WINDOW_SYSTEM */
3856
3857 return 1;
3858 }
3859
3860 /* Invalid property or property not supported. Restore
3861 POSITION to what it was before. */
3862 *position = start_pos;
3863 return 0;
3864 }
3865
3866
3867 /* Check if SPEC is a display specification value whose text should be
3868 treated as intangible. */
3869
3870 static int
3871 single_display_spec_intangible_p (prop)
3872 Lisp_Object prop;
3873 {
3874 /* Skip over `when FORM'. */
3875 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3876 {
3877 prop = XCDR (prop);
3878 if (!CONSP (prop))
3879 return 0;
3880 prop = XCDR (prop);
3881 }
3882
3883 if (STRINGP (prop))
3884 return 1;
3885
3886 if (!CONSP (prop))
3887 return 0;
3888
3889 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3890 we don't need to treat text as intangible. */
3891 if (EQ (XCAR (prop), Qmargin))
3892 {
3893 prop = XCDR (prop);
3894 if (!CONSP (prop))
3895 return 0;
3896
3897 prop = XCDR (prop);
3898 if (!CONSP (prop)
3899 || EQ (XCAR (prop), Qleft_margin)
3900 || EQ (XCAR (prop), Qright_margin))
3901 return 0;
3902 }
3903
3904 return (CONSP (prop)
3905 && (EQ (XCAR (prop), Qimage)
3906 || EQ (XCAR (prop), Qspace)));
3907 }
3908
3909
3910 /* Check if PROP is a display property value whose text should be
3911 treated as intangible. */
3912
3913 int
3914 display_prop_intangible_p (prop)
3915 Lisp_Object prop;
3916 {
3917 if (CONSP (prop)
3918 && CONSP (XCAR (prop))
3919 && !EQ (Qmargin, XCAR (XCAR (prop))))
3920 {
3921 /* A list of sub-properties. */
3922 while (CONSP (prop))
3923 {
3924 if (single_display_spec_intangible_p (XCAR (prop)))
3925 return 1;
3926 prop = XCDR (prop);
3927 }
3928 }
3929 else if (VECTORP (prop))
3930 {
3931 /* A vector of sub-properties. */
3932 int i;
3933 for (i = 0; i < ASIZE (prop); ++i)
3934 if (single_display_spec_intangible_p (AREF (prop, i)))
3935 return 1;
3936 }
3937 else
3938 return single_display_spec_intangible_p (prop);
3939
3940 return 0;
3941 }
3942
3943
3944 /* Return 1 if PROP is a display sub-property value containing STRING. */
3945
3946 static int
3947 single_display_spec_string_p (prop, string)
3948 Lisp_Object prop, string;
3949 {
3950 if (EQ (string, prop))
3951 return 1;
3952
3953 /* Skip over `when FORM'. */
3954 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3955 {
3956 prop = XCDR (prop);
3957 if (!CONSP (prop))
3958 return 0;
3959 prop = XCDR (prop);
3960 }
3961
3962 if (CONSP (prop))
3963 /* Skip over `margin LOCATION'. */
3964 if (EQ (XCAR (prop), Qmargin))
3965 {
3966 prop = XCDR (prop);
3967 if (!CONSP (prop))
3968 return 0;
3969
3970 prop = XCDR (prop);
3971 if (!CONSP (prop))
3972 return 0;
3973 }
3974
3975 return CONSP (prop) && EQ (XCAR (prop), string);
3976 }
3977
3978
3979 /* Return 1 if STRING appears in the `display' property PROP. */
3980
3981 static int
3982 display_prop_string_p (prop, string)
3983 Lisp_Object prop, string;
3984 {
3985 if (CONSP (prop)
3986 && CONSP (XCAR (prop))
3987 && !EQ (Qmargin, XCAR (XCAR (prop))))
3988 {
3989 /* A list of sub-properties. */
3990 while (CONSP (prop))
3991 {
3992 if (single_display_spec_string_p (XCAR (prop), string))
3993 return 1;
3994 prop = XCDR (prop);
3995 }
3996 }
3997 else if (VECTORP (prop))
3998 {
3999 /* A vector of sub-properties. */
4000 int i;
4001 for (i = 0; i < ASIZE (prop); ++i)
4002 if (single_display_spec_string_p (AREF (prop, i), string))
4003 return 1;
4004 }
4005 else
4006 return single_display_spec_string_p (prop, string);
4007
4008 return 0;
4009 }
4010
4011
4012 /* Determine from which buffer position in W's buffer STRING comes
4013 from. AROUND_CHARPOS is an approximate position where it could
4014 be from. Value is the buffer position or 0 if it couldn't be
4015 determined.
4016
4017 W's buffer must be current.
4018
4019 This function is necessary because we don't record buffer positions
4020 in glyphs generated from strings (to keep struct glyph small).
4021 This function may only use code that doesn't eval because it is
4022 called asynchronously from note_mouse_highlight. */
4023
4024 int
4025 string_buffer_position (w, string, around_charpos)
4026 struct window *w;
4027 Lisp_Object string;
4028 int around_charpos;
4029 {
4030 Lisp_Object limit, prop, pos;
4031 const int MAX_DISTANCE = 1000;
4032 int found = 0;
4033
4034 pos = make_number (around_charpos);
4035 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4036 while (!found && !EQ (pos, limit))
4037 {
4038 prop = Fget_char_property (pos, Qdisplay, Qnil);
4039 if (!NILP (prop) && display_prop_string_p (prop, string))
4040 found = 1;
4041 else
4042 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4043 }
4044
4045 if (!found)
4046 {
4047 pos = make_number (around_charpos);
4048 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4049 while (!found && !EQ (pos, limit))
4050 {
4051 prop = Fget_char_property (pos, Qdisplay, Qnil);
4052 if (!NILP (prop) && display_prop_string_p (prop, string))
4053 found = 1;
4054 else
4055 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4056 limit);
4057 }
4058 }
4059
4060 return found ? XINT (pos) : 0;
4061 }
4062
4063
4064 \f
4065 /***********************************************************************
4066 `composition' property
4067 ***********************************************************************/
4068
4069 /* Set up iterator IT from `composition' property at its current
4070 position. Called from handle_stop. */
4071
4072 static enum prop_handled
4073 handle_composition_prop (it)
4074 struct it *it;
4075 {
4076 Lisp_Object prop, string;
4077 int pos, pos_byte, end;
4078 enum prop_handled handled = HANDLED_NORMALLY;
4079
4080 if (STRINGP (it->string))
4081 {
4082 pos = IT_STRING_CHARPOS (*it);
4083 pos_byte = IT_STRING_BYTEPOS (*it);
4084 string = it->string;
4085 }
4086 else
4087 {
4088 pos = IT_CHARPOS (*it);
4089 pos_byte = IT_BYTEPOS (*it);
4090 string = Qnil;
4091 }
4092
4093 /* If there's a valid composition and point is not inside of the
4094 composition (in the case that the composition is from the current
4095 buffer), draw a glyph composed from the composition components. */
4096 if (find_composition (pos, -1, &pos, &end, &prop, string)
4097 && COMPOSITION_VALID_P (pos, end, prop)
4098 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4099 {
4100 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4101
4102 if (id >= 0)
4103 {
4104 it->method = GET_FROM_COMPOSITION;
4105 it->cmp_id = id;
4106 it->cmp_len = COMPOSITION_LENGTH (prop);
4107 /* For a terminal, draw only the first character of the
4108 components. */
4109 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4110 it->len = (STRINGP (it->string)
4111 ? string_char_to_byte (it->string, end)
4112 : CHAR_TO_BYTE (end)) - pos_byte;
4113 it->stop_charpos = end;
4114 handled = HANDLED_RETURN;
4115 }
4116 }
4117
4118 return handled;
4119 }
4120
4121
4122 \f
4123 /***********************************************************************
4124 Overlay strings
4125 ***********************************************************************/
4126
4127 /* The following structure is used to record overlay strings for
4128 later sorting in load_overlay_strings. */
4129
4130 struct overlay_entry
4131 {
4132 Lisp_Object overlay;
4133 Lisp_Object string;
4134 int priority;
4135 int after_string_p;
4136 };
4137
4138
4139 /* Set up iterator IT from overlay strings at its current position.
4140 Called from handle_stop. */
4141
4142 static enum prop_handled
4143 handle_overlay_change (it)
4144 struct it *it;
4145 {
4146 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4147 return HANDLED_RECOMPUTE_PROPS;
4148 else
4149 return HANDLED_NORMALLY;
4150 }
4151
4152
4153 /* Set up the next overlay string for delivery by IT, if there is an
4154 overlay string to deliver. Called by set_iterator_to_next when the
4155 end of the current overlay string is reached. If there are more
4156 overlay strings to display, IT->string and
4157 IT->current.overlay_string_index are set appropriately here.
4158 Otherwise IT->string is set to nil. */
4159
4160 static void
4161 next_overlay_string (it)
4162 struct it *it;
4163 {
4164 ++it->current.overlay_string_index;
4165 if (it->current.overlay_string_index == it->n_overlay_strings)
4166 {
4167 /* No more overlay strings. Restore IT's settings to what
4168 they were before overlay strings were processed, and
4169 continue to deliver from current_buffer. */
4170 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4171
4172 pop_it (it);
4173 xassert (it->stop_charpos >= BEGV
4174 && it->stop_charpos <= it->end_charpos);
4175 it->string = Qnil;
4176 it->current.overlay_string_index = -1;
4177 SET_TEXT_POS (it->current.string_pos, -1, -1);
4178 it->n_overlay_strings = 0;
4179 it->method = GET_FROM_BUFFER;
4180
4181 /* If we're at the end of the buffer, record that we have
4182 processed the overlay strings there already, so that
4183 next_element_from_buffer doesn't try it again. */
4184 if (IT_CHARPOS (*it) >= it->end_charpos)
4185 it->overlay_strings_at_end_processed_p = 1;
4186
4187 /* If we have to display `...' for invisible text, set
4188 the iterator up for that. */
4189 if (display_ellipsis_p)
4190 setup_for_ellipsis (it, 0);
4191 }
4192 else
4193 {
4194 /* There are more overlay strings to process. If
4195 IT->current.overlay_string_index has advanced to a position
4196 where we must load IT->overlay_strings with more strings, do
4197 it. */
4198 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4199
4200 if (it->current.overlay_string_index && i == 0)
4201 load_overlay_strings (it, 0);
4202
4203 /* Initialize IT to deliver display elements from the overlay
4204 string. */
4205 it->string = it->overlay_strings[i];
4206 it->multibyte_p = STRING_MULTIBYTE (it->string);
4207 SET_TEXT_POS (it->current.string_pos, 0, 0);
4208 it->method = GET_FROM_STRING;
4209 it->stop_charpos = 0;
4210 }
4211
4212 CHECK_IT (it);
4213 }
4214
4215
4216 /* Compare two overlay_entry structures E1 and E2. Used as a
4217 comparison function for qsort in load_overlay_strings. Overlay
4218 strings for the same position are sorted so that
4219
4220 1. All after-strings come in front of before-strings, except
4221 when they come from the same overlay.
4222
4223 2. Within after-strings, strings are sorted so that overlay strings
4224 from overlays with higher priorities come first.
4225
4226 2. Within before-strings, strings are sorted so that overlay
4227 strings from overlays with higher priorities come last.
4228
4229 Value is analogous to strcmp. */
4230
4231
4232 static int
4233 compare_overlay_entries (e1, e2)
4234 void *e1, *e2;
4235 {
4236 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4237 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4238 int result;
4239
4240 if (entry1->after_string_p != entry2->after_string_p)
4241 {
4242 /* Let after-strings appear in front of before-strings if
4243 they come from different overlays. */
4244 if (EQ (entry1->overlay, entry2->overlay))
4245 result = entry1->after_string_p ? 1 : -1;
4246 else
4247 result = entry1->after_string_p ? -1 : 1;
4248 }
4249 else if (entry1->after_string_p)
4250 /* After-strings sorted in order of decreasing priority. */
4251 result = entry2->priority - entry1->priority;
4252 else
4253 /* Before-strings sorted in order of increasing priority. */
4254 result = entry1->priority - entry2->priority;
4255
4256 return result;
4257 }
4258
4259
4260 /* Load the vector IT->overlay_strings with overlay strings from IT's
4261 current buffer position, or from CHARPOS if that is > 0. Set
4262 IT->n_overlays to the total number of overlay strings found.
4263
4264 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4265 a time. On entry into load_overlay_strings,
4266 IT->current.overlay_string_index gives the number of overlay
4267 strings that have already been loaded by previous calls to this
4268 function.
4269
4270 IT->add_overlay_start contains an additional overlay start
4271 position to consider for taking overlay strings from, if non-zero.
4272 This position comes into play when the overlay has an `invisible'
4273 property, and both before and after-strings. When we've skipped to
4274 the end of the overlay, because of its `invisible' property, we
4275 nevertheless want its before-string to appear.
4276 IT->add_overlay_start will contain the overlay start position
4277 in this case.
4278
4279 Overlay strings are sorted so that after-string strings come in
4280 front of before-string strings. Within before and after-strings,
4281 strings are sorted by overlay priority. See also function
4282 compare_overlay_entries. */
4283
4284 static void
4285 load_overlay_strings (it, charpos)
4286 struct it *it;
4287 int charpos;
4288 {
4289 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4290 Lisp_Object overlay, window, str, invisible;
4291 struct Lisp_Overlay *ov;
4292 int start, end;
4293 int size = 20;
4294 int n = 0, i, j, invis_p;
4295 struct overlay_entry *entries
4296 = (struct overlay_entry *) alloca (size * sizeof *entries);
4297
4298 if (charpos <= 0)
4299 charpos = IT_CHARPOS (*it);
4300
4301 /* Append the overlay string STRING of overlay OVERLAY to vector
4302 `entries' which has size `size' and currently contains `n'
4303 elements. AFTER_P non-zero means STRING is an after-string of
4304 OVERLAY. */
4305 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4306 do \
4307 { \
4308 Lisp_Object priority; \
4309 \
4310 if (n == size) \
4311 { \
4312 int new_size = 2 * size; \
4313 struct overlay_entry *old = entries; \
4314 entries = \
4315 (struct overlay_entry *) alloca (new_size \
4316 * sizeof *entries); \
4317 bcopy (old, entries, size * sizeof *entries); \
4318 size = new_size; \
4319 } \
4320 \
4321 entries[n].string = (STRING); \
4322 entries[n].overlay = (OVERLAY); \
4323 priority = Foverlay_get ((OVERLAY), Qpriority); \
4324 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4325 entries[n].after_string_p = (AFTER_P); \
4326 ++n; \
4327 } \
4328 while (0)
4329
4330 /* Process overlay before the overlay center. */
4331 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4332 {
4333 XSETMISC (overlay, ov);
4334 xassert (OVERLAYP (overlay));
4335 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4336 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4337
4338 if (end < charpos)
4339 break;
4340
4341 /* Skip this overlay if it doesn't start or end at IT's current
4342 position. */
4343 if (end != charpos && start != charpos)
4344 continue;
4345
4346 /* Skip this overlay if it doesn't apply to IT->w. */
4347 window = Foverlay_get (overlay, Qwindow);
4348 if (WINDOWP (window) && XWINDOW (window) != it->w)
4349 continue;
4350
4351 /* If the text ``under'' the overlay is invisible, both before-
4352 and after-strings from this overlay are visible; start and
4353 end position are indistinguishable. */
4354 invisible = Foverlay_get (overlay, Qinvisible);
4355 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4356
4357 /* If overlay has a non-empty before-string, record it. */
4358 if ((start == charpos || (end == charpos && invis_p))
4359 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4360 && SCHARS (str))
4361 RECORD_OVERLAY_STRING (overlay, str, 0);
4362
4363 /* If overlay has a non-empty after-string, record it. */
4364 if ((end == charpos || (start == charpos && invis_p))
4365 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4366 && SCHARS (str))
4367 RECORD_OVERLAY_STRING (overlay, str, 1);
4368 }
4369
4370 /* Process overlays after the overlay center. */
4371 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4372 {
4373 XSETMISC (overlay, ov);
4374 xassert (OVERLAYP (overlay));
4375 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4376 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4377
4378 if (start > charpos)
4379 break;
4380
4381 /* Skip this overlay if it doesn't start or end at IT's current
4382 position. */
4383 if (end != charpos && start != charpos)
4384 continue;
4385
4386 /* Skip this overlay if it doesn't apply to IT->w. */
4387 window = Foverlay_get (overlay, Qwindow);
4388 if (WINDOWP (window) && XWINDOW (window) != it->w)
4389 continue;
4390
4391 /* If the text ``under'' the overlay is invisible, it has a zero
4392 dimension, and both before- and after-strings apply. */
4393 invisible = Foverlay_get (overlay, Qinvisible);
4394 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4395
4396 /* If overlay has a non-empty before-string, record it. */
4397 if ((start == charpos || (end == charpos && invis_p))
4398 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4399 && SCHARS (str))
4400 RECORD_OVERLAY_STRING (overlay, str, 0);
4401
4402 /* If overlay has a non-empty after-string, record it. */
4403 if ((end == charpos || (start == charpos && invis_p))
4404 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4405 && SCHARS (str))
4406 RECORD_OVERLAY_STRING (overlay, str, 1);
4407 }
4408
4409 #undef RECORD_OVERLAY_STRING
4410
4411 /* Sort entries. */
4412 if (n > 1)
4413 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4414
4415 /* Record the total number of strings to process. */
4416 it->n_overlay_strings = n;
4417
4418 /* IT->current.overlay_string_index is the number of overlay strings
4419 that have already been consumed by IT. Copy some of the
4420 remaining overlay strings to IT->overlay_strings. */
4421 i = 0;
4422 j = it->current.overlay_string_index;
4423 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4424 it->overlay_strings[i++] = entries[j++].string;
4425
4426 CHECK_IT (it);
4427 }
4428
4429
4430 /* Get the first chunk of overlay strings at IT's current buffer
4431 position, or at CHARPOS if that is > 0. Value is non-zero if at
4432 least one overlay string was found. */
4433
4434 static int
4435 get_overlay_strings (it, charpos)
4436 struct it *it;
4437 int charpos;
4438 {
4439 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4440 process. This fills IT->overlay_strings with strings, and sets
4441 IT->n_overlay_strings to the total number of strings to process.
4442 IT->pos.overlay_string_index has to be set temporarily to zero
4443 because load_overlay_strings needs this; it must be set to -1
4444 when no overlay strings are found because a zero value would
4445 indicate a position in the first overlay string. */
4446 it->current.overlay_string_index = 0;
4447 load_overlay_strings (it, charpos);
4448
4449 /* If we found overlay strings, set up IT to deliver display
4450 elements from the first one. Otherwise set up IT to deliver
4451 from current_buffer. */
4452 if (it->n_overlay_strings)
4453 {
4454 /* Make sure we know settings in current_buffer, so that we can
4455 restore meaningful values when we're done with the overlay
4456 strings. */
4457 compute_stop_pos (it);
4458 xassert (it->face_id >= 0);
4459
4460 /* Save IT's settings. They are restored after all overlay
4461 strings have been processed. */
4462 xassert (it->sp == 0);
4463 push_it (it);
4464
4465 /* Set up IT to deliver display elements from the first overlay
4466 string. */
4467 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4468 it->string = it->overlay_strings[0];
4469 it->stop_charpos = 0;
4470 xassert (STRINGP (it->string));
4471 it->end_charpos = SCHARS (it->string);
4472 it->multibyte_p = STRING_MULTIBYTE (it->string);
4473 it->method = GET_FROM_STRING;
4474 }
4475 else
4476 {
4477 it->string = Qnil;
4478 it->current.overlay_string_index = -1;
4479 it->method = GET_FROM_BUFFER;
4480 }
4481
4482 CHECK_IT (it);
4483
4484 /* Value is non-zero if we found at least one overlay string. */
4485 return STRINGP (it->string);
4486 }
4487
4488
4489 \f
4490 /***********************************************************************
4491 Saving and restoring state
4492 ***********************************************************************/
4493
4494 /* Save current settings of IT on IT->stack. Called, for example,
4495 before setting up IT for an overlay string, to be able to restore
4496 IT's settings to what they were after the overlay string has been
4497 processed. */
4498
4499 static void
4500 push_it (it)
4501 struct it *it;
4502 {
4503 struct iterator_stack_entry *p;
4504
4505 xassert (it->sp < 2);
4506 p = it->stack + it->sp;
4507
4508 p->stop_charpos = it->stop_charpos;
4509 xassert (it->face_id >= 0);
4510 p->face_id = it->face_id;
4511 p->string = it->string;
4512 p->pos = it->current;
4513 p->end_charpos = it->end_charpos;
4514 p->string_nchars = it->string_nchars;
4515 p->area = it->area;
4516 p->multibyte_p = it->multibyte_p;
4517 p->slice = it->slice;
4518 p->space_width = it->space_width;
4519 p->font_height = it->font_height;
4520 p->voffset = it->voffset;
4521 p->string_from_display_prop_p = it->string_from_display_prop_p;
4522 p->display_ellipsis_p = 0;
4523 ++it->sp;
4524 }
4525
4526
4527 /* Restore IT's settings from IT->stack. Called, for example, when no
4528 more overlay strings must be processed, and we return to delivering
4529 display elements from a buffer, or when the end of a string from a
4530 `display' property is reached and we return to delivering display
4531 elements from an overlay string, or from a buffer. */
4532
4533 static void
4534 pop_it (it)
4535 struct it *it;
4536 {
4537 struct iterator_stack_entry *p;
4538
4539 xassert (it->sp > 0);
4540 --it->sp;
4541 p = it->stack + it->sp;
4542 it->stop_charpos = p->stop_charpos;
4543 it->face_id = p->face_id;
4544 it->string = p->string;
4545 it->current = p->pos;
4546 it->end_charpos = p->end_charpos;
4547 it->string_nchars = p->string_nchars;
4548 it->area = p->area;
4549 it->multibyte_p = p->multibyte_p;
4550 it->slice = p->slice;
4551 it->space_width = p->space_width;
4552 it->font_height = p->font_height;
4553 it->voffset = p->voffset;
4554 it->string_from_display_prop_p = p->string_from_display_prop_p;
4555 }
4556
4557
4558 \f
4559 /***********************************************************************
4560 Moving over lines
4561 ***********************************************************************/
4562
4563 /* Set IT's current position to the previous line start. */
4564
4565 static void
4566 back_to_previous_line_start (it)
4567 struct it *it;
4568 {
4569 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4570 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4571 }
4572
4573
4574 /* Move IT to the next line start.
4575
4576 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4577 we skipped over part of the text (as opposed to moving the iterator
4578 continuously over the text). Otherwise, don't change the value
4579 of *SKIPPED_P.
4580
4581 Newlines may come from buffer text, overlay strings, or strings
4582 displayed via the `display' property. That's the reason we can't
4583 simply use find_next_newline_no_quit.
4584
4585 Note that this function may not skip over invisible text that is so
4586 because of text properties and immediately follows a newline. If
4587 it would, function reseat_at_next_visible_line_start, when called
4588 from set_iterator_to_next, would effectively make invisible
4589 characters following a newline part of the wrong glyph row, which
4590 leads to wrong cursor motion. */
4591
4592 static int
4593 forward_to_next_line_start (it, skipped_p)
4594 struct it *it;
4595 int *skipped_p;
4596 {
4597 int old_selective, newline_found_p, n;
4598 const int MAX_NEWLINE_DISTANCE = 500;
4599
4600 /* If already on a newline, just consume it to avoid unintended
4601 skipping over invisible text below. */
4602 if (it->what == IT_CHARACTER
4603 && it->c == '\n'
4604 && CHARPOS (it->position) == IT_CHARPOS (*it))
4605 {
4606 set_iterator_to_next (it, 0);
4607 it->c = 0;
4608 return 1;
4609 }
4610
4611 /* Don't handle selective display in the following. It's (a)
4612 unnecessary because it's done by the caller, and (b) leads to an
4613 infinite recursion because next_element_from_ellipsis indirectly
4614 calls this function. */
4615 old_selective = it->selective;
4616 it->selective = 0;
4617
4618 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4619 from buffer text. */
4620 for (n = newline_found_p = 0;
4621 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4622 n += STRINGP (it->string) ? 0 : 1)
4623 {
4624 if (!get_next_display_element (it))
4625 return 0;
4626 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4627 set_iterator_to_next (it, 0);
4628 }
4629
4630 /* If we didn't find a newline near enough, see if we can use a
4631 short-cut. */
4632 if (!newline_found_p)
4633 {
4634 int start = IT_CHARPOS (*it);
4635 int limit = find_next_newline_no_quit (start, 1);
4636 Lisp_Object pos;
4637
4638 xassert (!STRINGP (it->string));
4639
4640 /* If there isn't any `display' property in sight, and no
4641 overlays, we can just use the position of the newline in
4642 buffer text. */
4643 if (it->stop_charpos >= limit
4644 || ((pos = Fnext_single_property_change (make_number (start),
4645 Qdisplay,
4646 Qnil, make_number (limit)),
4647 NILP (pos))
4648 && next_overlay_change (start) == ZV))
4649 {
4650 IT_CHARPOS (*it) = limit;
4651 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4652 *skipped_p = newline_found_p = 1;
4653 }
4654 else
4655 {
4656 while (get_next_display_element (it)
4657 && !newline_found_p)
4658 {
4659 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4660 set_iterator_to_next (it, 0);
4661 }
4662 }
4663 }
4664
4665 it->selective = old_selective;
4666 return newline_found_p;
4667 }
4668
4669
4670 /* Set IT's current position to the previous visible line start. Skip
4671 invisible text that is so either due to text properties or due to
4672 selective display. Caution: this does not change IT->current_x and
4673 IT->hpos. */
4674
4675 static void
4676 back_to_previous_visible_line_start (it)
4677 struct it *it;
4678 {
4679 while (IT_CHARPOS (*it) > BEGV)
4680 {
4681 back_to_previous_line_start (it);
4682 if (IT_CHARPOS (*it) <= BEGV)
4683 break;
4684
4685 /* If selective > 0, then lines indented more than that values
4686 are invisible. */
4687 if (it->selective > 0
4688 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4689 (double) it->selective)) /* iftc */
4690 continue;
4691
4692 /* Check the newline before point for invisibility. */
4693 {
4694 Lisp_Object prop;
4695 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4696 Qinvisible, it->window);
4697 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4698 continue;
4699 }
4700
4701 /* If newline has a display property that replaces the newline with something
4702 else (image or text), find start of overlay or interval and continue search
4703 from that point. */
4704 if (IT_CHARPOS (*it) > BEGV)
4705 {
4706 struct it it2 = *it;
4707 int pos;
4708 int beg, end;
4709 Lisp_Object val, overlay;
4710
4711 pos = --IT_CHARPOS (it2);
4712 --IT_BYTEPOS (it2);
4713 it2.sp = 0;
4714 if (handle_display_prop (&it2) == HANDLED_RETURN
4715 && !NILP (val = get_char_property_and_overlay
4716 (make_number (pos), Qdisplay, Qnil, &overlay))
4717 && (OVERLAYP (overlay)
4718 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
4719 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
4720 {
4721 if (beg < BEGV)
4722 beg = BEGV;
4723 IT_CHARPOS (*it) = beg;
4724 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
4725 continue;
4726 }
4727 }
4728
4729 break;
4730 }
4731
4732 xassert (IT_CHARPOS (*it) >= BEGV);
4733 xassert (IT_CHARPOS (*it) == BEGV
4734 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4735 CHECK_IT (it);
4736 }
4737
4738
4739 /* Reseat iterator IT at the previous visible line start. Skip
4740 invisible text that is so either due to text properties or due to
4741 selective display. At the end, update IT's overlay information,
4742 face information etc. */
4743
4744 void
4745 reseat_at_previous_visible_line_start (it)
4746 struct it *it;
4747 {
4748 back_to_previous_visible_line_start (it);
4749 reseat (it, it->current.pos, 1);
4750 CHECK_IT (it);
4751 }
4752
4753
4754 /* Reseat iterator IT on the next visible line start in the current
4755 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4756 preceding the line start. Skip over invisible text that is so
4757 because of selective display. Compute faces, overlays etc at the
4758 new position. Note that this function does not skip over text that
4759 is invisible because of text properties. */
4760
4761 static void
4762 reseat_at_next_visible_line_start (it, on_newline_p)
4763 struct it *it;
4764 int on_newline_p;
4765 {
4766 int newline_found_p, skipped_p = 0;
4767
4768 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4769
4770 /* Skip over lines that are invisible because they are indented
4771 more than the value of IT->selective. */
4772 if (it->selective > 0)
4773 while (IT_CHARPOS (*it) < ZV
4774 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4775 (double) it->selective)) /* iftc */
4776 {
4777 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4778 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4779 }
4780
4781 /* Position on the newline if that's what's requested. */
4782 if (on_newline_p && newline_found_p)
4783 {
4784 if (STRINGP (it->string))
4785 {
4786 if (IT_STRING_CHARPOS (*it) > 0)
4787 {
4788 --IT_STRING_CHARPOS (*it);
4789 --IT_STRING_BYTEPOS (*it);
4790 }
4791 }
4792 else if (IT_CHARPOS (*it) > BEGV)
4793 {
4794 --IT_CHARPOS (*it);
4795 --IT_BYTEPOS (*it);
4796 reseat (it, it->current.pos, 0);
4797 }
4798 }
4799 else if (skipped_p)
4800 reseat (it, it->current.pos, 0);
4801
4802 CHECK_IT (it);
4803 }
4804
4805
4806 \f
4807 /***********************************************************************
4808 Changing an iterator's position
4809 ***********************************************************************/
4810
4811 /* Change IT's current position to POS in current_buffer. If FORCE_P
4812 is non-zero, always check for text properties at the new position.
4813 Otherwise, text properties are only looked up if POS >=
4814 IT->check_charpos of a property. */
4815
4816 static void
4817 reseat (it, pos, force_p)
4818 struct it *it;
4819 struct text_pos pos;
4820 int force_p;
4821 {
4822 int original_pos = IT_CHARPOS (*it);
4823
4824 reseat_1 (it, pos, 0);
4825
4826 /* Determine where to check text properties. Avoid doing it
4827 where possible because text property lookup is very expensive. */
4828 if (force_p
4829 || CHARPOS (pos) > it->stop_charpos
4830 || CHARPOS (pos) < original_pos)
4831 handle_stop (it);
4832
4833 CHECK_IT (it);
4834 }
4835
4836
4837 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4838 IT->stop_pos to POS, also. */
4839
4840 static void
4841 reseat_1 (it, pos, set_stop_p)
4842 struct it *it;
4843 struct text_pos pos;
4844 int set_stop_p;
4845 {
4846 /* Don't call this function when scanning a C string. */
4847 xassert (it->s == NULL);
4848
4849 /* POS must be a reasonable value. */
4850 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4851
4852 it->current.pos = it->position = pos;
4853 XSETBUFFER (it->object, current_buffer);
4854 it->end_charpos = ZV;
4855 it->dpvec = NULL;
4856 it->current.dpvec_index = -1;
4857 it->current.overlay_string_index = -1;
4858 IT_STRING_CHARPOS (*it) = -1;
4859 IT_STRING_BYTEPOS (*it) = -1;
4860 it->string = Qnil;
4861 it->method = GET_FROM_BUFFER;
4862 /* RMS: I added this to fix a bug in move_it_vertically_backward
4863 where it->area continued to relate to the starting point
4864 for the backward motion. Bug report from
4865 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4866 However, I am not sure whether reseat still does the right thing
4867 in general after this change. */
4868 it->area = TEXT_AREA;
4869 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4870 it->sp = 0;
4871 it->face_before_selective_p = 0;
4872
4873 if (set_stop_p)
4874 it->stop_charpos = CHARPOS (pos);
4875 }
4876
4877
4878 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4879 If S is non-null, it is a C string to iterate over. Otherwise,
4880 STRING gives a Lisp string to iterate over.
4881
4882 If PRECISION > 0, don't return more then PRECISION number of
4883 characters from the string.
4884
4885 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4886 characters have been returned. FIELD_WIDTH < 0 means an infinite
4887 field width.
4888
4889 MULTIBYTE = 0 means disable processing of multibyte characters,
4890 MULTIBYTE > 0 means enable it,
4891 MULTIBYTE < 0 means use IT->multibyte_p.
4892
4893 IT must be initialized via a prior call to init_iterator before
4894 calling this function. */
4895
4896 static void
4897 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4898 struct it *it;
4899 unsigned char *s;
4900 Lisp_Object string;
4901 int charpos;
4902 int precision, field_width, multibyte;
4903 {
4904 /* No region in strings. */
4905 it->region_beg_charpos = it->region_end_charpos = -1;
4906
4907 /* No text property checks performed by default, but see below. */
4908 it->stop_charpos = -1;
4909
4910 /* Set iterator position and end position. */
4911 bzero (&it->current, sizeof it->current);
4912 it->current.overlay_string_index = -1;
4913 it->current.dpvec_index = -1;
4914 xassert (charpos >= 0);
4915
4916 /* If STRING is specified, use its multibyteness, otherwise use the
4917 setting of MULTIBYTE, if specified. */
4918 if (multibyte >= 0)
4919 it->multibyte_p = multibyte > 0;
4920
4921 if (s == NULL)
4922 {
4923 xassert (STRINGP (string));
4924 it->string = string;
4925 it->s = NULL;
4926 it->end_charpos = it->string_nchars = SCHARS (string);
4927 it->method = GET_FROM_STRING;
4928 it->current.string_pos = string_pos (charpos, string);
4929 }
4930 else
4931 {
4932 it->s = s;
4933 it->string = Qnil;
4934
4935 /* Note that we use IT->current.pos, not it->current.string_pos,
4936 for displaying C strings. */
4937 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4938 if (it->multibyte_p)
4939 {
4940 it->current.pos = c_string_pos (charpos, s, 1);
4941 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4942 }
4943 else
4944 {
4945 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4946 it->end_charpos = it->string_nchars = strlen (s);
4947 }
4948
4949 it->method = GET_FROM_C_STRING;
4950 }
4951
4952 /* PRECISION > 0 means don't return more than PRECISION characters
4953 from the string. */
4954 if (precision > 0 && it->end_charpos - charpos > precision)
4955 it->end_charpos = it->string_nchars = charpos + precision;
4956
4957 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4958 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4959 FIELD_WIDTH < 0 means infinite field width. This is useful for
4960 padding with `-' at the end of a mode line. */
4961 if (field_width < 0)
4962 field_width = INFINITY;
4963 if (field_width > it->end_charpos - charpos)
4964 it->end_charpos = charpos + field_width;
4965
4966 /* Use the standard display table for displaying strings. */
4967 if (DISP_TABLE_P (Vstandard_display_table))
4968 it->dp = XCHAR_TABLE (Vstandard_display_table);
4969
4970 it->stop_charpos = charpos;
4971 CHECK_IT (it);
4972 }
4973
4974
4975 \f
4976 /***********************************************************************
4977 Iteration
4978 ***********************************************************************/
4979
4980 /* Map enum it_method value to corresponding next_element_from_* function. */
4981
4982 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
4983 {
4984 next_element_from_buffer,
4985 next_element_from_display_vector,
4986 next_element_from_composition,
4987 next_element_from_string,
4988 next_element_from_c_string,
4989 next_element_from_image,
4990 next_element_from_stretch
4991 };
4992
4993
4994 /* Load IT's display element fields with information about the next
4995 display element from the current position of IT. Value is zero if
4996 end of buffer (or C string) is reached. */
4997
4998 int
4999 get_next_display_element (it)
5000 struct it *it;
5001 {
5002 /* Non-zero means that we found a display element. Zero means that
5003 we hit the end of what we iterate over. Performance note: the
5004 function pointer `method' used here turns out to be faster than
5005 using a sequence of if-statements. */
5006 int success_p;
5007
5008 get_next:
5009 success_p = (*get_next_element[it->method]) (it);
5010
5011 if (it->what == IT_CHARACTER)
5012 {
5013 /* Map via display table or translate control characters.
5014 IT->c, IT->len etc. have been set to the next character by
5015 the function call above. If we have a display table, and it
5016 contains an entry for IT->c, translate it. Don't do this if
5017 IT->c itself comes from a display table, otherwise we could
5018 end up in an infinite recursion. (An alternative could be to
5019 count the recursion depth of this function and signal an
5020 error when a certain maximum depth is reached.) Is it worth
5021 it? */
5022 if (success_p && it->dpvec == NULL)
5023 {
5024 Lisp_Object dv;
5025
5026 if (it->dp
5027 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5028 VECTORP (dv)))
5029 {
5030 struct Lisp_Vector *v = XVECTOR (dv);
5031
5032 /* Return the first character from the display table
5033 entry, if not empty. If empty, don't display the
5034 current character. */
5035 if (v->size)
5036 {
5037 it->dpvec_char_len = it->len;
5038 it->dpvec = v->contents;
5039 it->dpend = v->contents + v->size;
5040 it->current.dpvec_index = 0;
5041 it->dpvec_face_id = -1;
5042 it->saved_face_id = it->face_id;
5043 it->method = GET_FROM_DISPLAY_VECTOR;
5044 it->ellipsis_p = 0;
5045 }
5046 else
5047 {
5048 set_iterator_to_next (it, 0);
5049 }
5050 goto get_next;
5051 }
5052
5053 /* Translate control characters into `\003' or `^C' form.
5054 Control characters coming from a display table entry are
5055 currently not translated because we use IT->dpvec to hold
5056 the translation. This could easily be changed but I
5057 don't believe that it is worth doing.
5058
5059 If it->multibyte_p is nonzero, eight-bit characters and
5060 non-printable multibyte characters are also translated to
5061 octal form.
5062
5063 If it->multibyte_p is zero, eight-bit characters that
5064 don't have corresponding multibyte char code are also
5065 translated to octal form. */
5066 else if ((it->c < ' '
5067 && (it->area != TEXT_AREA
5068 /* In mode line, treat \n like other crl chars. */
5069 || (it->c != '\t'
5070 && it->glyph_row && it->glyph_row->mode_line_p)
5071 || (it->c != '\n' && it->c != '\t')))
5072 || (it->multibyte_p
5073 ? ((it->c >= 127
5074 && it->len == 1)
5075 || !CHAR_PRINTABLE_P (it->c)
5076 || (!NILP (Vshow_nonbreak_escape)
5077 && (it->c == 0x8ad || it->c == 0x8a0)))
5078 : (it->c >= 127
5079 && (!unibyte_display_via_language_environment
5080 || it->c == unibyte_char_to_multibyte (it->c)))))
5081 {
5082 /* IT->c is a control character which must be displayed
5083 either as '\003' or as `^C' where the '\\' and '^'
5084 can be defined in the display table. Fill
5085 IT->ctl_chars with glyphs for what we have to
5086 display. Then, set IT->dpvec to these glyphs. */
5087 GLYPH g;
5088 int ctl_len;
5089 int face_id, lface_id = 0 ;
5090 GLYPH escape_glyph;
5091
5092 if (it->c < 128 && it->ctl_arrow_p)
5093 {
5094 g = '^'; /* default glyph for Control */
5095 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5096 if (it->dp
5097 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5098 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5099 {
5100 g = XINT (DISP_CTRL_GLYPH (it->dp));
5101 lface_id = FAST_GLYPH_FACE (g);
5102 }
5103 if (lface_id)
5104 {
5105 g = FAST_GLYPH_CHAR (g);
5106 face_id = merge_faces (it->f, Qt, lface_id,
5107 it->face_id);
5108 }
5109 else
5110 {
5111 /* Merge the escape-glyph face into the current face. */
5112 face_id = merge_faces (it->f, Qescape_glyph, 0,
5113 it->face_id);
5114 }
5115
5116 XSETINT (it->ctl_chars[0], g);
5117 g = it->c ^ 0100;
5118 XSETINT (it->ctl_chars[1], g);
5119 ctl_len = 2;
5120 goto display_control;
5121 }
5122
5123 escape_glyph = '\\'; /* default for Octal display */
5124 if (it->dp
5125 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5126 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5127 {
5128 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5129 lface_id = FAST_GLYPH_FACE (escape_glyph);
5130 }
5131 if (lface_id)
5132 {
5133 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5134 face_id = merge_faces (it->f, Qt, lface_id,
5135 it->face_id);
5136 }
5137 else
5138 {
5139 /* Merge the escape-glyph face into the current face. */
5140 face_id = merge_faces (it->f, Qescape_glyph, 0,
5141 it->face_id);
5142 }
5143
5144 if (it->c == 0x8a0 || it->c == 0x8ad)
5145 {
5146 XSETINT (it->ctl_chars[0], escape_glyph);
5147 g = it->c == 0x8ad ? '-' : ' ';
5148 XSETINT (it->ctl_chars[1], g);
5149 ctl_len = 2;
5150 goto display_control;
5151 }
5152
5153 {
5154 unsigned char str[MAX_MULTIBYTE_LENGTH];
5155 int len;
5156 int i;
5157
5158 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5159 if (SINGLE_BYTE_CHAR_P (it->c))
5160 str[0] = it->c, len = 1;
5161 else
5162 {
5163 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5164 if (len < 0)
5165 {
5166 /* It's an invalid character, which shouldn't
5167 happen actually, but due to bugs it may
5168 happen. Let's print the char as is, there's
5169 not much meaningful we can do with it. */
5170 str[0] = it->c;
5171 str[1] = it->c >> 8;
5172 str[2] = it->c >> 16;
5173 str[3] = it->c >> 24;
5174 len = 4;
5175 }
5176 }
5177
5178 for (i = 0; i < len; i++)
5179 {
5180 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5181 /* Insert three more glyphs into IT->ctl_chars for
5182 the octal display of the character. */
5183 g = ((str[i] >> 6) & 7) + '0';
5184 XSETINT (it->ctl_chars[i * 4 + 1], g);
5185 g = ((str[i] >> 3) & 7) + '0';
5186 XSETINT (it->ctl_chars[i * 4 + 2], g);
5187 g = (str[i] & 7) + '0';
5188 XSETINT (it->ctl_chars[i * 4 + 3], g);
5189 }
5190 ctl_len = len * 4;
5191 }
5192
5193 display_control:
5194 /* Set up IT->dpvec and return first character from it. */
5195 it->dpvec_char_len = it->len;
5196 it->dpvec = it->ctl_chars;
5197 it->dpend = it->dpvec + ctl_len;
5198 it->current.dpvec_index = 0;
5199 it->dpvec_face_id = face_id;
5200 it->saved_face_id = it->face_id;
5201 it->method = GET_FROM_DISPLAY_VECTOR;
5202 it->ellipsis_p = 0;
5203 goto get_next;
5204 }
5205 }
5206
5207 /* Adjust face id for a multibyte character. There are no
5208 multibyte character in unibyte text. */
5209 if (it->multibyte_p
5210 && success_p
5211 && FRAME_WINDOW_P (it->f))
5212 {
5213 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5214 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5215 }
5216 }
5217
5218 /* Is this character the last one of a run of characters with
5219 box? If yes, set IT->end_of_box_run_p to 1. */
5220 if (it->face_box_p
5221 && it->s == NULL)
5222 {
5223 int face_id;
5224 struct face *face;
5225
5226 it->end_of_box_run_p
5227 = ((face_id = face_after_it_pos (it),
5228 face_id != it->face_id)
5229 && (face = FACE_FROM_ID (it->f, face_id),
5230 face->box == FACE_NO_BOX));
5231 }
5232
5233 /* Value is 0 if end of buffer or string reached. */
5234 return success_p;
5235 }
5236
5237
5238 /* Move IT to the next display element.
5239
5240 RESEAT_P non-zero means if called on a newline in buffer text,
5241 skip to the next visible line start.
5242
5243 Functions get_next_display_element and set_iterator_to_next are
5244 separate because I find this arrangement easier to handle than a
5245 get_next_display_element function that also increments IT's
5246 position. The way it is we can first look at an iterator's current
5247 display element, decide whether it fits on a line, and if it does,
5248 increment the iterator position. The other way around we probably
5249 would either need a flag indicating whether the iterator has to be
5250 incremented the next time, or we would have to implement a
5251 decrement position function which would not be easy to write. */
5252
5253 void
5254 set_iterator_to_next (it, reseat_p)
5255 struct it *it;
5256 int reseat_p;
5257 {
5258 /* Reset flags indicating start and end of a sequence of characters
5259 with box. Reset them at the start of this function because
5260 moving the iterator to a new position might set them. */
5261 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5262
5263 switch (it->method)
5264 {
5265 case GET_FROM_BUFFER:
5266 /* The current display element of IT is a character from
5267 current_buffer. Advance in the buffer, and maybe skip over
5268 invisible lines that are so because of selective display. */
5269 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5270 reseat_at_next_visible_line_start (it, 0);
5271 else
5272 {
5273 xassert (it->len != 0);
5274 IT_BYTEPOS (*it) += it->len;
5275 IT_CHARPOS (*it) += 1;
5276 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5277 }
5278 break;
5279
5280 case GET_FROM_COMPOSITION:
5281 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5282 if (STRINGP (it->string))
5283 {
5284 IT_STRING_BYTEPOS (*it) += it->len;
5285 IT_STRING_CHARPOS (*it) += it->cmp_len;
5286 it->method = GET_FROM_STRING;
5287 goto consider_string_end;
5288 }
5289 else
5290 {
5291 IT_BYTEPOS (*it) += it->len;
5292 IT_CHARPOS (*it) += it->cmp_len;
5293 it->method = GET_FROM_BUFFER;
5294 }
5295 break;
5296
5297 case GET_FROM_C_STRING:
5298 /* Current display element of IT is from a C string. */
5299 IT_BYTEPOS (*it) += it->len;
5300 IT_CHARPOS (*it) += 1;
5301 break;
5302
5303 case GET_FROM_DISPLAY_VECTOR:
5304 /* Current display element of IT is from a display table entry.
5305 Advance in the display table definition. Reset it to null if
5306 end reached, and continue with characters from buffers/
5307 strings. */
5308 ++it->current.dpvec_index;
5309
5310 /* Restore face of the iterator to what they were before the
5311 display vector entry (these entries may contain faces). */
5312 it->face_id = it->saved_face_id;
5313
5314 if (it->dpvec + it->current.dpvec_index == it->dpend)
5315 {
5316 if (it->s)
5317 it->method = GET_FROM_C_STRING;
5318 else if (STRINGP (it->string))
5319 it->method = GET_FROM_STRING;
5320 else
5321 it->method = GET_FROM_BUFFER;
5322
5323 it->dpvec = NULL;
5324 it->current.dpvec_index = -1;
5325
5326 /* Skip over characters which were displayed via IT->dpvec. */
5327 if (it->dpvec_char_len < 0)
5328 reseat_at_next_visible_line_start (it, 1);
5329 else if (it->dpvec_char_len > 0)
5330 {
5331 it->len = it->dpvec_char_len;
5332 set_iterator_to_next (it, reseat_p);
5333 }
5334
5335 /* Recheck faces after display vector */
5336 it->stop_charpos = IT_CHARPOS (*it);
5337 }
5338 break;
5339
5340 case GET_FROM_STRING:
5341 /* Current display element is a character from a Lisp string. */
5342 xassert (it->s == NULL && STRINGP (it->string));
5343 IT_STRING_BYTEPOS (*it) += it->len;
5344 IT_STRING_CHARPOS (*it) += 1;
5345
5346 consider_string_end:
5347
5348 if (it->current.overlay_string_index >= 0)
5349 {
5350 /* IT->string is an overlay string. Advance to the
5351 next, if there is one. */
5352 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5353 next_overlay_string (it);
5354 }
5355 else
5356 {
5357 /* IT->string is not an overlay string. If we reached
5358 its end, and there is something on IT->stack, proceed
5359 with what is on the stack. This can be either another
5360 string, this time an overlay string, or a buffer. */
5361 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5362 && it->sp > 0)
5363 {
5364 pop_it (it);
5365 if (STRINGP (it->string))
5366 goto consider_string_end;
5367 it->method = GET_FROM_BUFFER;
5368 }
5369 }
5370 break;
5371
5372 case GET_FROM_IMAGE:
5373 case GET_FROM_STRETCH:
5374 /* The position etc with which we have to proceed are on
5375 the stack. The position may be at the end of a string,
5376 if the `display' property takes up the whole string. */
5377 xassert (it->sp > 0);
5378 pop_it (it);
5379 it->image_id = 0;
5380 if (STRINGP (it->string))
5381 {
5382 it->method = GET_FROM_STRING;
5383 goto consider_string_end;
5384 }
5385 it->method = GET_FROM_BUFFER;
5386 break;
5387
5388 default:
5389 /* There are no other methods defined, so this should be a bug. */
5390 abort ();
5391 }
5392
5393 xassert (it->method != GET_FROM_STRING
5394 || (STRINGP (it->string)
5395 && IT_STRING_CHARPOS (*it) >= 0));
5396 }
5397
5398 /* Load IT's display element fields with information about the next
5399 display element which comes from a display table entry or from the
5400 result of translating a control character to one of the forms `^C'
5401 or `\003'.
5402
5403 IT->dpvec holds the glyphs to return as characters.
5404 IT->saved_face_id holds the face id before the display vector--
5405 it is restored into IT->face_idin set_iterator_to_next. */
5406
5407 static int
5408 next_element_from_display_vector (it)
5409 struct it *it;
5410 {
5411 /* Precondition. */
5412 xassert (it->dpvec && it->current.dpvec_index >= 0);
5413
5414 if (INTEGERP (*it->dpvec)
5415 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5416 {
5417 GLYPH g;
5418
5419 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5420 it->c = FAST_GLYPH_CHAR (g);
5421 it->len = CHAR_BYTES (it->c);
5422
5423 /* The entry may contain a face id to use. Such a face id is
5424 the id of a Lisp face, not a realized face. A face id of
5425 zero means no face is specified. */
5426 if (it->dpvec_face_id >= 0)
5427 it->face_id = it->dpvec_face_id;
5428 else
5429 {
5430 int lface_id = FAST_GLYPH_FACE (g);
5431 if (lface_id > 0)
5432 it->face_id = merge_faces (it->f, Qt, lface_id,
5433 it->saved_face_id);
5434 }
5435 }
5436 else
5437 /* Display table entry is invalid. Return a space. */
5438 it->c = ' ', it->len = 1;
5439
5440 /* Don't change position and object of the iterator here. They are
5441 still the values of the character that had this display table
5442 entry or was translated, and that's what we want. */
5443 it->what = IT_CHARACTER;
5444 return 1;
5445 }
5446
5447
5448 /* Load IT with the next display element from Lisp string IT->string.
5449 IT->current.string_pos is the current position within the string.
5450 If IT->current.overlay_string_index >= 0, the Lisp string is an
5451 overlay string. */
5452
5453 static int
5454 next_element_from_string (it)
5455 struct it *it;
5456 {
5457 struct text_pos position;
5458
5459 xassert (STRINGP (it->string));
5460 xassert (IT_STRING_CHARPOS (*it) >= 0);
5461 position = it->current.string_pos;
5462
5463 /* Time to check for invisible text? */
5464 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5465 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5466 {
5467 handle_stop (it);
5468
5469 /* Since a handler may have changed IT->method, we must
5470 recurse here. */
5471 return get_next_display_element (it);
5472 }
5473
5474 if (it->current.overlay_string_index >= 0)
5475 {
5476 /* Get the next character from an overlay string. In overlay
5477 strings, There is no field width or padding with spaces to
5478 do. */
5479 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5480 {
5481 it->what = IT_EOB;
5482 return 0;
5483 }
5484 else if (STRING_MULTIBYTE (it->string))
5485 {
5486 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5487 const unsigned char *s = (SDATA (it->string)
5488 + IT_STRING_BYTEPOS (*it));
5489 it->c = string_char_and_length (s, remaining, &it->len);
5490 }
5491 else
5492 {
5493 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5494 it->len = 1;
5495 }
5496 }
5497 else
5498 {
5499 /* Get the next character from a Lisp string that is not an
5500 overlay string. Such strings come from the mode line, for
5501 example. We may have to pad with spaces, or truncate the
5502 string. See also next_element_from_c_string. */
5503 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5504 {
5505 it->what = IT_EOB;
5506 return 0;
5507 }
5508 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5509 {
5510 /* Pad with spaces. */
5511 it->c = ' ', it->len = 1;
5512 CHARPOS (position) = BYTEPOS (position) = -1;
5513 }
5514 else if (STRING_MULTIBYTE (it->string))
5515 {
5516 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5517 const unsigned char *s = (SDATA (it->string)
5518 + IT_STRING_BYTEPOS (*it));
5519 it->c = string_char_and_length (s, maxlen, &it->len);
5520 }
5521 else
5522 {
5523 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5524 it->len = 1;
5525 }
5526 }
5527
5528 /* Record what we have and where it came from. Note that we store a
5529 buffer position in IT->position although it could arguably be a
5530 string position. */
5531 it->what = IT_CHARACTER;
5532 it->object = it->string;
5533 it->position = position;
5534 return 1;
5535 }
5536
5537
5538 /* Load IT with next display element from C string IT->s.
5539 IT->string_nchars is the maximum number of characters to return
5540 from the string. IT->end_charpos may be greater than
5541 IT->string_nchars when this function is called, in which case we
5542 may have to return padding spaces. Value is zero if end of string
5543 reached, including padding spaces. */
5544
5545 static int
5546 next_element_from_c_string (it)
5547 struct it *it;
5548 {
5549 int success_p = 1;
5550
5551 xassert (it->s);
5552 it->what = IT_CHARACTER;
5553 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5554 it->object = Qnil;
5555
5556 /* IT's position can be greater IT->string_nchars in case a field
5557 width or precision has been specified when the iterator was
5558 initialized. */
5559 if (IT_CHARPOS (*it) >= it->end_charpos)
5560 {
5561 /* End of the game. */
5562 it->what = IT_EOB;
5563 success_p = 0;
5564 }
5565 else if (IT_CHARPOS (*it) >= it->string_nchars)
5566 {
5567 /* Pad with spaces. */
5568 it->c = ' ', it->len = 1;
5569 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5570 }
5571 else if (it->multibyte_p)
5572 {
5573 /* Implementation note: The calls to strlen apparently aren't a
5574 performance problem because there is no noticeable performance
5575 difference between Emacs running in unibyte or multibyte mode. */
5576 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5577 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5578 maxlen, &it->len);
5579 }
5580 else
5581 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5582
5583 return success_p;
5584 }
5585
5586
5587 /* Set up IT to return characters from an ellipsis, if appropriate.
5588 The definition of the ellipsis glyphs may come from a display table
5589 entry. This function Fills IT with the first glyph from the
5590 ellipsis if an ellipsis is to be displayed. */
5591
5592 static int
5593 next_element_from_ellipsis (it)
5594 struct it *it;
5595 {
5596 if (it->selective_display_ellipsis_p)
5597 setup_for_ellipsis (it, it->len);
5598 else
5599 {
5600 /* The face at the current position may be different from the
5601 face we find after the invisible text. Remember what it
5602 was in IT->saved_face_id, and signal that it's there by
5603 setting face_before_selective_p. */
5604 it->saved_face_id = it->face_id;
5605 it->method = GET_FROM_BUFFER;
5606 reseat_at_next_visible_line_start (it, 1);
5607 it->face_before_selective_p = 1;
5608 }
5609
5610 return get_next_display_element (it);
5611 }
5612
5613
5614 /* Deliver an image display element. The iterator IT is already
5615 filled with image information (done in handle_display_prop). Value
5616 is always 1. */
5617
5618
5619 static int
5620 next_element_from_image (it)
5621 struct it *it;
5622 {
5623 it->what = IT_IMAGE;
5624 return 1;
5625 }
5626
5627
5628 /* Fill iterator IT with next display element from a stretch glyph
5629 property. IT->object is the value of the text property. Value is
5630 always 1. */
5631
5632 static int
5633 next_element_from_stretch (it)
5634 struct it *it;
5635 {
5636 it->what = IT_STRETCH;
5637 return 1;
5638 }
5639
5640
5641 /* Load IT with the next display element from current_buffer. Value
5642 is zero if end of buffer reached. IT->stop_charpos is the next
5643 position at which to stop and check for text properties or buffer
5644 end. */
5645
5646 static int
5647 next_element_from_buffer (it)
5648 struct it *it;
5649 {
5650 int success_p = 1;
5651
5652 /* Check this assumption, otherwise, we would never enter the
5653 if-statement, below. */
5654 xassert (IT_CHARPOS (*it) >= BEGV
5655 && IT_CHARPOS (*it) <= it->stop_charpos);
5656
5657 if (IT_CHARPOS (*it) >= it->stop_charpos)
5658 {
5659 if (IT_CHARPOS (*it) >= it->end_charpos)
5660 {
5661 int overlay_strings_follow_p;
5662
5663 /* End of the game, except when overlay strings follow that
5664 haven't been returned yet. */
5665 if (it->overlay_strings_at_end_processed_p)
5666 overlay_strings_follow_p = 0;
5667 else
5668 {
5669 it->overlay_strings_at_end_processed_p = 1;
5670 overlay_strings_follow_p = get_overlay_strings (it, 0);
5671 }
5672
5673 if (overlay_strings_follow_p)
5674 success_p = get_next_display_element (it);
5675 else
5676 {
5677 it->what = IT_EOB;
5678 it->position = it->current.pos;
5679 success_p = 0;
5680 }
5681 }
5682 else
5683 {
5684 handle_stop (it);
5685 return get_next_display_element (it);
5686 }
5687 }
5688 else
5689 {
5690 /* No face changes, overlays etc. in sight, so just return a
5691 character from current_buffer. */
5692 unsigned char *p;
5693
5694 /* Maybe run the redisplay end trigger hook. Performance note:
5695 This doesn't seem to cost measurable time. */
5696 if (it->redisplay_end_trigger_charpos
5697 && it->glyph_row
5698 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5699 run_redisplay_end_trigger_hook (it);
5700
5701 /* Get the next character, maybe multibyte. */
5702 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5703 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5704 {
5705 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5706 - IT_BYTEPOS (*it));
5707 it->c = string_char_and_length (p, maxlen, &it->len);
5708 }
5709 else
5710 it->c = *p, it->len = 1;
5711
5712 /* Record what we have and where it came from. */
5713 it->what = IT_CHARACTER;;
5714 it->object = it->w->buffer;
5715 it->position = it->current.pos;
5716
5717 /* Normally we return the character found above, except when we
5718 really want to return an ellipsis for selective display. */
5719 if (it->selective)
5720 {
5721 if (it->c == '\n')
5722 {
5723 /* A value of selective > 0 means hide lines indented more
5724 than that number of columns. */
5725 if (it->selective > 0
5726 && IT_CHARPOS (*it) + 1 < ZV
5727 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5728 IT_BYTEPOS (*it) + 1,
5729 (double) it->selective)) /* iftc */
5730 {
5731 success_p = next_element_from_ellipsis (it);
5732 it->dpvec_char_len = -1;
5733 }
5734 }
5735 else if (it->c == '\r' && it->selective == -1)
5736 {
5737 /* A value of selective == -1 means that everything from the
5738 CR to the end of the line is invisible, with maybe an
5739 ellipsis displayed for it. */
5740 success_p = next_element_from_ellipsis (it);
5741 it->dpvec_char_len = -1;
5742 }
5743 }
5744 }
5745
5746 /* Value is zero if end of buffer reached. */
5747 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5748 return success_p;
5749 }
5750
5751
5752 /* Run the redisplay end trigger hook for IT. */
5753
5754 static void
5755 run_redisplay_end_trigger_hook (it)
5756 struct it *it;
5757 {
5758 Lisp_Object args[3];
5759
5760 /* IT->glyph_row should be non-null, i.e. we should be actually
5761 displaying something, or otherwise we should not run the hook. */
5762 xassert (it->glyph_row);
5763
5764 /* Set up hook arguments. */
5765 args[0] = Qredisplay_end_trigger_functions;
5766 args[1] = it->window;
5767 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5768 it->redisplay_end_trigger_charpos = 0;
5769
5770 /* Since we are *trying* to run these functions, don't try to run
5771 them again, even if they get an error. */
5772 it->w->redisplay_end_trigger = Qnil;
5773 Frun_hook_with_args (3, args);
5774
5775 /* Notice if it changed the face of the character we are on. */
5776 handle_face_prop (it);
5777 }
5778
5779
5780 /* Deliver a composition display element. The iterator IT is already
5781 filled with composition information (done in
5782 handle_composition_prop). Value is always 1. */
5783
5784 static int
5785 next_element_from_composition (it)
5786 struct it *it;
5787 {
5788 it->what = IT_COMPOSITION;
5789 it->position = (STRINGP (it->string)
5790 ? it->current.string_pos
5791 : it->current.pos);
5792 return 1;
5793 }
5794
5795
5796 \f
5797 /***********************************************************************
5798 Moving an iterator without producing glyphs
5799 ***********************************************************************/
5800
5801 /* Move iterator IT to a specified buffer or X position within one
5802 line on the display without producing glyphs.
5803
5804 OP should be a bit mask including some or all of these bits:
5805 MOVE_TO_X: Stop on reaching x-position TO_X.
5806 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5807 Regardless of OP's value, stop in reaching the end of the display line.
5808
5809 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5810 This means, in particular, that TO_X includes window's horizontal
5811 scroll amount.
5812
5813 The return value has several possible values that
5814 say what condition caused the scan to stop:
5815
5816 MOVE_POS_MATCH_OR_ZV
5817 - when TO_POS or ZV was reached.
5818
5819 MOVE_X_REACHED
5820 -when TO_X was reached before TO_POS or ZV were reached.
5821
5822 MOVE_LINE_CONTINUED
5823 - when we reached the end of the display area and the line must
5824 be continued.
5825
5826 MOVE_LINE_TRUNCATED
5827 - when we reached the end of the display area and the line is
5828 truncated.
5829
5830 MOVE_NEWLINE_OR_CR
5831 - when we stopped at a line end, i.e. a newline or a CR and selective
5832 display is on. */
5833
5834 static enum move_it_result
5835 move_it_in_display_line_to (it, to_charpos, to_x, op)
5836 struct it *it;
5837 int to_charpos, to_x, op;
5838 {
5839 enum move_it_result result = MOVE_UNDEFINED;
5840 struct glyph_row *saved_glyph_row;
5841
5842 /* Don't produce glyphs in produce_glyphs. */
5843 saved_glyph_row = it->glyph_row;
5844 it->glyph_row = NULL;
5845
5846 #define BUFFER_POS_REACHED_P() \
5847 ((op & MOVE_TO_POS) != 0 \
5848 && BUFFERP (it->object) \
5849 && IT_CHARPOS (*it) >= to_charpos \
5850 && (it->method == GET_FROM_BUFFER \
5851 || (it->method == GET_FROM_DISPLAY_VECTOR \
5852 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
5853
5854
5855 while (1)
5856 {
5857 int x, i, ascent = 0, descent = 0;
5858
5859 /* Stop when ZV reached.
5860 We used to stop here when TO_CHARPOS reached as well, but that is
5861 too soon if this glyph does not fit on this line. So we handle it
5862 explicitly below. */
5863 if (!get_next_display_element (it)
5864 || (it->truncate_lines_p
5865 && BUFFER_POS_REACHED_P ()))
5866 {
5867 result = MOVE_POS_MATCH_OR_ZV;
5868 break;
5869 }
5870
5871 /* The call to produce_glyphs will get the metrics of the
5872 display element IT is loaded with. We record in x the
5873 x-position before this display element in case it does not
5874 fit on the line. */
5875 x = it->current_x;
5876
5877 /* Remember the line height so far in case the next element doesn't
5878 fit on the line. */
5879 if (!it->truncate_lines_p)
5880 {
5881 ascent = it->max_ascent;
5882 descent = it->max_descent;
5883 }
5884
5885 PRODUCE_GLYPHS (it);
5886
5887 if (it->area != TEXT_AREA)
5888 {
5889 set_iterator_to_next (it, 1);
5890 continue;
5891 }
5892
5893 /* The number of glyphs we get back in IT->nglyphs will normally
5894 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5895 character on a terminal frame, or (iii) a line end. For the
5896 second case, IT->nglyphs - 1 padding glyphs will be present
5897 (on X frames, there is only one glyph produced for a
5898 composite character.
5899
5900 The behavior implemented below means, for continuation lines,
5901 that as many spaces of a TAB as fit on the current line are
5902 displayed there. For terminal frames, as many glyphs of a
5903 multi-glyph character are displayed in the current line, too.
5904 This is what the old redisplay code did, and we keep it that
5905 way. Under X, the whole shape of a complex character must
5906 fit on the line or it will be completely displayed in the
5907 next line.
5908
5909 Note that both for tabs and padding glyphs, all glyphs have
5910 the same width. */
5911 if (it->nglyphs)
5912 {
5913 /* More than one glyph or glyph doesn't fit on line. All
5914 glyphs have the same width. */
5915 int single_glyph_width = it->pixel_width / it->nglyphs;
5916 int new_x;
5917
5918 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5919 {
5920 new_x = x + single_glyph_width;
5921
5922 /* We want to leave anything reaching TO_X to the caller. */
5923 if ((op & MOVE_TO_X) && new_x > to_x)
5924 {
5925 if (BUFFER_POS_REACHED_P ())
5926 goto buffer_pos_reached;
5927 it->current_x = x;
5928 result = MOVE_X_REACHED;
5929 break;
5930 }
5931 else if (/* Lines are continued. */
5932 !it->truncate_lines_p
5933 && (/* And glyph doesn't fit on the line. */
5934 new_x > it->last_visible_x
5935 /* Or it fits exactly and we're on a window
5936 system frame. */
5937 || (new_x == it->last_visible_x
5938 && FRAME_WINDOW_P (it->f))))
5939 {
5940 if (/* IT->hpos == 0 means the very first glyph
5941 doesn't fit on the line, e.g. a wide image. */
5942 it->hpos == 0
5943 || (new_x == it->last_visible_x
5944 && FRAME_WINDOW_P (it->f)))
5945 {
5946 ++it->hpos;
5947 it->current_x = new_x;
5948 if (i == it->nglyphs - 1)
5949 {
5950 set_iterator_to_next (it, 1);
5951 #ifdef HAVE_WINDOW_SYSTEM
5952 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5953 {
5954 if (!get_next_display_element (it))
5955 {
5956 result = MOVE_POS_MATCH_OR_ZV;
5957 break;
5958 }
5959 if (BUFFER_POS_REACHED_P ())
5960 {
5961 if (ITERATOR_AT_END_OF_LINE_P (it))
5962 result = MOVE_POS_MATCH_OR_ZV;
5963 else
5964 result = MOVE_LINE_CONTINUED;
5965 break;
5966 }
5967 if (ITERATOR_AT_END_OF_LINE_P (it))
5968 {
5969 result = MOVE_NEWLINE_OR_CR;
5970 break;
5971 }
5972 }
5973 #endif /* HAVE_WINDOW_SYSTEM */
5974 }
5975 }
5976 else
5977 {
5978 it->current_x = x;
5979 it->max_ascent = ascent;
5980 it->max_descent = descent;
5981 }
5982
5983 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
5984 IT_CHARPOS (*it)));
5985 result = MOVE_LINE_CONTINUED;
5986 break;
5987 }
5988 else if (BUFFER_POS_REACHED_P ())
5989 goto buffer_pos_reached;
5990 else if (new_x > it->first_visible_x)
5991 {
5992 /* Glyph is visible. Increment number of glyphs that
5993 would be displayed. */
5994 ++it->hpos;
5995 }
5996 else
5997 {
5998 /* Glyph is completely off the left margin of the display
5999 area. Nothing to do. */
6000 }
6001 }
6002
6003 if (result != MOVE_UNDEFINED)
6004 break;
6005 }
6006 else if (BUFFER_POS_REACHED_P ())
6007 {
6008 buffer_pos_reached:
6009 it->current_x = x;
6010 it->max_ascent = ascent;
6011 it->max_descent = descent;
6012 result = MOVE_POS_MATCH_OR_ZV;
6013 break;
6014 }
6015 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6016 {
6017 /* Stop when TO_X specified and reached. This check is
6018 necessary here because of lines consisting of a line end,
6019 only. The line end will not produce any glyphs and we
6020 would never get MOVE_X_REACHED. */
6021 xassert (it->nglyphs == 0);
6022 result = MOVE_X_REACHED;
6023 break;
6024 }
6025
6026 /* Is this a line end? If yes, we're done. */
6027 if (ITERATOR_AT_END_OF_LINE_P (it))
6028 {
6029 result = MOVE_NEWLINE_OR_CR;
6030 break;
6031 }
6032
6033 /* The current display element has been consumed. Advance
6034 to the next. */
6035 set_iterator_to_next (it, 1);
6036
6037 /* Stop if lines are truncated and IT's current x-position is
6038 past the right edge of the window now. */
6039 if (it->truncate_lines_p
6040 && it->current_x >= it->last_visible_x)
6041 {
6042 #ifdef HAVE_WINDOW_SYSTEM
6043 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6044 {
6045 if (!get_next_display_element (it)
6046 || BUFFER_POS_REACHED_P ())
6047 {
6048 result = MOVE_POS_MATCH_OR_ZV;
6049 break;
6050 }
6051 if (ITERATOR_AT_END_OF_LINE_P (it))
6052 {
6053 result = MOVE_NEWLINE_OR_CR;
6054 break;
6055 }
6056 }
6057 #endif /* HAVE_WINDOW_SYSTEM */
6058 result = MOVE_LINE_TRUNCATED;
6059 break;
6060 }
6061 }
6062
6063 #undef BUFFER_POS_REACHED_P
6064
6065 /* Restore the iterator settings altered at the beginning of this
6066 function. */
6067 it->glyph_row = saved_glyph_row;
6068 return result;
6069 }
6070
6071
6072 /* Move IT forward until it satisfies one or more of the criteria in
6073 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6074
6075 OP is a bit-mask that specifies where to stop, and in particular,
6076 which of those four position arguments makes a difference. See the
6077 description of enum move_operation_enum.
6078
6079 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6080 screen line, this function will set IT to the next position >
6081 TO_CHARPOS. */
6082
6083 void
6084 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6085 struct it *it;
6086 int to_charpos, to_x, to_y, to_vpos;
6087 int op;
6088 {
6089 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6090 int line_height;
6091 int reached = 0;
6092
6093 for (;;)
6094 {
6095 if (op & MOVE_TO_VPOS)
6096 {
6097 /* If no TO_CHARPOS and no TO_X specified, stop at the
6098 start of the line TO_VPOS. */
6099 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6100 {
6101 if (it->vpos == to_vpos)
6102 {
6103 reached = 1;
6104 break;
6105 }
6106 else
6107 skip = move_it_in_display_line_to (it, -1, -1, 0);
6108 }
6109 else
6110 {
6111 /* TO_VPOS >= 0 means stop at TO_X in the line at
6112 TO_VPOS, or at TO_POS, whichever comes first. */
6113 if (it->vpos == to_vpos)
6114 {
6115 reached = 2;
6116 break;
6117 }
6118
6119 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6120
6121 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6122 {
6123 reached = 3;
6124 break;
6125 }
6126 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6127 {
6128 /* We have reached TO_X but not in the line we want. */
6129 skip = move_it_in_display_line_to (it, to_charpos,
6130 -1, MOVE_TO_POS);
6131 if (skip == MOVE_POS_MATCH_OR_ZV)
6132 {
6133 reached = 4;
6134 break;
6135 }
6136 }
6137 }
6138 }
6139 else if (op & MOVE_TO_Y)
6140 {
6141 struct it it_backup;
6142
6143 /* TO_Y specified means stop at TO_X in the line containing
6144 TO_Y---or at TO_CHARPOS if this is reached first. The
6145 problem is that we can't really tell whether the line
6146 contains TO_Y before we have completely scanned it, and
6147 this may skip past TO_X. What we do is to first scan to
6148 TO_X.
6149
6150 If TO_X is not specified, use a TO_X of zero. The reason
6151 is to make the outcome of this function more predictable.
6152 If we didn't use TO_X == 0, we would stop at the end of
6153 the line which is probably not what a caller would expect
6154 to happen. */
6155 skip = move_it_in_display_line_to (it, to_charpos,
6156 ((op & MOVE_TO_X)
6157 ? to_x : 0),
6158 (MOVE_TO_X
6159 | (op & MOVE_TO_POS)));
6160
6161 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6162 if (skip == MOVE_POS_MATCH_OR_ZV)
6163 {
6164 reached = 5;
6165 break;
6166 }
6167
6168 /* If TO_X was reached, we would like to know whether TO_Y
6169 is in the line. This can only be said if we know the
6170 total line height which requires us to scan the rest of
6171 the line. */
6172 if (skip == MOVE_X_REACHED)
6173 {
6174 it_backup = *it;
6175 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6176 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6177 op & MOVE_TO_POS);
6178 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6179 }
6180
6181 /* Now, decide whether TO_Y is in this line. */
6182 line_height = it->max_ascent + it->max_descent;
6183 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6184
6185 if (to_y >= it->current_y
6186 && to_y < it->current_y + line_height)
6187 {
6188 if (skip == MOVE_X_REACHED)
6189 /* If TO_Y is in this line and TO_X was reached above,
6190 we scanned too far. We have to restore IT's settings
6191 to the ones before skipping. */
6192 *it = it_backup;
6193 reached = 6;
6194 }
6195 else if (skip == MOVE_X_REACHED)
6196 {
6197 skip = skip2;
6198 if (skip == MOVE_POS_MATCH_OR_ZV)
6199 reached = 7;
6200 }
6201
6202 if (reached)
6203 break;
6204 }
6205 else
6206 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6207
6208 switch (skip)
6209 {
6210 case MOVE_POS_MATCH_OR_ZV:
6211 reached = 8;
6212 goto out;
6213
6214 case MOVE_NEWLINE_OR_CR:
6215 set_iterator_to_next (it, 1);
6216 it->continuation_lines_width = 0;
6217 break;
6218
6219 case MOVE_LINE_TRUNCATED:
6220 it->continuation_lines_width = 0;
6221 reseat_at_next_visible_line_start (it, 0);
6222 if ((op & MOVE_TO_POS) != 0
6223 && IT_CHARPOS (*it) > to_charpos)
6224 {
6225 reached = 9;
6226 goto out;
6227 }
6228 break;
6229
6230 case MOVE_LINE_CONTINUED:
6231 it->continuation_lines_width += it->current_x;
6232 break;
6233
6234 default:
6235 abort ();
6236 }
6237
6238 /* Reset/increment for the next run. */
6239 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6240 it->current_x = it->hpos = 0;
6241 it->current_y += it->max_ascent + it->max_descent;
6242 ++it->vpos;
6243 last_height = it->max_ascent + it->max_descent;
6244 last_max_ascent = it->max_ascent;
6245 it->max_ascent = it->max_descent = 0;
6246 }
6247
6248 out:
6249
6250 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6251 }
6252
6253
6254 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6255
6256 If DY > 0, move IT backward at least that many pixels. DY = 0
6257 means move IT backward to the preceding line start or BEGV. This
6258 function may move over more than DY pixels if IT->current_y - DY
6259 ends up in the middle of a line; in this case IT->current_y will be
6260 set to the top of the line moved to. */
6261
6262 void
6263 move_it_vertically_backward (it, dy)
6264 struct it *it;
6265 int dy;
6266 {
6267 int nlines, h;
6268 struct it it2, it3;
6269 int start_pos;
6270
6271 move_further_back:
6272 xassert (dy >= 0);
6273
6274 start_pos = IT_CHARPOS (*it);
6275
6276 /* Estimate how many newlines we must move back. */
6277 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6278
6279 /* Set the iterator's position that many lines back. */
6280 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6281 back_to_previous_visible_line_start (it);
6282
6283 /* Reseat the iterator here. When moving backward, we don't want
6284 reseat to skip forward over invisible text, set up the iterator
6285 to deliver from overlay strings at the new position etc. So,
6286 use reseat_1 here. */
6287 reseat_1 (it, it->current.pos, 1);
6288
6289 /* We are now surely at a line start. */
6290 it->current_x = it->hpos = 0;
6291 it->continuation_lines_width = 0;
6292
6293 /* Move forward and see what y-distance we moved. First move to the
6294 start of the next line so that we get its height. We need this
6295 height to be able to tell whether we reached the specified
6296 y-distance. */
6297 it2 = *it;
6298 it2.max_ascent = it2.max_descent = 0;
6299 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6300 MOVE_TO_POS | MOVE_TO_VPOS);
6301 xassert (IT_CHARPOS (*it) >= BEGV);
6302 it3 = it2;
6303
6304 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6305 xassert (IT_CHARPOS (*it) >= BEGV);
6306 /* H is the actual vertical distance from the position in *IT
6307 and the starting position. */
6308 h = it2.current_y - it->current_y;
6309 /* NLINES is the distance in number of lines. */
6310 nlines = it2.vpos - it->vpos;
6311
6312 /* Correct IT's y and vpos position
6313 so that they are relative to the starting point. */
6314 it->vpos -= nlines;
6315 it->current_y -= h;
6316
6317 if (dy == 0)
6318 {
6319 /* DY == 0 means move to the start of the screen line. The
6320 value of nlines is > 0 if continuation lines were involved. */
6321 if (nlines > 0)
6322 move_it_by_lines (it, nlines, 1);
6323 #if 0
6324 /* I think this assert is bogus if buffer contains
6325 invisible text or images. KFS. */
6326 xassert (IT_CHARPOS (*it) <= start_pos);
6327 #endif
6328 }
6329 else
6330 {
6331 /* The y-position we try to reach, relative to *IT.
6332 Note that H has been subtracted in front of the if-statement. */
6333 int target_y = it->current_y + h - dy;
6334 int y0 = it3.current_y;
6335 int y1 = line_bottom_y (&it3);
6336 int line_height = y1 - y0;
6337
6338 /* If we did not reach target_y, try to move further backward if
6339 we can. If we moved too far backward, try to move forward. */
6340 if (target_y < it->current_y
6341 /* This is heuristic. In a window that's 3 lines high, with
6342 a line height of 13 pixels each, recentering with point
6343 on the bottom line will try to move -39/2 = 19 pixels
6344 backward. Try to avoid moving into the first line. */
6345 && (it->current_y - target_y
6346 > min (window_box_height (it->w), line_height * 2 / 3))
6347 && IT_CHARPOS (*it) > BEGV)
6348 {
6349 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6350 target_y - it->current_y));
6351 dy = it->current_y - target_y;
6352 goto move_further_back;
6353 }
6354 else if (target_y >= it->current_y + line_height
6355 && IT_CHARPOS (*it) < ZV)
6356 {
6357 /* Should move forward by at least one line, maybe more.
6358
6359 Note: Calling move_it_by_lines can be expensive on
6360 terminal frames, where compute_motion is used (via
6361 vmotion) to do the job, when there are very long lines
6362 and truncate-lines is nil. That's the reason for
6363 treating terminal frames specially here. */
6364
6365 if (!FRAME_WINDOW_P (it->f))
6366 move_it_vertically (it, target_y - (it->current_y + line_height));
6367 else
6368 {
6369 do
6370 {
6371 move_it_by_lines (it, 1, 1);
6372 }
6373 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6374 }
6375
6376 #if 0
6377 /* I think this assert is bogus if buffer contains
6378 invisible text or images. KFS. */
6379 xassert (IT_CHARPOS (*it) >= BEGV);
6380 #endif
6381 }
6382 }
6383 }
6384
6385
6386 /* Move IT by a specified amount of pixel lines DY. DY negative means
6387 move backwards. DY = 0 means move to start of screen line. At the
6388 end, IT will be on the start of a screen line. */
6389
6390 void
6391 move_it_vertically (it, dy)
6392 struct it *it;
6393 int dy;
6394 {
6395 if (dy <= 0)
6396 move_it_vertically_backward (it, -dy);
6397 else
6398 {
6399 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6400 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6401 MOVE_TO_POS | MOVE_TO_Y);
6402 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6403
6404 /* If buffer ends in ZV without a newline, move to the start of
6405 the line to satisfy the post-condition. */
6406 if (IT_CHARPOS (*it) == ZV
6407 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6408 move_it_by_lines (it, 0, 0);
6409 }
6410 }
6411
6412
6413 /* Move iterator IT past the end of the text line it is in. */
6414
6415 void
6416 move_it_past_eol (it)
6417 struct it *it;
6418 {
6419 enum move_it_result rc;
6420
6421 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6422 if (rc == MOVE_NEWLINE_OR_CR)
6423 set_iterator_to_next (it, 0);
6424 }
6425
6426
6427 #if 0 /* Currently not used. */
6428
6429 /* Return non-zero if some text between buffer positions START_CHARPOS
6430 and END_CHARPOS is invisible. IT->window is the window for text
6431 property lookup. */
6432
6433 static int
6434 invisible_text_between_p (it, start_charpos, end_charpos)
6435 struct it *it;
6436 int start_charpos, end_charpos;
6437 {
6438 Lisp_Object prop, limit;
6439 int invisible_found_p;
6440
6441 xassert (it != NULL && start_charpos <= end_charpos);
6442
6443 /* Is text at START invisible? */
6444 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6445 it->window);
6446 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6447 invisible_found_p = 1;
6448 else
6449 {
6450 limit = Fnext_single_char_property_change (make_number (start_charpos),
6451 Qinvisible, Qnil,
6452 make_number (end_charpos));
6453 invisible_found_p = XFASTINT (limit) < end_charpos;
6454 }
6455
6456 return invisible_found_p;
6457 }
6458
6459 #endif /* 0 */
6460
6461
6462 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6463 negative means move up. DVPOS == 0 means move to the start of the
6464 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6465 NEED_Y_P is zero, IT->current_y will be left unchanged.
6466
6467 Further optimization ideas: If we would know that IT->f doesn't use
6468 a face with proportional font, we could be faster for
6469 truncate-lines nil. */
6470
6471 void
6472 move_it_by_lines (it, dvpos, need_y_p)
6473 struct it *it;
6474 int dvpos, need_y_p;
6475 {
6476 struct position pos;
6477
6478 if (!FRAME_WINDOW_P (it->f))
6479 {
6480 struct text_pos textpos;
6481
6482 /* We can use vmotion on frames without proportional fonts. */
6483 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6484 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6485 reseat (it, textpos, 1);
6486 it->vpos += pos.vpos;
6487 it->current_y += pos.vpos;
6488 }
6489 else if (dvpos == 0)
6490 {
6491 /* DVPOS == 0 means move to the start of the screen line. */
6492 move_it_vertically_backward (it, 0);
6493 xassert (it->current_x == 0 && it->hpos == 0);
6494 /* Let next call to line_bottom_y calculate real line height */
6495 last_height = 0;
6496 }
6497 else if (dvpos > 0)
6498 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6499 else
6500 {
6501 struct it it2;
6502 int start_charpos, i;
6503
6504 /* Start at the beginning of the screen line containing IT's
6505 position. */
6506 move_it_vertically_backward (it, 0);
6507
6508 /* Go back -DVPOS visible lines and reseat the iterator there. */
6509 start_charpos = IT_CHARPOS (*it);
6510 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6511 back_to_previous_visible_line_start (it);
6512 reseat (it, it->current.pos, 1);
6513 it->current_x = it->hpos = 0;
6514
6515 /* Above call may have moved too far if continuation lines
6516 are involved. Scan forward and see if it did. */
6517 it2 = *it;
6518 it2.vpos = it2.current_y = 0;
6519 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6520 it->vpos -= it2.vpos;
6521 it->current_y -= it2.current_y;
6522 it->current_x = it->hpos = 0;
6523
6524 /* If we moved too far back, move IT some lines forward. */
6525 if (it2.vpos > -dvpos)
6526 {
6527 int delta = it2.vpos + dvpos;
6528 it2 = *it;
6529 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6530 /* Move back again if we got too far ahead. */
6531 if (IT_CHARPOS (*it) >= start_charpos)
6532 *it = it2;
6533 }
6534 }
6535 }
6536
6537 /* Return 1 if IT points into the middle of a display vector. */
6538
6539 int
6540 in_display_vector_p (it)
6541 struct it *it;
6542 {
6543 return (it->method == GET_FROM_DISPLAY_VECTOR
6544 && it->current.dpvec_index > 0
6545 && it->dpvec + it->current.dpvec_index != it->dpend);
6546 }
6547
6548 \f
6549 /***********************************************************************
6550 Messages
6551 ***********************************************************************/
6552
6553
6554 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6555 to *Messages*. */
6556
6557 void
6558 add_to_log (format, arg1, arg2)
6559 char *format;
6560 Lisp_Object arg1, arg2;
6561 {
6562 Lisp_Object args[3];
6563 Lisp_Object msg, fmt;
6564 char *buffer;
6565 int len;
6566 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6567 USE_SAFE_ALLOCA;
6568
6569 /* Do nothing if called asynchronously. Inserting text into
6570 a buffer may call after-change-functions and alike and
6571 that would means running Lisp asynchronously. */
6572 if (handling_signal)
6573 return;
6574
6575 fmt = msg = Qnil;
6576 GCPRO4 (fmt, msg, arg1, arg2);
6577
6578 args[0] = fmt = build_string (format);
6579 args[1] = arg1;
6580 args[2] = arg2;
6581 msg = Fformat (3, args);
6582
6583 len = SBYTES (msg) + 1;
6584 SAFE_ALLOCA (buffer, char *, len);
6585 bcopy (SDATA (msg), buffer, len);
6586
6587 message_dolog (buffer, len - 1, 1, 0);
6588 SAFE_FREE ();
6589
6590 UNGCPRO;
6591 }
6592
6593
6594 /* Output a newline in the *Messages* buffer if "needs" one. */
6595
6596 void
6597 message_log_maybe_newline ()
6598 {
6599 if (message_log_need_newline)
6600 message_dolog ("", 0, 1, 0);
6601 }
6602
6603
6604 /* Add a string M of length NBYTES to the message log, optionally
6605 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6606 nonzero, means interpret the contents of M as multibyte. This
6607 function calls low-level routines in order to bypass text property
6608 hooks, etc. which might not be safe to run. */
6609
6610 void
6611 message_dolog (m, nbytes, nlflag, multibyte)
6612 const char *m;
6613 int nbytes, nlflag, multibyte;
6614 {
6615 if (!NILP (Vmemory_full))
6616 return;
6617
6618 if (!NILP (Vmessage_log_max))
6619 {
6620 struct buffer *oldbuf;
6621 Lisp_Object oldpoint, oldbegv, oldzv;
6622 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6623 int point_at_end = 0;
6624 int zv_at_end = 0;
6625 Lisp_Object old_deactivate_mark, tem;
6626 struct gcpro gcpro1;
6627
6628 old_deactivate_mark = Vdeactivate_mark;
6629 oldbuf = current_buffer;
6630 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6631 current_buffer->undo_list = Qt;
6632
6633 oldpoint = message_dolog_marker1;
6634 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6635 oldbegv = message_dolog_marker2;
6636 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6637 oldzv = message_dolog_marker3;
6638 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6639 GCPRO1 (old_deactivate_mark);
6640
6641 if (PT == Z)
6642 point_at_end = 1;
6643 if (ZV == Z)
6644 zv_at_end = 1;
6645
6646 BEGV = BEG;
6647 BEGV_BYTE = BEG_BYTE;
6648 ZV = Z;
6649 ZV_BYTE = Z_BYTE;
6650 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6651
6652 /* Insert the string--maybe converting multibyte to single byte
6653 or vice versa, so that all the text fits the buffer. */
6654 if (multibyte
6655 && NILP (current_buffer->enable_multibyte_characters))
6656 {
6657 int i, c, char_bytes;
6658 unsigned char work[1];
6659
6660 /* Convert a multibyte string to single-byte
6661 for the *Message* buffer. */
6662 for (i = 0; i < nbytes; i += char_bytes)
6663 {
6664 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6665 work[0] = (SINGLE_BYTE_CHAR_P (c)
6666 ? c
6667 : multibyte_char_to_unibyte (c, Qnil));
6668 insert_1_both (work, 1, 1, 1, 0, 0);
6669 }
6670 }
6671 else if (! multibyte
6672 && ! NILP (current_buffer->enable_multibyte_characters))
6673 {
6674 int i, c, char_bytes;
6675 unsigned char *msg = (unsigned char *) m;
6676 unsigned char str[MAX_MULTIBYTE_LENGTH];
6677 /* Convert a single-byte string to multibyte
6678 for the *Message* buffer. */
6679 for (i = 0; i < nbytes; i++)
6680 {
6681 c = unibyte_char_to_multibyte (msg[i]);
6682 char_bytes = CHAR_STRING (c, str);
6683 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6684 }
6685 }
6686 else if (nbytes)
6687 insert_1 (m, nbytes, 1, 0, 0);
6688
6689 if (nlflag)
6690 {
6691 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6692 insert_1 ("\n", 1, 1, 0, 0);
6693
6694 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6695 this_bol = PT;
6696 this_bol_byte = PT_BYTE;
6697
6698 /* See if this line duplicates the previous one.
6699 If so, combine duplicates. */
6700 if (this_bol > BEG)
6701 {
6702 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6703 prev_bol = PT;
6704 prev_bol_byte = PT_BYTE;
6705
6706 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6707 this_bol, this_bol_byte);
6708 if (dup)
6709 {
6710 del_range_both (prev_bol, prev_bol_byte,
6711 this_bol, this_bol_byte, 0);
6712 if (dup > 1)
6713 {
6714 char dupstr[40];
6715 int duplen;
6716
6717 /* If you change this format, don't forget to also
6718 change message_log_check_duplicate. */
6719 sprintf (dupstr, " [%d times]", dup);
6720 duplen = strlen (dupstr);
6721 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6722 insert_1 (dupstr, duplen, 1, 0, 1);
6723 }
6724 }
6725 }
6726
6727 /* If we have more than the desired maximum number of lines
6728 in the *Messages* buffer now, delete the oldest ones.
6729 This is safe because we don't have undo in this buffer. */
6730
6731 if (NATNUMP (Vmessage_log_max))
6732 {
6733 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6734 -XFASTINT (Vmessage_log_max) - 1, 0);
6735 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6736 }
6737 }
6738 BEGV = XMARKER (oldbegv)->charpos;
6739 BEGV_BYTE = marker_byte_position (oldbegv);
6740
6741 if (zv_at_end)
6742 {
6743 ZV = Z;
6744 ZV_BYTE = Z_BYTE;
6745 }
6746 else
6747 {
6748 ZV = XMARKER (oldzv)->charpos;
6749 ZV_BYTE = marker_byte_position (oldzv);
6750 }
6751
6752 if (point_at_end)
6753 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6754 else
6755 /* We can't do Fgoto_char (oldpoint) because it will run some
6756 Lisp code. */
6757 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6758 XMARKER (oldpoint)->bytepos);
6759
6760 UNGCPRO;
6761 unchain_marker (XMARKER (oldpoint));
6762 unchain_marker (XMARKER (oldbegv));
6763 unchain_marker (XMARKER (oldzv));
6764
6765 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6766 set_buffer_internal (oldbuf);
6767 if (NILP (tem))
6768 windows_or_buffers_changed = old_windows_or_buffers_changed;
6769 message_log_need_newline = !nlflag;
6770 Vdeactivate_mark = old_deactivate_mark;
6771 }
6772 }
6773
6774
6775 /* We are at the end of the buffer after just having inserted a newline.
6776 (Note: We depend on the fact we won't be crossing the gap.)
6777 Check to see if the most recent message looks a lot like the previous one.
6778 Return 0 if different, 1 if the new one should just replace it, or a
6779 value N > 1 if we should also append " [N times]". */
6780
6781 static int
6782 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6783 int prev_bol, this_bol;
6784 int prev_bol_byte, this_bol_byte;
6785 {
6786 int i;
6787 int len = Z_BYTE - 1 - this_bol_byte;
6788 int seen_dots = 0;
6789 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6790 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6791
6792 for (i = 0; i < len; i++)
6793 {
6794 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6795 seen_dots = 1;
6796 if (p1[i] != p2[i])
6797 return seen_dots;
6798 }
6799 p1 += len;
6800 if (*p1 == '\n')
6801 return 2;
6802 if (*p1++ == ' ' && *p1++ == '[')
6803 {
6804 int n = 0;
6805 while (*p1 >= '0' && *p1 <= '9')
6806 n = n * 10 + *p1++ - '0';
6807 if (strncmp (p1, " times]\n", 8) == 0)
6808 return n+1;
6809 }
6810 return 0;
6811 }
6812 \f
6813
6814 /* Display an echo area message M with a specified length of NBYTES
6815 bytes. The string may include null characters. If M is 0, clear
6816 out any existing message, and let the mini-buffer text show
6817 through.
6818
6819 The buffer M must continue to exist until after the echo area gets
6820 cleared or some other message gets displayed there. This means do
6821 not pass text that is stored in a Lisp string; do not pass text in
6822 a buffer that was alloca'd. */
6823
6824 void
6825 message2 (m, nbytes, multibyte)
6826 const char *m;
6827 int nbytes;
6828 int multibyte;
6829 {
6830 /* First flush out any partial line written with print. */
6831 message_log_maybe_newline ();
6832 if (m)
6833 message_dolog (m, nbytes, 1, multibyte);
6834 message2_nolog (m, nbytes, multibyte);
6835 }
6836
6837
6838 /* The non-logging counterpart of message2. */
6839
6840 void
6841 message2_nolog (m, nbytes, multibyte)
6842 const char *m;
6843 int nbytes, multibyte;
6844 {
6845 struct frame *sf = SELECTED_FRAME ();
6846 message_enable_multibyte = multibyte;
6847
6848 if (noninteractive)
6849 {
6850 if (noninteractive_need_newline)
6851 putc ('\n', stderr);
6852 noninteractive_need_newline = 0;
6853 if (m)
6854 fwrite (m, nbytes, 1, stderr);
6855 if (cursor_in_echo_area == 0)
6856 fprintf (stderr, "\n");
6857 fflush (stderr);
6858 }
6859 /* A null message buffer means that the frame hasn't really been
6860 initialized yet. Error messages get reported properly by
6861 cmd_error, so this must be just an informative message; toss it. */
6862 else if (INTERACTIVE
6863 && sf->glyphs_initialized_p
6864 && FRAME_MESSAGE_BUF (sf))
6865 {
6866 Lisp_Object mini_window;
6867 struct frame *f;
6868
6869 /* Get the frame containing the mini-buffer
6870 that the selected frame is using. */
6871 mini_window = FRAME_MINIBUF_WINDOW (sf);
6872 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6873
6874 FRAME_SAMPLE_VISIBILITY (f);
6875 if (FRAME_VISIBLE_P (sf)
6876 && ! FRAME_VISIBLE_P (f))
6877 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6878
6879 if (m)
6880 {
6881 set_message (m, Qnil, nbytes, multibyte);
6882 if (minibuffer_auto_raise)
6883 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6884 }
6885 else
6886 clear_message (1, 1);
6887
6888 do_pending_window_change (0);
6889 echo_area_display (1);
6890 do_pending_window_change (0);
6891 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6892 (*frame_up_to_date_hook) (f);
6893 }
6894 }
6895
6896
6897 /* Display an echo area message M with a specified length of NBYTES
6898 bytes. The string may include null characters. If M is not a
6899 string, clear out any existing message, and let the mini-buffer
6900 text show through. */
6901
6902 void
6903 message3 (m, nbytes, multibyte)
6904 Lisp_Object m;
6905 int nbytes;
6906 int multibyte;
6907 {
6908 struct gcpro gcpro1;
6909
6910 GCPRO1 (m);
6911 clear_message (1,1);
6912
6913 /* First flush out any partial line written with print. */
6914 message_log_maybe_newline ();
6915 if (STRINGP (m))
6916 message_dolog (SDATA (m), nbytes, 1, multibyte);
6917 message3_nolog (m, nbytes, multibyte);
6918
6919 UNGCPRO;
6920 }
6921
6922
6923 /* The non-logging version of message3. */
6924
6925 void
6926 message3_nolog (m, nbytes, multibyte)
6927 Lisp_Object m;
6928 int nbytes, multibyte;
6929 {
6930 struct frame *sf = SELECTED_FRAME ();
6931 message_enable_multibyte = multibyte;
6932
6933 if (noninteractive)
6934 {
6935 if (noninteractive_need_newline)
6936 putc ('\n', stderr);
6937 noninteractive_need_newline = 0;
6938 if (STRINGP (m))
6939 fwrite (SDATA (m), nbytes, 1, stderr);
6940 if (cursor_in_echo_area == 0)
6941 fprintf (stderr, "\n");
6942 fflush (stderr);
6943 }
6944 /* A null message buffer means that the frame hasn't really been
6945 initialized yet. Error messages get reported properly by
6946 cmd_error, so this must be just an informative message; toss it. */
6947 else if (INTERACTIVE
6948 && sf->glyphs_initialized_p
6949 && FRAME_MESSAGE_BUF (sf))
6950 {
6951 Lisp_Object mini_window;
6952 Lisp_Object frame;
6953 struct frame *f;
6954
6955 /* Get the frame containing the mini-buffer
6956 that the selected frame is using. */
6957 mini_window = FRAME_MINIBUF_WINDOW (sf);
6958 frame = XWINDOW (mini_window)->frame;
6959 f = XFRAME (frame);
6960
6961 FRAME_SAMPLE_VISIBILITY (f);
6962 if (FRAME_VISIBLE_P (sf)
6963 && !FRAME_VISIBLE_P (f))
6964 Fmake_frame_visible (frame);
6965
6966 if (STRINGP (m) && SCHARS (m) > 0)
6967 {
6968 set_message (NULL, m, nbytes, multibyte);
6969 if (minibuffer_auto_raise)
6970 Fraise_frame (frame);
6971 }
6972 else
6973 clear_message (1, 1);
6974
6975 do_pending_window_change (0);
6976 echo_area_display (1);
6977 do_pending_window_change (0);
6978 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6979 (*frame_up_to_date_hook) (f);
6980 }
6981 }
6982
6983
6984 /* Display a null-terminated echo area message M. If M is 0, clear
6985 out any existing message, and let the mini-buffer text show through.
6986
6987 The buffer M must continue to exist until after the echo area gets
6988 cleared or some other message gets displayed there. Do not pass
6989 text that is stored in a Lisp string. Do not pass text in a buffer
6990 that was alloca'd. */
6991
6992 void
6993 message1 (m)
6994 char *m;
6995 {
6996 message2 (m, (m ? strlen (m) : 0), 0);
6997 }
6998
6999
7000 /* The non-logging counterpart of message1. */
7001
7002 void
7003 message1_nolog (m)
7004 char *m;
7005 {
7006 message2_nolog (m, (m ? strlen (m) : 0), 0);
7007 }
7008
7009 /* Display a message M which contains a single %s
7010 which gets replaced with STRING. */
7011
7012 void
7013 message_with_string (m, string, log)
7014 char *m;
7015 Lisp_Object string;
7016 int log;
7017 {
7018 CHECK_STRING (string);
7019
7020 if (noninteractive)
7021 {
7022 if (m)
7023 {
7024 if (noninteractive_need_newline)
7025 putc ('\n', stderr);
7026 noninteractive_need_newline = 0;
7027 fprintf (stderr, m, SDATA (string));
7028 if (cursor_in_echo_area == 0)
7029 fprintf (stderr, "\n");
7030 fflush (stderr);
7031 }
7032 }
7033 else if (INTERACTIVE)
7034 {
7035 /* The frame whose minibuffer we're going to display the message on.
7036 It may be larger than the selected frame, so we need
7037 to use its buffer, not the selected frame's buffer. */
7038 Lisp_Object mini_window;
7039 struct frame *f, *sf = SELECTED_FRAME ();
7040
7041 /* Get the frame containing the minibuffer
7042 that the selected frame is using. */
7043 mini_window = FRAME_MINIBUF_WINDOW (sf);
7044 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7045
7046 /* A null message buffer means that the frame hasn't really been
7047 initialized yet. Error messages get reported properly by
7048 cmd_error, so this must be just an informative message; toss it. */
7049 if (FRAME_MESSAGE_BUF (f))
7050 {
7051 Lisp_Object args[2], message;
7052 struct gcpro gcpro1, gcpro2;
7053
7054 args[0] = build_string (m);
7055 args[1] = message = string;
7056 GCPRO2 (args[0], message);
7057 gcpro1.nvars = 2;
7058
7059 message = Fformat (2, args);
7060
7061 if (log)
7062 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7063 else
7064 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7065
7066 UNGCPRO;
7067
7068 /* Print should start at the beginning of the message
7069 buffer next time. */
7070 message_buf_print = 0;
7071 }
7072 }
7073 }
7074
7075
7076 /* Dump an informative message to the minibuf. If M is 0, clear out
7077 any existing message, and let the mini-buffer text show through. */
7078
7079 /* VARARGS 1 */
7080 void
7081 message (m, a1, a2, a3)
7082 char *m;
7083 EMACS_INT a1, a2, a3;
7084 {
7085 if (noninteractive)
7086 {
7087 if (m)
7088 {
7089 if (noninteractive_need_newline)
7090 putc ('\n', stderr);
7091 noninteractive_need_newline = 0;
7092 fprintf (stderr, m, a1, a2, a3);
7093 if (cursor_in_echo_area == 0)
7094 fprintf (stderr, "\n");
7095 fflush (stderr);
7096 }
7097 }
7098 else if (INTERACTIVE)
7099 {
7100 /* The frame whose mini-buffer we're going to display the message
7101 on. It may be larger than the selected frame, so we need to
7102 use its buffer, not the selected frame's buffer. */
7103 Lisp_Object mini_window;
7104 struct frame *f, *sf = SELECTED_FRAME ();
7105
7106 /* Get the frame containing the mini-buffer
7107 that the selected frame is using. */
7108 mini_window = FRAME_MINIBUF_WINDOW (sf);
7109 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7110
7111 /* A null message buffer means that the frame hasn't really been
7112 initialized yet. Error messages get reported properly by
7113 cmd_error, so this must be just an informative message; toss
7114 it. */
7115 if (FRAME_MESSAGE_BUF (f))
7116 {
7117 if (m)
7118 {
7119 int len;
7120 #ifdef NO_ARG_ARRAY
7121 char *a[3];
7122 a[0] = (char *) a1;
7123 a[1] = (char *) a2;
7124 a[2] = (char *) a3;
7125
7126 len = doprnt (FRAME_MESSAGE_BUF (f),
7127 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7128 #else
7129 len = doprnt (FRAME_MESSAGE_BUF (f),
7130 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7131 (char **) &a1);
7132 #endif /* NO_ARG_ARRAY */
7133
7134 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7135 }
7136 else
7137 message1 (0);
7138
7139 /* Print should start at the beginning of the message
7140 buffer next time. */
7141 message_buf_print = 0;
7142 }
7143 }
7144 }
7145
7146
7147 /* The non-logging version of message. */
7148
7149 void
7150 message_nolog (m, a1, a2, a3)
7151 char *m;
7152 EMACS_INT a1, a2, a3;
7153 {
7154 Lisp_Object old_log_max;
7155 old_log_max = Vmessage_log_max;
7156 Vmessage_log_max = Qnil;
7157 message (m, a1, a2, a3);
7158 Vmessage_log_max = old_log_max;
7159 }
7160
7161
7162 /* Display the current message in the current mini-buffer. This is
7163 only called from error handlers in process.c, and is not time
7164 critical. */
7165
7166 void
7167 update_echo_area ()
7168 {
7169 if (!NILP (echo_area_buffer[0]))
7170 {
7171 Lisp_Object string;
7172 string = Fcurrent_message ();
7173 message3 (string, SBYTES (string),
7174 !NILP (current_buffer->enable_multibyte_characters));
7175 }
7176 }
7177
7178
7179 /* Make sure echo area buffers in `echo_buffers' are live.
7180 If they aren't, make new ones. */
7181
7182 static void
7183 ensure_echo_area_buffers ()
7184 {
7185 int i;
7186
7187 for (i = 0; i < 2; ++i)
7188 if (!BUFFERP (echo_buffer[i])
7189 || NILP (XBUFFER (echo_buffer[i])->name))
7190 {
7191 char name[30];
7192 Lisp_Object old_buffer;
7193 int j;
7194
7195 old_buffer = echo_buffer[i];
7196 sprintf (name, " *Echo Area %d*", i);
7197 echo_buffer[i] = Fget_buffer_create (build_string (name));
7198 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7199
7200 for (j = 0; j < 2; ++j)
7201 if (EQ (old_buffer, echo_area_buffer[j]))
7202 echo_area_buffer[j] = echo_buffer[i];
7203 }
7204 }
7205
7206
7207 /* Call FN with args A1..A4 with either the current or last displayed
7208 echo_area_buffer as current buffer.
7209
7210 WHICH zero means use the current message buffer
7211 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7212 from echo_buffer[] and clear it.
7213
7214 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7215 suitable buffer from echo_buffer[] and clear it.
7216
7217 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7218 that the current message becomes the last displayed one, make
7219 choose a suitable buffer for echo_area_buffer[0], and clear it.
7220
7221 Value is what FN returns. */
7222
7223 static int
7224 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7225 struct window *w;
7226 int which;
7227 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7228 EMACS_INT a1;
7229 Lisp_Object a2;
7230 EMACS_INT a3, a4;
7231 {
7232 Lisp_Object buffer;
7233 int this_one, the_other, clear_buffer_p, rc;
7234 int count = SPECPDL_INDEX ();
7235
7236 /* If buffers aren't live, make new ones. */
7237 ensure_echo_area_buffers ();
7238
7239 clear_buffer_p = 0;
7240
7241 if (which == 0)
7242 this_one = 0, the_other = 1;
7243 else if (which > 0)
7244 this_one = 1, the_other = 0;
7245 else
7246 {
7247 this_one = 0, the_other = 1;
7248 clear_buffer_p = 1;
7249
7250 /* We need a fresh one in case the current echo buffer equals
7251 the one containing the last displayed echo area message. */
7252 if (!NILP (echo_area_buffer[this_one])
7253 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7254 echo_area_buffer[this_one] = Qnil;
7255 }
7256
7257 /* Choose a suitable buffer from echo_buffer[] is we don't
7258 have one. */
7259 if (NILP (echo_area_buffer[this_one]))
7260 {
7261 echo_area_buffer[this_one]
7262 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7263 ? echo_buffer[the_other]
7264 : echo_buffer[this_one]);
7265 clear_buffer_p = 1;
7266 }
7267
7268 buffer = echo_area_buffer[this_one];
7269
7270 /* Don't get confused by reusing the buffer used for echoing
7271 for a different purpose. */
7272 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7273 cancel_echoing ();
7274
7275 record_unwind_protect (unwind_with_echo_area_buffer,
7276 with_echo_area_buffer_unwind_data (w));
7277
7278 /* Make the echo area buffer current. Note that for display
7279 purposes, it is not necessary that the displayed window's buffer
7280 == current_buffer, except for text property lookup. So, let's
7281 only set that buffer temporarily here without doing a full
7282 Fset_window_buffer. We must also change w->pointm, though,
7283 because otherwise an assertions in unshow_buffer fails, and Emacs
7284 aborts. */
7285 set_buffer_internal_1 (XBUFFER (buffer));
7286 if (w)
7287 {
7288 w->buffer = buffer;
7289 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7290 }
7291
7292 current_buffer->undo_list = Qt;
7293 current_buffer->read_only = Qnil;
7294 specbind (Qinhibit_read_only, Qt);
7295 specbind (Qinhibit_modification_hooks, Qt);
7296
7297 if (clear_buffer_p && Z > BEG)
7298 del_range (BEG, Z);
7299
7300 xassert (BEGV >= BEG);
7301 xassert (ZV <= Z && ZV >= BEGV);
7302
7303 rc = fn (a1, a2, a3, a4);
7304
7305 xassert (BEGV >= BEG);
7306 xassert (ZV <= Z && ZV >= BEGV);
7307
7308 unbind_to (count, Qnil);
7309 return rc;
7310 }
7311
7312
7313 /* Save state that should be preserved around the call to the function
7314 FN called in with_echo_area_buffer. */
7315
7316 static Lisp_Object
7317 with_echo_area_buffer_unwind_data (w)
7318 struct window *w;
7319 {
7320 int i = 0;
7321 Lisp_Object vector;
7322
7323 /* Reduce consing by keeping one vector in
7324 Vwith_echo_area_save_vector. */
7325 vector = Vwith_echo_area_save_vector;
7326 Vwith_echo_area_save_vector = Qnil;
7327
7328 if (NILP (vector))
7329 vector = Fmake_vector (make_number (7), Qnil);
7330
7331 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7332 AREF (vector, i) = Vdeactivate_mark, ++i;
7333 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7334
7335 if (w)
7336 {
7337 XSETWINDOW (AREF (vector, i), w); ++i;
7338 AREF (vector, i) = w->buffer; ++i;
7339 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7340 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7341 }
7342 else
7343 {
7344 int end = i + 4;
7345 for (; i < end; ++i)
7346 AREF (vector, i) = Qnil;
7347 }
7348
7349 xassert (i == ASIZE (vector));
7350 return vector;
7351 }
7352
7353
7354 /* Restore global state from VECTOR which was created by
7355 with_echo_area_buffer_unwind_data. */
7356
7357 static Lisp_Object
7358 unwind_with_echo_area_buffer (vector)
7359 Lisp_Object vector;
7360 {
7361 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7362 Vdeactivate_mark = AREF (vector, 1);
7363 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7364
7365 if (WINDOWP (AREF (vector, 3)))
7366 {
7367 struct window *w;
7368 Lisp_Object buffer, charpos, bytepos;
7369
7370 w = XWINDOW (AREF (vector, 3));
7371 buffer = AREF (vector, 4);
7372 charpos = AREF (vector, 5);
7373 bytepos = AREF (vector, 6);
7374
7375 w->buffer = buffer;
7376 set_marker_both (w->pointm, buffer,
7377 XFASTINT (charpos), XFASTINT (bytepos));
7378 }
7379
7380 Vwith_echo_area_save_vector = vector;
7381 return Qnil;
7382 }
7383
7384
7385 /* Set up the echo area for use by print functions. MULTIBYTE_P
7386 non-zero means we will print multibyte. */
7387
7388 void
7389 setup_echo_area_for_printing (multibyte_p)
7390 int multibyte_p;
7391 {
7392 /* If we can't find an echo area any more, exit. */
7393 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7394 Fkill_emacs (Qnil);
7395
7396 ensure_echo_area_buffers ();
7397
7398 if (!message_buf_print)
7399 {
7400 /* A message has been output since the last time we printed.
7401 Choose a fresh echo area buffer. */
7402 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7403 echo_area_buffer[0] = echo_buffer[1];
7404 else
7405 echo_area_buffer[0] = echo_buffer[0];
7406
7407 /* Switch to that buffer and clear it. */
7408 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7409 current_buffer->truncate_lines = Qnil;
7410
7411 if (Z > BEG)
7412 {
7413 int count = SPECPDL_INDEX ();
7414 specbind (Qinhibit_read_only, Qt);
7415 /* Note that undo recording is always disabled. */
7416 del_range (BEG, Z);
7417 unbind_to (count, Qnil);
7418 }
7419 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7420
7421 /* Set up the buffer for the multibyteness we need. */
7422 if (multibyte_p
7423 != !NILP (current_buffer->enable_multibyte_characters))
7424 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7425
7426 /* Raise the frame containing the echo area. */
7427 if (minibuffer_auto_raise)
7428 {
7429 struct frame *sf = SELECTED_FRAME ();
7430 Lisp_Object mini_window;
7431 mini_window = FRAME_MINIBUF_WINDOW (sf);
7432 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7433 }
7434
7435 message_log_maybe_newline ();
7436 message_buf_print = 1;
7437 }
7438 else
7439 {
7440 if (NILP (echo_area_buffer[0]))
7441 {
7442 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7443 echo_area_buffer[0] = echo_buffer[1];
7444 else
7445 echo_area_buffer[0] = echo_buffer[0];
7446 }
7447
7448 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7449 {
7450 /* Someone switched buffers between print requests. */
7451 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7452 current_buffer->truncate_lines = Qnil;
7453 }
7454 }
7455 }
7456
7457
7458 /* Display an echo area message in window W. Value is non-zero if W's
7459 height is changed. If display_last_displayed_message_p is
7460 non-zero, display the message that was last displayed, otherwise
7461 display the current message. */
7462
7463 static int
7464 display_echo_area (w)
7465 struct window *w;
7466 {
7467 int i, no_message_p, window_height_changed_p, count;
7468
7469 /* Temporarily disable garbage collections while displaying the echo
7470 area. This is done because a GC can print a message itself.
7471 That message would modify the echo area buffer's contents while a
7472 redisplay of the buffer is going on, and seriously confuse
7473 redisplay. */
7474 count = inhibit_garbage_collection ();
7475
7476 /* If there is no message, we must call display_echo_area_1
7477 nevertheless because it resizes the window. But we will have to
7478 reset the echo_area_buffer in question to nil at the end because
7479 with_echo_area_buffer will sets it to an empty buffer. */
7480 i = display_last_displayed_message_p ? 1 : 0;
7481 no_message_p = NILP (echo_area_buffer[i]);
7482
7483 window_height_changed_p
7484 = with_echo_area_buffer (w, display_last_displayed_message_p,
7485 display_echo_area_1,
7486 (EMACS_INT) w, Qnil, 0, 0);
7487
7488 if (no_message_p)
7489 echo_area_buffer[i] = Qnil;
7490
7491 unbind_to (count, Qnil);
7492 return window_height_changed_p;
7493 }
7494
7495
7496 /* Helper for display_echo_area. Display the current buffer which
7497 contains the current echo area message in window W, a mini-window,
7498 a pointer to which is passed in A1. A2..A4 are currently not used.
7499 Change the height of W so that all of the message is displayed.
7500 Value is non-zero if height of W was changed. */
7501
7502 static int
7503 display_echo_area_1 (a1, a2, a3, a4)
7504 EMACS_INT a1;
7505 Lisp_Object a2;
7506 EMACS_INT a3, a4;
7507 {
7508 struct window *w = (struct window *) a1;
7509 Lisp_Object window;
7510 struct text_pos start;
7511 int window_height_changed_p = 0;
7512
7513 /* Do this before displaying, so that we have a large enough glyph
7514 matrix for the display. */
7515 window_height_changed_p = resize_mini_window (w, 0);
7516
7517 /* Display. */
7518 clear_glyph_matrix (w->desired_matrix);
7519 XSETWINDOW (window, w);
7520 SET_TEXT_POS (start, BEG, BEG_BYTE);
7521 try_window (window, start);
7522
7523 return window_height_changed_p;
7524 }
7525
7526
7527 /* Resize the echo area window to exactly the size needed for the
7528 currently displayed message, if there is one. If a mini-buffer
7529 is active, don't shrink it. */
7530
7531 void
7532 resize_echo_area_exactly ()
7533 {
7534 if (BUFFERP (echo_area_buffer[0])
7535 && WINDOWP (echo_area_window))
7536 {
7537 struct window *w = XWINDOW (echo_area_window);
7538 int resized_p;
7539 Lisp_Object resize_exactly;
7540
7541 if (minibuf_level == 0)
7542 resize_exactly = Qt;
7543 else
7544 resize_exactly = Qnil;
7545
7546 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7547 (EMACS_INT) w, resize_exactly, 0, 0);
7548 if (resized_p)
7549 {
7550 ++windows_or_buffers_changed;
7551 ++update_mode_lines;
7552 redisplay_internal (0);
7553 }
7554 }
7555 }
7556
7557
7558 /* Callback function for with_echo_area_buffer, when used from
7559 resize_echo_area_exactly. A1 contains a pointer to the window to
7560 resize, EXACTLY non-nil means resize the mini-window exactly to the
7561 size of the text displayed. A3 and A4 are not used. Value is what
7562 resize_mini_window returns. */
7563
7564 static int
7565 resize_mini_window_1 (a1, exactly, a3, a4)
7566 EMACS_INT a1;
7567 Lisp_Object exactly;
7568 EMACS_INT a3, a4;
7569 {
7570 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7571 }
7572
7573
7574 /* Resize mini-window W to fit the size of its contents. EXACT:P
7575 means size the window exactly to the size needed. Otherwise, it's
7576 only enlarged until W's buffer is empty. Value is non-zero if
7577 the window height has been changed. */
7578
7579 int
7580 resize_mini_window (w, exact_p)
7581 struct window *w;
7582 int exact_p;
7583 {
7584 struct frame *f = XFRAME (w->frame);
7585 int window_height_changed_p = 0;
7586
7587 xassert (MINI_WINDOW_P (w));
7588
7589 /* Don't resize windows while redisplaying a window; it would
7590 confuse redisplay functions when the size of the window they are
7591 displaying changes from under them. Such a resizing can happen,
7592 for instance, when which-func prints a long message while
7593 we are running fontification-functions. We're running these
7594 functions with safe_call which binds inhibit-redisplay to t. */
7595 if (!NILP (Vinhibit_redisplay))
7596 return 0;
7597
7598 /* Nil means don't try to resize. */
7599 if (NILP (Vresize_mini_windows)
7600 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7601 return 0;
7602
7603 if (!FRAME_MINIBUF_ONLY_P (f))
7604 {
7605 struct it it;
7606 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7607 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7608 int height, max_height;
7609 int unit = FRAME_LINE_HEIGHT (f);
7610 struct text_pos start;
7611 struct buffer *old_current_buffer = NULL;
7612
7613 if (current_buffer != XBUFFER (w->buffer))
7614 {
7615 old_current_buffer = current_buffer;
7616 set_buffer_internal (XBUFFER (w->buffer));
7617 }
7618
7619 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7620
7621 /* Compute the max. number of lines specified by the user. */
7622 if (FLOATP (Vmax_mini_window_height))
7623 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7624 else if (INTEGERP (Vmax_mini_window_height))
7625 max_height = XINT (Vmax_mini_window_height);
7626 else
7627 max_height = total_height / 4;
7628
7629 /* Correct that max. height if it's bogus. */
7630 max_height = max (1, max_height);
7631 max_height = min (total_height, max_height);
7632
7633 /* Find out the height of the text in the window. */
7634 if (it.truncate_lines_p)
7635 height = 1;
7636 else
7637 {
7638 last_height = 0;
7639 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7640 if (it.max_ascent == 0 && it.max_descent == 0)
7641 height = it.current_y + last_height;
7642 else
7643 height = it.current_y + it.max_ascent + it.max_descent;
7644 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7645 height = (height + unit - 1) / unit;
7646 }
7647
7648 /* Compute a suitable window start. */
7649 if (height > max_height)
7650 {
7651 height = max_height;
7652 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7653 move_it_vertically_backward (&it, (height - 1) * unit);
7654 start = it.current.pos;
7655 }
7656 else
7657 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7658 SET_MARKER_FROM_TEXT_POS (w->start, start);
7659
7660 if (EQ (Vresize_mini_windows, Qgrow_only))
7661 {
7662 /* Let it grow only, until we display an empty message, in which
7663 case the window shrinks again. */
7664 if (height > WINDOW_TOTAL_LINES (w))
7665 {
7666 int old_height = WINDOW_TOTAL_LINES (w);
7667 freeze_window_starts (f, 1);
7668 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7669 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7670 }
7671 else if (height < WINDOW_TOTAL_LINES (w)
7672 && (exact_p || BEGV == ZV))
7673 {
7674 int old_height = WINDOW_TOTAL_LINES (w);
7675 freeze_window_starts (f, 0);
7676 shrink_mini_window (w);
7677 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7678 }
7679 }
7680 else
7681 {
7682 /* Always resize to exact size needed. */
7683 if (height > WINDOW_TOTAL_LINES (w))
7684 {
7685 int old_height = WINDOW_TOTAL_LINES (w);
7686 freeze_window_starts (f, 1);
7687 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7688 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7689 }
7690 else if (height < WINDOW_TOTAL_LINES (w))
7691 {
7692 int old_height = WINDOW_TOTAL_LINES (w);
7693 freeze_window_starts (f, 0);
7694 shrink_mini_window (w);
7695
7696 if (height)
7697 {
7698 freeze_window_starts (f, 1);
7699 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7700 }
7701
7702 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7703 }
7704 }
7705
7706 if (old_current_buffer)
7707 set_buffer_internal (old_current_buffer);
7708 }
7709
7710 return window_height_changed_p;
7711 }
7712
7713
7714 /* Value is the current message, a string, or nil if there is no
7715 current message. */
7716
7717 Lisp_Object
7718 current_message ()
7719 {
7720 Lisp_Object msg;
7721
7722 if (NILP (echo_area_buffer[0]))
7723 msg = Qnil;
7724 else
7725 {
7726 with_echo_area_buffer (0, 0, current_message_1,
7727 (EMACS_INT) &msg, Qnil, 0, 0);
7728 if (NILP (msg))
7729 echo_area_buffer[0] = Qnil;
7730 }
7731
7732 return msg;
7733 }
7734
7735
7736 static int
7737 current_message_1 (a1, a2, a3, a4)
7738 EMACS_INT a1;
7739 Lisp_Object a2;
7740 EMACS_INT a3, a4;
7741 {
7742 Lisp_Object *msg = (Lisp_Object *) a1;
7743
7744 if (Z > BEG)
7745 *msg = make_buffer_string (BEG, Z, 1);
7746 else
7747 *msg = Qnil;
7748 return 0;
7749 }
7750
7751
7752 /* Push the current message on Vmessage_stack for later restauration
7753 by restore_message. Value is non-zero if the current message isn't
7754 empty. This is a relatively infrequent operation, so it's not
7755 worth optimizing. */
7756
7757 int
7758 push_message ()
7759 {
7760 Lisp_Object msg;
7761 msg = current_message ();
7762 Vmessage_stack = Fcons (msg, Vmessage_stack);
7763 return STRINGP (msg);
7764 }
7765
7766
7767 /* Restore message display from the top of Vmessage_stack. */
7768
7769 void
7770 restore_message ()
7771 {
7772 Lisp_Object msg;
7773
7774 xassert (CONSP (Vmessage_stack));
7775 msg = XCAR (Vmessage_stack);
7776 if (STRINGP (msg))
7777 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7778 else
7779 message3_nolog (msg, 0, 0);
7780 }
7781
7782
7783 /* Handler for record_unwind_protect calling pop_message. */
7784
7785 Lisp_Object
7786 pop_message_unwind (dummy)
7787 Lisp_Object dummy;
7788 {
7789 pop_message ();
7790 return Qnil;
7791 }
7792
7793 /* Pop the top-most entry off Vmessage_stack. */
7794
7795 void
7796 pop_message ()
7797 {
7798 xassert (CONSP (Vmessage_stack));
7799 Vmessage_stack = XCDR (Vmessage_stack);
7800 }
7801
7802
7803 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7804 exits. If the stack is not empty, we have a missing pop_message
7805 somewhere. */
7806
7807 void
7808 check_message_stack ()
7809 {
7810 if (!NILP (Vmessage_stack))
7811 abort ();
7812 }
7813
7814
7815 /* Truncate to NCHARS what will be displayed in the echo area the next
7816 time we display it---but don't redisplay it now. */
7817
7818 void
7819 truncate_echo_area (nchars)
7820 int nchars;
7821 {
7822 if (nchars == 0)
7823 echo_area_buffer[0] = Qnil;
7824 /* A null message buffer means that the frame hasn't really been
7825 initialized yet. Error messages get reported properly by
7826 cmd_error, so this must be just an informative message; toss it. */
7827 else if (!noninteractive
7828 && INTERACTIVE
7829 && !NILP (echo_area_buffer[0]))
7830 {
7831 struct frame *sf = SELECTED_FRAME ();
7832 if (FRAME_MESSAGE_BUF (sf))
7833 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7834 }
7835 }
7836
7837
7838 /* Helper function for truncate_echo_area. Truncate the current
7839 message to at most NCHARS characters. */
7840
7841 static int
7842 truncate_message_1 (nchars, a2, a3, a4)
7843 EMACS_INT nchars;
7844 Lisp_Object a2;
7845 EMACS_INT a3, a4;
7846 {
7847 if (BEG + nchars < Z)
7848 del_range (BEG + nchars, Z);
7849 if (Z == BEG)
7850 echo_area_buffer[0] = Qnil;
7851 return 0;
7852 }
7853
7854
7855 /* Set the current message to a substring of S or STRING.
7856
7857 If STRING is a Lisp string, set the message to the first NBYTES
7858 bytes from STRING. NBYTES zero means use the whole string. If
7859 STRING is multibyte, the message will be displayed multibyte.
7860
7861 If S is not null, set the message to the first LEN bytes of S. LEN
7862 zero means use the whole string. MULTIBYTE_P non-zero means S is
7863 multibyte. Display the message multibyte in that case. */
7864
7865 void
7866 set_message (s, string, nbytes, multibyte_p)
7867 const char *s;
7868 Lisp_Object string;
7869 int nbytes, multibyte_p;
7870 {
7871 message_enable_multibyte
7872 = ((s && multibyte_p)
7873 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7874
7875 with_echo_area_buffer (0, -1, set_message_1,
7876 (EMACS_INT) s, string, nbytes, multibyte_p);
7877 message_buf_print = 0;
7878 help_echo_showing_p = 0;
7879 }
7880
7881
7882 /* Helper function for set_message. Arguments have the same meaning
7883 as there, with A1 corresponding to S and A2 corresponding to STRING
7884 This function is called with the echo area buffer being
7885 current. */
7886
7887 static int
7888 set_message_1 (a1, a2, nbytes, multibyte_p)
7889 EMACS_INT a1;
7890 Lisp_Object a2;
7891 EMACS_INT nbytes, multibyte_p;
7892 {
7893 const char *s = (const char *) a1;
7894 Lisp_Object string = a2;
7895
7896 xassert (BEG == Z);
7897
7898 /* Change multibyteness of the echo buffer appropriately. */
7899 if (message_enable_multibyte
7900 != !NILP (current_buffer->enable_multibyte_characters))
7901 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7902
7903 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7904
7905 /* Insert new message at BEG. */
7906 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7907
7908 if (STRINGP (string))
7909 {
7910 int nchars;
7911
7912 if (nbytes == 0)
7913 nbytes = SBYTES (string);
7914 nchars = string_byte_to_char (string, nbytes);
7915
7916 /* This function takes care of single/multibyte conversion. We
7917 just have to ensure that the echo area buffer has the right
7918 setting of enable_multibyte_characters. */
7919 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7920 }
7921 else if (s)
7922 {
7923 if (nbytes == 0)
7924 nbytes = strlen (s);
7925
7926 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7927 {
7928 /* Convert from multi-byte to single-byte. */
7929 int i, c, n;
7930 unsigned char work[1];
7931
7932 /* Convert a multibyte string to single-byte. */
7933 for (i = 0; i < nbytes; i += n)
7934 {
7935 c = string_char_and_length (s + i, nbytes - i, &n);
7936 work[0] = (SINGLE_BYTE_CHAR_P (c)
7937 ? c
7938 : multibyte_char_to_unibyte (c, Qnil));
7939 insert_1_both (work, 1, 1, 1, 0, 0);
7940 }
7941 }
7942 else if (!multibyte_p
7943 && !NILP (current_buffer->enable_multibyte_characters))
7944 {
7945 /* Convert from single-byte to multi-byte. */
7946 int i, c, n;
7947 const unsigned char *msg = (const unsigned char *) s;
7948 unsigned char str[MAX_MULTIBYTE_LENGTH];
7949
7950 /* Convert a single-byte string to multibyte. */
7951 for (i = 0; i < nbytes; i++)
7952 {
7953 c = unibyte_char_to_multibyte (msg[i]);
7954 n = CHAR_STRING (c, str);
7955 insert_1_both (str, 1, n, 1, 0, 0);
7956 }
7957 }
7958 else
7959 insert_1 (s, nbytes, 1, 0, 0);
7960 }
7961
7962 return 0;
7963 }
7964
7965
7966 /* Clear messages. CURRENT_P non-zero means clear the current
7967 message. LAST_DISPLAYED_P non-zero means clear the message
7968 last displayed. */
7969
7970 void
7971 clear_message (current_p, last_displayed_p)
7972 int current_p, last_displayed_p;
7973 {
7974 if (current_p)
7975 {
7976 echo_area_buffer[0] = Qnil;
7977 message_cleared_p = 1;
7978 }
7979
7980 if (last_displayed_p)
7981 echo_area_buffer[1] = Qnil;
7982
7983 message_buf_print = 0;
7984 }
7985
7986 /* Clear garbaged frames.
7987
7988 This function is used where the old redisplay called
7989 redraw_garbaged_frames which in turn called redraw_frame which in
7990 turn called clear_frame. The call to clear_frame was a source of
7991 flickering. I believe a clear_frame is not necessary. It should
7992 suffice in the new redisplay to invalidate all current matrices,
7993 and ensure a complete redisplay of all windows. */
7994
7995 static void
7996 clear_garbaged_frames ()
7997 {
7998 if (frame_garbaged)
7999 {
8000 Lisp_Object tail, frame;
8001 int changed_count = 0;
8002
8003 FOR_EACH_FRAME (tail, frame)
8004 {
8005 struct frame *f = XFRAME (frame);
8006
8007 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8008 {
8009 if (f->resized_p)
8010 {
8011 Fredraw_frame (frame);
8012 f->force_flush_display_p = 1;
8013 }
8014 clear_current_matrices (f);
8015 changed_count++;
8016 f->garbaged = 0;
8017 f->resized_p = 0;
8018 }
8019 }
8020
8021 frame_garbaged = 0;
8022 if (changed_count)
8023 ++windows_or_buffers_changed;
8024 }
8025 }
8026
8027
8028 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8029 is non-zero update selected_frame. Value is non-zero if the
8030 mini-windows height has been changed. */
8031
8032 static int
8033 echo_area_display (update_frame_p)
8034 int update_frame_p;
8035 {
8036 Lisp_Object mini_window;
8037 struct window *w;
8038 struct frame *f;
8039 int window_height_changed_p = 0;
8040 struct frame *sf = SELECTED_FRAME ();
8041
8042 mini_window = FRAME_MINIBUF_WINDOW (sf);
8043 w = XWINDOW (mini_window);
8044 f = XFRAME (WINDOW_FRAME (w));
8045
8046 /* Don't display if frame is invisible or not yet initialized. */
8047 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8048 return 0;
8049
8050 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8051 #ifndef MAC_OS8
8052 #ifdef HAVE_WINDOW_SYSTEM
8053 /* When Emacs starts, selected_frame may be a visible terminal
8054 frame, even if we run under a window system. If we let this
8055 through, a message would be displayed on the terminal. */
8056 if (EQ (selected_frame, Vterminal_frame)
8057 && !NILP (Vwindow_system))
8058 return 0;
8059 #endif /* HAVE_WINDOW_SYSTEM */
8060 #endif
8061
8062 /* Redraw garbaged frames. */
8063 if (frame_garbaged)
8064 clear_garbaged_frames ();
8065
8066 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8067 {
8068 echo_area_window = mini_window;
8069 window_height_changed_p = display_echo_area (w);
8070 w->must_be_updated_p = 1;
8071
8072 /* Update the display, unless called from redisplay_internal.
8073 Also don't update the screen during redisplay itself. The
8074 update will happen at the end of redisplay, and an update
8075 here could cause confusion. */
8076 if (update_frame_p && !redisplaying_p)
8077 {
8078 int n = 0;
8079
8080 /* If the display update has been interrupted by pending
8081 input, update mode lines in the frame. Due to the
8082 pending input, it might have been that redisplay hasn't
8083 been called, so that mode lines above the echo area are
8084 garbaged. This looks odd, so we prevent it here. */
8085 if (!display_completed)
8086 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8087
8088 if (window_height_changed_p
8089 /* Don't do this if Emacs is shutting down. Redisplay
8090 needs to run hooks. */
8091 && !NILP (Vrun_hooks))
8092 {
8093 /* Must update other windows. Likewise as in other
8094 cases, don't let this update be interrupted by
8095 pending input. */
8096 int count = SPECPDL_INDEX ();
8097 specbind (Qredisplay_dont_pause, Qt);
8098 windows_or_buffers_changed = 1;
8099 redisplay_internal (0);
8100 unbind_to (count, Qnil);
8101 }
8102 else if (FRAME_WINDOW_P (f) && n == 0)
8103 {
8104 /* Window configuration is the same as before.
8105 Can do with a display update of the echo area,
8106 unless we displayed some mode lines. */
8107 update_single_window (w, 1);
8108 rif->flush_display (f);
8109 }
8110 else
8111 update_frame (f, 1, 1);
8112
8113 /* If cursor is in the echo area, make sure that the next
8114 redisplay displays the minibuffer, so that the cursor will
8115 be replaced with what the minibuffer wants. */
8116 if (cursor_in_echo_area)
8117 ++windows_or_buffers_changed;
8118 }
8119 }
8120 else if (!EQ (mini_window, selected_window))
8121 windows_or_buffers_changed++;
8122
8123 /* Last displayed message is now the current message. */
8124 echo_area_buffer[1] = echo_area_buffer[0];
8125 /* Inform read_char that we're not echoing. */
8126 echo_message_buffer = Qnil;
8127
8128 /* Prevent redisplay optimization in redisplay_internal by resetting
8129 this_line_start_pos. This is done because the mini-buffer now
8130 displays the message instead of its buffer text. */
8131 if (EQ (mini_window, selected_window))
8132 CHARPOS (this_line_start_pos) = 0;
8133
8134 return window_height_changed_p;
8135 }
8136
8137
8138 \f
8139 /***********************************************************************
8140 Frame Titles
8141 ***********************************************************************/
8142
8143
8144 /* The frame title buffering code is also used by Fformat_mode_line.
8145 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
8146
8147 /* A buffer for constructing frame titles in it; allocated from the
8148 heap in init_xdisp and resized as needed in store_frame_title_char. */
8149
8150 static char *frame_title_buf;
8151
8152 /* The buffer's end, and a current output position in it. */
8153
8154 static char *frame_title_buf_end;
8155 static char *frame_title_ptr;
8156
8157
8158 /* Store a single character C for the frame title in frame_title_buf.
8159 Re-allocate frame_title_buf if necessary. */
8160
8161 static void
8162 #ifdef PROTOTYPES
8163 store_frame_title_char (char c)
8164 #else
8165 store_frame_title_char (c)
8166 char c;
8167 #endif
8168 {
8169 /* If output position has reached the end of the allocated buffer,
8170 double the buffer's size. */
8171 if (frame_title_ptr == frame_title_buf_end)
8172 {
8173 int len = frame_title_ptr - frame_title_buf;
8174 int new_size = 2 * len * sizeof *frame_title_buf;
8175 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
8176 frame_title_buf_end = frame_title_buf + new_size;
8177 frame_title_ptr = frame_title_buf + len;
8178 }
8179
8180 *frame_title_ptr++ = c;
8181 }
8182
8183
8184 /* Store part of a frame title in frame_title_buf, beginning at
8185 frame_title_ptr. STR is the string to store. Do not copy
8186 characters that yield more columns than PRECISION; PRECISION <= 0
8187 means copy the whole string. Pad with spaces until FIELD_WIDTH
8188 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8189 pad. Called from display_mode_element when it is used to build a
8190 frame title. */
8191
8192 static int
8193 store_frame_title (str, field_width, precision)
8194 const unsigned char *str;
8195 int field_width, precision;
8196 {
8197 int n = 0;
8198 int dummy, nbytes;
8199
8200 /* Copy at most PRECISION chars from STR. */
8201 nbytes = strlen (str);
8202 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8203 while (nbytes--)
8204 store_frame_title_char (*str++);
8205
8206 /* Fill up with spaces until FIELD_WIDTH reached. */
8207 while (field_width > 0
8208 && n < field_width)
8209 {
8210 store_frame_title_char (' ');
8211 ++n;
8212 }
8213
8214 return n;
8215 }
8216
8217 #ifdef HAVE_WINDOW_SYSTEM
8218
8219 /* Set the title of FRAME, if it has changed. The title format is
8220 Vicon_title_format if FRAME is iconified, otherwise it is
8221 frame_title_format. */
8222
8223 static void
8224 x_consider_frame_title (frame)
8225 Lisp_Object frame;
8226 {
8227 struct frame *f = XFRAME (frame);
8228
8229 if (FRAME_WINDOW_P (f)
8230 || FRAME_MINIBUF_ONLY_P (f)
8231 || f->explicit_name)
8232 {
8233 /* Do we have more than one visible frame on this X display? */
8234 Lisp_Object tail;
8235 Lisp_Object fmt;
8236 struct buffer *obuf;
8237 int len;
8238 struct it it;
8239
8240 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8241 {
8242 Lisp_Object other_frame = XCAR (tail);
8243 struct frame *tf = XFRAME (other_frame);
8244
8245 if (tf != f
8246 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8247 && !FRAME_MINIBUF_ONLY_P (tf)
8248 && !EQ (other_frame, tip_frame)
8249 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8250 break;
8251 }
8252
8253 /* Set global variable indicating that multiple frames exist. */
8254 multiple_frames = CONSP (tail);
8255
8256 /* Switch to the buffer of selected window of the frame. Set up
8257 frame_title_ptr so that display_mode_element will output into it;
8258 then display the title. */
8259 obuf = current_buffer;
8260 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8261 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8262 frame_title_ptr = frame_title_buf;
8263 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8264 NULL, DEFAULT_FACE_ID);
8265 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8266 len = frame_title_ptr - frame_title_buf;
8267 frame_title_ptr = NULL;
8268 set_buffer_internal_1 (obuf);
8269
8270 /* Set the title only if it's changed. This avoids consing in
8271 the common case where it hasn't. (If it turns out that we've
8272 already wasted too much time by walking through the list with
8273 display_mode_element, then we might need to optimize at a
8274 higher level than this.) */
8275 if (! STRINGP (f->name)
8276 || SBYTES (f->name) != len
8277 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8278 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8279 }
8280 }
8281
8282 #endif /* not HAVE_WINDOW_SYSTEM */
8283
8284
8285
8286 \f
8287 /***********************************************************************
8288 Menu Bars
8289 ***********************************************************************/
8290
8291
8292 /* Prepare for redisplay by updating menu-bar item lists when
8293 appropriate. This can call eval. */
8294
8295 void
8296 prepare_menu_bars ()
8297 {
8298 int all_windows;
8299 struct gcpro gcpro1, gcpro2;
8300 struct frame *f;
8301 Lisp_Object tooltip_frame;
8302
8303 #ifdef HAVE_WINDOW_SYSTEM
8304 tooltip_frame = tip_frame;
8305 #else
8306 tooltip_frame = Qnil;
8307 #endif
8308
8309 /* Update all frame titles based on their buffer names, etc. We do
8310 this before the menu bars so that the buffer-menu will show the
8311 up-to-date frame titles. */
8312 #ifdef HAVE_WINDOW_SYSTEM
8313 if (windows_or_buffers_changed || update_mode_lines)
8314 {
8315 Lisp_Object tail, frame;
8316
8317 FOR_EACH_FRAME (tail, frame)
8318 {
8319 f = XFRAME (frame);
8320 if (!EQ (frame, tooltip_frame)
8321 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8322 x_consider_frame_title (frame);
8323 }
8324 }
8325 #endif /* HAVE_WINDOW_SYSTEM */
8326
8327 /* Update the menu bar item lists, if appropriate. This has to be
8328 done before any actual redisplay or generation of display lines. */
8329 all_windows = (update_mode_lines
8330 || buffer_shared > 1
8331 || windows_or_buffers_changed);
8332 if (all_windows)
8333 {
8334 Lisp_Object tail, frame;
8335 int count = SPECPDL_INDEX ();
8336
8337 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8338
8339 FOR_EACH_FRAME (tail, frame)
8340 {
8341 f = XFRAME (frame);
8342
8343 /* Ignore tooltip frame. */
8344 if (EQ (frame, tooltip_frame))
8345 continue;
8346
8347 /* If a window on this frame changed size, report that to
8348 the user and clear the size-change flag. */
8349 if (FRAME_WINDOW_SIZES_CHANGED (f))
8350 {
8351 Lisp_Object functions;
8352
8353 /* Clear flag first in case we get an error below. */
8354 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8355 functions = Vwindow_size_change_functions;
8356 GCPRO2 (tail, functions);
8357
8358 while (CONSP (functions))
8359 {
8360 call1 (XCAR (functions), frame);
8361 functions = XCDR (functions);
8362 }
8363 UNGCPRO;
8364 }
8365
8366 GCPRO1 (tail);
8367 update_menu_bar (f, 0);
8368 #ifdef HAVE_WINDOW_SYSTEM
8369 update_tool_bar (f, 0);
8370 #endif
8371 UNGCPRO;
8372 }
8373
8374 unbind_to (count, Qnil);
8375 }
8376 else
8377 {
8378 struct frame *sf = SELECTED_FRAME ();
8379 update_menu_bar (sf, 1);
8380 #ifdef HAVE_WINDOW_SYSTEM
8381 update_tool_bar (sf, 1);
8382 #endif
8383 }
8384
8385 /* Motif needs this. See comment in xmenu.c. Turn it off when
8386 pending_menu_activation is not defined. */
8387 #ifdef USE_X_TOOLKIT
8388 pending_menu_activation = 0;
8389 #endif
8390 }
8391
8392
8393 /* Update the menu bar item list for frame F. This has to be done
8394 before we start to fill in any display lines, because it can call
8395 eval.
8396
8397 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8398
8399 static void
8400 update_menu_bar (f, save_match_data)
8401 struct frame *f;
8402 int save_match_data;
8403 {
8404 Lisp_Object window;
8405 register struct window *w;
8406
8407 /* If called recursively during a menu update, do nothing. This can
8408 happen when, for instance, an activate-menubar-hook causes a
8409 redisplay. */
8410 if (inhibit_menubar_update)
8411 return;
8412
8413 window = FRAME_SELECTED_WINDOW (f);
8414 w = XWINDOW (window);
8415
8416 #if 0 /* The if statement below this if statement used to include the
8417 condition !NILP (w->update_mode_line), rather than using
8418 update_mode_lines directly, and this if statement may have
8419 been added to make that condition work. Now the if
8420 statement below matches its comment, this isn't needed. */
8421 if (update_mode_lines)
8422 w->update_mode_line = Qt;
8423 #endif
8424
8425 if (FRAME_WINDOW_P (f)
8426 ?
8427 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8428 || defined (USE_GTK)
8429 FRAME_EXTERNAL_MENU_BAR (f)
8430 #else
8431 FRAME_MENU_BAR_LINES (f) > 0
8432 #endif
8433 : FRAME_MENU_BAR_LINES (f) > 0)
8434 {
8435 /* If the user has switched buffers or windows, we need to
8436 recompute to reflect the new bindings. But we'll
8437 recompute when update_mode_lines is set too; that means
8438 that people can use force-mode-line-update to request
8439 that the menu bar be recomputed. The adverse effect on
8440 the rest of the redisplay algorithm is about the same as
8441 windows_or_buffers_changed anyway. */
8442 if (windows_or_buffers_changed
8443 /* This used to test w->update_mode_line, but we believe
8444 there is no need to recompute the menu in that case. */
8445 || update_mode_lines
8446 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8447 < BUF_MODIFF (XBUFFER (w->buffer)))
8448 != !NILP (w->last_had_star))
8449 || ((!NILP (Vtransient_mark_mode)
8450 && !NILP (XBUFFER (w->buffer)->mark_active))
8451 != !NILP (w->region_showing)))
8452 {
8453 struct buffer *prev = current_buffer;
8454 int count = SPECPDL_INDEX ();
8455
8456 specbind (Qinhibit_menubar_update, Qt);
8457
8458 set_buffer_internal_1 (XBUFFER (w->buffer));
8459 if (save_match_data)
8460 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8461 if (NILP (Voverriding_local_map_menu_flag))
8462 {
8463 specbind (Qoverriding_terminal_local_map, Qnil);
8464 specbind (Qoverriding_local_map, Qnil);
8465 }
8466
8467 /* Run the Lucid hook. */
8468 safe_run_hooks (Qactivate_menubar_hook);
8469
8470 /* If it has changed current-menubar from previous value,
8471 really recompute the menu-bar from the value. */
8472 if (! NILP (Vlucid_menu_bar_dirty_flag))
8473 call0 (Qrecompute_lucid_menubar);
8474
8475 safe_run_hooks (Qmenu_bar_update_hook);
8476 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8477
8478 /* Redisplay the menu bar in case we changed it. */
8479 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8480 || defined (USE_GTK)
8481 if (FRAME_WINDOW_P (f)
8482 #if defined (MAC_OS)
8483 /* All frames on Mac OS share the same menubar. So only the
8484 selected frame should be allowed to set it. */
8485 && f == SELECTED_FRAME ()
8486 #endif
8487 )
8488 set_frame_menubar (f, 0, 0);
8489 else
8490 /* On a terminal screen, the menu bar is an ordinary screen
8491 line, and this makes it get updated. */
8492 w->update_mode_line = Qt;
8493 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8494 /* In the non-toolkit version, the menu bar is an ordinary screen
8495 line, and this makes it get updated. */
8496 w->update_mode_line = Qt;
8497 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8498
8499 unbind_to (count, Qnil);
8500 set_buffer_internal_1 (prev);
8501 }
8502 }
8503 }
8504
8505
8506 \f
8507 /***********************************************************************
8508 Output Cursor
8509 ***********************************************************************/
8510
8511 #ifdef HAVE_WINDOW_SYSTEM
8512
8513 /* EXPORT:
8514 Nominal cursor position -- where to draw output.
8515 HPOS and VPOS are window relative glyph matrix coordinates.
8516 X and Y are window relative pixel coordinates. */
8517
8518 struct cursor_pos output_cursor;
8519
8520
8521 /* EXPORT:
8522 Set the global variable output_cursor to CURSOR. All cursor
8523 positions are relative to updated_window. */
8524
8525 void
8526 set_output_cursor (cursor)
8527 struct cursor_pos *cursor;
8528 {
8529 output_cursor.hpos = cursor->hpos;
8530 output_cursor.vpos = cursor->vpos;
8531 output_cursor.x = cursor->x;
8532 output_cursor.y = cursor->y;
8533 }
8534
8535
8536 /* EXPORT for RIF:
8537 Set a nominal cursor position.
8538
8539 HPOS and VPOS are column/row positions in a window glyph matrix. X
8540 and Y are window text area relative pixel positions.
8541
8542 If this is done during an update, updated_window will contain the
8543 window that is being updated and the position is the future output
8544 cursor position for that window. If updated_window is null, use
8545 selected_window and display the cursor at the given position. */
8546
8547 void
8548 x_cursor_to (vpos, hpos, y, x)
8549 int vpos, hpos, y, x;
8550 {
8551 struct window *w;
8552
8553 /* If updated_window is not set, work on selected_window. */
8554 if (updated_window)
8555 w = updated_window;
8556 else
8557 w = XWINDOW (selected_window);
8558
8559 /* Set the output cursor. */
8560 output_cursor.hpos = hpos;
8561 output_cursor.vpos = vpos;
8562 output_cursor.x = x;
8563 output_cursor.y = y;
8564
8565 /* If not called as part of an update, really display the cursor.
8566 This will also set the cursor position of W. */
8567 if (updated_window == NULL)
8568 {
8569 BLOCK_INPUT;
8570 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8571 if (rif->flush_display_optional)
8572 rif->flush_display_optional (SELECTED_FRAME ());
8573 UNBLOCK_INPUT;
8574 }
8575 }
8576
8577 #endif /* HAVE_WINDOW_SYSTEM */
8578
8579 \f
8580 /***********************************************************************
8581 Tool-bars
8582 ***********************************************************************/
8583
8584 #ifdef HAVE_WINDOW_SYSTEM
8585
8586 /* Where the mouse was last time we reported a mouse event. */
8587
8588 FRAME_PTR last_mouse_frame;
8589
8590 /* Tool-bar item index of the item on which a mouse button was pressed
8591 or -1. */
8592
8593 int last_tool_bar_item;
8594
8595
8596 /* Update the tool-bar item list for frame F. This has to be done
8597 before we start to fill in any display lines. Called from
8598 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8599 and restore it here. */
8600
8601 static void
8602 update_tool_bar (f, save_match_data)
8603 struct frame *f;
8604 int save_match_data;
8605 {
8606 #ifdef USE_GTK
8607 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8608 #else
8609 int do_update = WINDOWP (f->tool_bar_window)
8610 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8611 #endif
8612
8613 if (do_update)
8614 {
8615 Lisp_Object window;
8616 struct window *w;
8617
8618 window = FRAME_SELECTED_WINDOW (f);
8619 w = XWINDOW (window);
8620
8621 /* If the user has switched buffers or windows, we need to
8622 recompute to reflect the new bindings. But we'll
8623 recompute when update_mode_lines is set too; that means
8624 that people can use force-mode-line-update to request
8625 that the menu bar be recomputed. The adverse effect on
8626 the rest of the redisplay algorithm is about the same as
8627 windows_or_buffers_changed anyway. */
8628 if (windows_or_buffers_changed
8629 || !NILP (w->update_mode_line)
8630 || update_mode_lines
8631 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8632 < BUF_MODIFF (XBUFFER (w->buffer)))
8633 != !NILP (w->last_had_star))
8634 || ((!NILP (Vtransient_mark_mode)
8635 && !NILP (XBUFFER (w->buffer)->mark_active))
8636 != !NILP (w->region_showing)))
8637 {
8638 struct buffer *prev = current_buffer;
8639 int count = SPECPDL_INDEX ();
8640 Lisp_Object new_tool_bar;
8641 int new_n_tool_bar;
8642 struct gcpro gcpro1;
8643
8644 /* Set current_buffer to the buffer of the selected
8645 window of the frame, so that we get the right local
8646 keymaps. */
8647 set_buffer_internal_1 (XBUFFER (w->buffer));
8648
8649 /* Save match data, if we must. */
8650 if (save_match_data)
8651 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8652
8653 /* Make sure that we don't accidentally use bogus keymaps. */
8654 if (NILP (Voverriding_local_map_menu_flag))
8655 {
8656 specbind (Qoverriding_terminal_local_map, Qnil);
8657 specbind (Qoverriding_local_map, Qnil);
8658 }
8659
8660 GCPRO1 (new_tool_bar);
8661
8662 /* Build desired tool-bar items from keymaps. */
8663 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8664 &new_n_tool_bar);
8665
8666 /* Redisplay the tool-bar if we changed it. */
8667 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8668 {
8669 /* Redisplay that happens asynchronously due to an expose event
8670 may access f->tool_bar_items. Make sure we update both
8671 variables within BLOCK_INPUT so no such event interrupts. */
8672 BLOCK_INPUT;
8673 f->tool_bar_items = new_tool_bar;
8674 f->n_tool_bar_items = new_n_tool_bar;
8675 w->update_mode_line = Qt;
8676 UNBLOCK_INPUT;
8677 }
8678
8679 UNGCPRO;
8680
8681 unbind_to (count, Qnil);
8682 set_buffer_internal_1 (prev);
8683 }
8684 }
8685 }
8686
8687
8688 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8689 F's desired tool-bar contents. F->tool_bar_items must have
8690 been set up previously by calling prepare_menu_bars. */
8691
8692 static void
8693 build_desired_tool_bar_string (f)
8694 struct frame *f;
8695 {
8696 int i, size, size_needed;
8697 struct gcpro gcpro1, gcpro2, gcpro3;
8698 Lisp_Object image, plist, props;
8699
8700 image = plist = props = Qnil;
8701 GCPRO3 (image, plist, props);
8702
8703 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8704 Otherwise, make a new string. */
8705
8706 /* The size of the string we might be able to reuse. */
8707 size = (STRINGP (f->desired_tool_bar_string)
8708 ? SCHARS (f->desired_tool_bar_string)
8709 : 0);
8710
8711 /* We need one space in the string for each image. */
8712 size_needed = f->n_tool_bar_items;
8713
8714 /* Reuse f->desired_tool_bar_string, if possible. */
8715 if (size < size_needed || NILP (f->desired_tool_bar_string))
8716 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8717 make_number (' '));
8718 else
8719 {
8720 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8721 Fremove_text_properties (make_number (0), make_number (size),
8722 props, f->desired_tool_bar_string);
8723 }
8724
8725 /* Put a `display' property on the string for the images to display,
8726 put a `menu_item' property on tool-bar items with a value that
8727 is the index of the item in F's tool-bar item vector. */
8728 for (i = 0; i < f->n_tool_bar_items; ++i)
8729 {
8730 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8731
8732 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8733 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8734 int hmargin, vmargin, relief, idx, end;
8735 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8736
8737 /* If image is a vector, choose the image according to the
8738 button state. */
8739 image = PROP (TOOL_BAR_ITEM_IMAGES);
8740 if (VECTORP (image))
8741 {
8742 if (enabled_p)
8743 idx = (selected_p
8744 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8745 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8746 else
8747 idx = (selected_p
8748 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8749 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8750
8751 xassert (ASIZE (image) >= idx);
8752 image = AREF (image, idx);
8753 }
8754 else
8755 idx = -1;
8756
8757 /* Ignore invalid image specifications. */
8758 if (!valid_image_p (image))
8759 continue;
8760
8761 /* Display the tool-bar button pressed, or depressed. */
8762 plist = Fcopy_sequence (XCDR (image));
8763
8764 /* Compute margin and relief to draw. */
8765 relief = (tool_bar_button_relief >= 0
8766 ? tool_bar_button_relief
8767 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8768 hmargin = vmargin = relief;
8769
8770 if (INTEGERP (Vtool_bar_button_margin)
8771 && XINT (Vtool_bar_button_margin) > 0)
8772 {
8773 hmargin += XFASTINT (Vtool_bar_button_margin);
8774 vmargin += XFASTINT (Vtool_bar_button_margin);
8775 }
8776 else if (CONSP (Vtool_bar_button_margin))
8777 {
8778 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8779 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8780 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8781
8782 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8783 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8784 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8785 }
8786
8787 if (auto_raise_tool_bar_buttons_p)
8788 {
8789 /* Add a `:relief' property to the image spec if the item is
8790 selected. */
8791 if (selected_p)
8792 {
8793 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8794 hmargin -= relief;
8795 vmargin -= relief;
8796 }
8797 }
8798 else
8799 {
8800 /* If image is selected, display it pressed, i.e. with a
8801 negative relief. If it's not selected, display it with a
8802 raised relief. */
8803 plist = Fplist_put (plist, QCrelief,
8804 (selected_p
8805 ? make_number (-relief)
8806 : make_number (relief)));
8807 hmargin -= relief;
8808 vmargin -= relief;
8809 }
8810
8811 /* Put a margin around the image. */
8812 if (hmargin || vmargin)
8813 {
8814 if (hmargin == vmargin)
8815 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8816 else
8817 plist = Fplist_put (plist, QCmargin,
8818 Fcons (make_number (hmargin),
8819 make_number (vmargin)));
8820 }
8821
8822 /* If button is not enabled, and we don't have special images
8823 for the disabled state, make the image appear disabled by
8824 applying an appropriate algorithm to it. */
8825 if (!enabled_p && idx < 0)
8826 plist = Fplist_put (plist, QCconversion, Qdisabled);
8827
8828 /* Put a `display' text property on the string for the image to
8829 display. Put a `menu-item' property on the string that gives
8830 the start of this item's properties in the tool-bar items
8831 vector. */
8832 image = Fcons (Qimage, plist);
8833 props = list4 (Qdisplay, image,
8834 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8835
8836 /* Let the last image hide all remaining spaces in the tool bar
8837 string. The string can be longer than needed when we reuse a
8838 previous string. */
8839 if (i + 1 == f->n_tool_bar_items)
8840 end = SCHARS (f->desired_tool_bar_string);
8841 else
8842 end = i + 1;
8843 Fadd_text_properties (make_number (i), make_number (end),
8844 props, f->desired_tool_bar_string);
8845 #undef PROP
8846 }
8847
8848 UNGCPRO;
8849 }
8850
8851
8852 /* Display one line of the tool-bar of frame IT->f. */
8853
8854 static void
8855 display_tool_bar_line (it)
8856 struct it *it;
8857 {
8858 struct glyph_row *row = it->glyph_row;
8859 int max_x = it->last_visible_x;
8860 struct glyph *last;
8861
8862 prepare_desired_row (row);
8863 row->y = it->current_y;
8864
8865 /* Note that this isn't made use of if the face hasn't a box,
8866 so there's no need to check the face here. */
8867 it->start_of_box_run_p = 1;
8868
8869 while (it->current_x < max_x)
8870 {
8871 int x_before, x, n_glyphs_before, i, nglyphs;
8872
8873 /* Get the next display element. */
8874 if (!get_next_display_element (it))
8875 break;
8876
8877 /* Produce glyphs. */
8878 x_before = it->current_x;
8879 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8880 PRODUCE_GLYPHS (it);
8881
8882 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8883 i = 0;
8884 x = x_before;
8885 while (i < nglyphs)
8886 {
8887 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8888
8889 if (x + glyph->pixel_width > max_x)
8890 {
8891 /* Glyph doesn't fit on line. */
8892 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8893 it->current_x = x;
8894 goto out;
8895 }
8896
8897 ++it->hpos;
8898 x += glyph->pixel_width;
8899 ++i;
8900 }
8901
8902 /* Stop at line ends. */
8903 if (ITERATOR_AT_END_OF_LINE_P (it))
8904 break;
8905
8906 set_iterator_to_next (it, 1);
8907 }
8908
8909 out:;
8910
8911 row->displays_text_p = row->used[TEXT_AREA] != 0;
8912 extend_face_to_end_of_line (it);
8913 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8914 last->right_box_line_p = 1;
8915 if (last == row->glyphs[TEXT_AREA])
8916 last->left_box_line_p = 1;
8917 compute_line_metrics (it);
8918
8919 /* If line is empty, make it occupy the rest of the tool-bar. */
8920 if (!row->displays_text_p)
8921 {
8922 row->height = row->phys_height = it->last_visible_y - row->y;
8923 row->ascent = row->phys_ascent = 0;
8924 row->extra_line_spacing = 0;
8925 }
8926
8927 row->full_width_p = 1;
8928 row->continued_p = 0;
8929 row->truncated_on_left_p = 0;
8930 row->truncated_on_right_p = 0;
8931
8932 it->current_x = it->hpos = 0;
8933 it->current_y += row->height;
8934 ++it->vpos;
8935 ++it->glyph_row;
8936 }
8937
8938
8939 /* Value is the number of screen lines needed to make all tool-bar
8940 items of frame F visible. */
8941
8942 static int
8943 tool_bar_lines_needed (f)
8944 struct frame *f;
8945 {
8946 struct window *w = XWINDOW (f->tool_bar_window);
8947 struct it it;
8948
8949 /* Initialize an iterator for iteration over
8950 F->desired_tool_bar_string in the tool-bar window of frame F. */
8951 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8952 it.first_visible_x = 0;
8953 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8954 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8955
8956 while (!ITERATOR_AT_END_P (&it))
8957 {
8958 it.glyph_row = w->desired_matrix->rows;
8959 clear_glyph_row (it.glyph_row);
8960 display_tool_bar_line (&it);
8961 }
8962
8963 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8964 }
8965
8966
8967 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8968 0, 1, 0,
8969 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8970 (frame)
8971 Lisp_Object frame;
8972 {
8973 struct frame *f;
8974 struct window *w;
8975 int nlines = 0;
8976
8977 if (NILP (frame))
8978 frame = selected_frame;
8979 else
8980 CHECK_FRAME (frame);
8981 f = XFRAME (frame);
8982
8983 if (WINDOWP (f->tool_bar_window)
8984 || (w = XWINDOW (f->tool_bar_window),
8985 WINDOW_TOTAL_LINES (w) > 0))
8986 {
8987 update_tool_bar (f, 1);
8988 if (f->n_tool_bar_items)
8989 {
8990 build_desired_tool_bar_string (f);
8991 nlines = tool_bar_lines_needed (f);
8992 }
8993 }
8994
8995 return make_number (nlines);
8996 }
8997
8998
8999 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9000 height should be changed. */
9001
9002 static int
9003 redisplay_tool_bar (f)
9004 struct frame *f;
9005 {
9006 struct window *w;
9007 struct it it;
9008 struct glyph_row *row;
9009 int change_height_p = 0;
9010
9011 #ifdef USE_GTK
9012 if (FRAME_EXTERNAL_TOOL_BAR (f))
9013 update_frame_tool_bar (f);
9014 return 0;
9015 #endif
9016
9017 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9018 do anything. This means you must start with tool-bar-lines
9019 non-zero to get the auto-sizing effect. Or in other words, you
9020 can turn off tool-bars by specifying tool-bar-lines zero. */
9021 if (!WINDOWP (f->tool_bar_window)
9022 || (w = XWINDOW (f->tool_bar_window),
9023 WINDOW_TOTAL_LINES (w) == 0))
9024 return 0;
9025
9026 /* Set up an iterator for the tool-bar window. */
9027 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9028 it.first_visible_x = 0;
9029 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9030 row = it.glyph_row;
9031
9032 /* Build a string that represents the contents of the tool-bar. */
9033 build_desired_tool_bar_string (f);
9034 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9035
9036 /* Display as many lines as needed to display all tool-bar items. */
9037 while (it.current_y < it.last_visible_y)
9038 display_tool_bar_line (&it);
9039
9040 /* It doesn't make much sense to try scrolling in the tool-bar
9041 window, so don't do it. */
9042 w->desired_matrix->no_scrolling_p = 1;
9043 w->must_be_updated_p = 1;
9044
9045 if (auto_resize_tool_bars_p)
9046 {
9047 int nlines;
9048
9049 /* If we couldn't display everything, change the tool-bar's
9050 height. */
9051 if (IT_STRING_CHARPOS (it) < it.end_charpos)
9052 change_height_p = 1;
9053
9054 /* If there are blank lines at the end, except for a partially
9055 visible blank line at the end that is smaller than
9056 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9057 row = it.glyph_row - 1;
9058 if (!row->displays_text_p
9059 && row->height >= FRAME_LINE_HEIGHT (f))
9060 change_height_p = 1;
9061
9062 /* If row displays tool-bar items, but is partially visible,
9063 change the tool-bar's height. */
9064 if (row->displays_text_p
9065 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
9066 change_height_p = 1;
9067
9068 /* Resize windows as needed by changing the `tool-bar-lines'
9069 frame parameter. */
9070 if (change_height_p
9071 && (nlines = tool_bar_lines_needed (f),
9072 nlines != WINDOW_TOTAL_LINES (w)))
9073 {
9074 extern Lisp_Object Qtool_bar_lines;
9075 Lisp_Object frame;
9076 int old_height = WINDOW_TOTAL_LINES (w);
9077
9078 XSETFRAME (frame, f);
9079 clear_glyph_matrix (w->desired_matrix);
9080 Fmodify_frame_parameters (frame,
9081 Fcons (Fcons (Qtool_bar_lines,
9082 make_number (nlines)),
9083 Qnil));
9084 if (WINDOW_TOTAL_LINES (w) != old_height)
9085 fonts_changed_p = 1;
9086 }
9087 }
9088
9089 return change_height_p;
9090 }
9091
9092
9093 /* Get information about the tool-bar item which is displayed in GLYPH
9094 on frame F. Return in *PROP_IDX the index where tool-bar item
9095 properties start in F->tool_bar_items. Value is zero if
9096 GLYPH doesn't display a tool-bar item. */
9097
9098 static int
9099 tool_bar_item_info (f, glyph, prop_idx)
9100 struct frame *f;
9101 struct glyph *glyph;
9102 int *prop_idx;
9103 {
9104 Lisp_Object prop;
9105 int success_p;
9106 int charpos;
9107
9108 /* This function can be called asynchronously, which means we must
9109 exclude any possibility that Fget_text_property signals an
9110 error. */
9111 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9112 charpos = max (0, charpos);
9113
9114 /* Get the text property `menu-item' at pos. The value of that
9115 property is the start index of this item's properties in
9116 F->tool_bar_items. */
9117 prop = Fget_text_property (make_number (charpos),
9118 Qmenu_item, f->current_tool_bar_string);
9119 if (INTEGERP (prop))
9120 {
9121 *prop_idx = XINT (prop);
9122 success_p = 1;
9123 }
9124 else
9125 success_p = 0;
9126
9127 return success_p;
9128 }
9129
9130 \f
9131 /* Get information about the tool-bar item at position X/Y on frame F.
9132 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9133 the current matrix of the tool-bar window of F, or NULL if not
9134 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9135 item in F->tool_bar_items. Value is
9136
9137 -1 if X/Y is not on a tool-bar item
9138 0 if X/Y is on the same item that was highlighted before.
9139 1 otherwise. */
9140
9141 static int
9142 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
9143 struct frame *f;
9144 int x, y;
9145 struct glyph **glyph;
9146 int *hpos, *vpos, *prop_idx;
9147 {
9148 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9149 struct window *w = XWINDOW (f->tool_bar_window);
9150 int area;
9151
9152 /* Find the glyph under X/Y. */
9153 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
9154 if (*glyph == NULL)
9155 return -1;
9156
9157 /* Get the start of this tool-bar item's properties in
9158 f->tool_bar_items. */
9159 if (!tool_bar_item_info (f, *glyph, prop_idx))
9160 return -1;
9161
9162 /* Is mouse on the highlighted item? */
9163 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9164 && *vpos >= dpyinfo->mouse_face_beg_row
9165 && *vpos <= dpyinfo->mouse_face_end_row
9166 && (*vpos > dpyinfo->mouse_face_beg_row
9167 || *hpos >= dpyinfo->mouse_face_beg_col)
9168 && (*vpos < dpyinfo->mouse_face_end_row
9169 || *hpos < dpyinfo->mouse_face_end_col
9170 || dpyinfo->mouse_face_past_end))
9171 return 0;
9172
9173 return 1;
9174 }
9175
9176
9177 /* EXPORT:
9178 Handle mouse button event on the tool-bar of frame F, at
9179 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9180 0 for button release. MODIFIERS is event modifiers for button
9181 release. */
9182
9183 void
9184 handle_tool_bar_click (f, x, y, down_p, modifiers)
9185 struct frame *f;
9186 int x, y, down_p;
9187 unsigned int modifiers;
9188 {
9189 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9190 struct window *w = XWINDOW (f->tool_bar_window);
9191 int hpos, vpos, prop_idx;
9192 struct glyph *glyph;
9193 Lisp_Object enabled_p;
9194
9195 /* If not on the highlighted tool-bar item, return. */
9196 frame_to_window_pixel_xy (w, &x, &y);
9197 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9198 return;
9199
9200 /* If item is disabled, do nothing. */
9201 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9202 if (NILP (enabled_p))
9203 return;
9204
9205 if (down_p)
9206 {
9207 /* Show item in pressed state. */
9208 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9209 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9210 last_tool_bar_item = prop_idx;
9211 }
9212 else
9213 {
9214 Lisp_Object key, frame;
9215 struct input_event event;
9216 EVENT_INIT (event);
9217
9218 /* Show item in released state. */
9219 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9220 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9221
9222 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9223
9224 XSETFRAME (frame, f);
9225 event.kind = TOOL_BAR_EVENT;
9226 event.frame_or_window = frame;
9227 event.arg = frame;
9228 kbd_buffer_store_event (&event);
9229
9230 event.kind = TOOL_BAR_EVENT;
9231 event.frame_or_window = frame;
9232 event.arg = key;
9233 event.modifiers = modifiers;
9234 kbd_buffer_store_event (&event);
9235 last_tool_bar_item = -1;
9236 }
9237 }
9238
9239
9240 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9241 tool-bar window-relative coordinates X/Y. Called from
9242 note_mouse_highlight. */
9243
9244 static void
9245 note_tool_bar_highlight (f, x, y)
9246 struct frame *f;
9247 int x, y;
9248 {
9249 Lisp_Object window = f->tool_bar_window;
9250 struct window *w = XWINDOW (window);
9251 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9252 int hpos, vpos;
9253 struct glyph *glyph;
9254 struct glyph_row *row;
9255 int i;
9256 Lisp_Object enabled_p;
9257 int prop_idx;
9258 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9259 int mouse_down_p, rc;
9260
9261 /* Function note_mouse_highlight is called with negative x(y
9262 values when mouse moves outside of the frame. */
9263 if (x <= 0 || y <= 0)
9264 {
9265 clear_mouse_face (dpyinfo);
9266 return;
9267 }
9268
9269 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9270 if (rc < 0)
9271 {
9272 /* Not on tool-bar item. */
9273 clear_mouse_face (dpyinfo);
9274 return;
9275 }
9276 else if (rc == 0)
9277 /* On same tool-bar item as before. */
9278 goto set_help_echo;
9279
9280 clear_mouse_face (dpyinfo);
9281
9282 /* Mouse is down, but on different tool-bar item? */
9283 mouse_down_p = (dpyinfo->grabbed
9284 && f == last_mouse_frame
9285 && FRAME_LIVE_P (f));
9286 if (mouse_down_p
9287 && last_tool_bar_item != prop_idx)
9288 return;
9289
9290 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9291 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9292
9293 /* If tool-bar item is not enabled, don't highlight it. */
9294 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9295 if (!NILP (enabled_p))
9296 {
9297 /* Compute the x-position of the glyph. In front and past the
9298 image is a space. We include this in the highlighted area. */
9299 row = MATRIX_ROW (w->current_matrix, vpos);
9300 for (i = x = 0; i < hpos; ++i)
9301 x += row->glyphs[TEXT_AREA][i].pixel_width;
9302
9303 /* Record this as the current active region. */
9304 dpyinfo->mouse_face_beg_col = hpos;
9305 dpyinfo->mouse_face_beg_row = vpos;
9306 dpyinfo->mouse_face_beg_x = x;
9307 dpyinfo->mouse_face_beg_y = row->y;
9308 dpyinfo->mouse_face_past_end = 0;
9309
9310 dpyinfo->mouse_face_end_col = hpos + 1;
9311 dpyinfo->mouse_face_end_row = vpos;
9312 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9313 dpyinfo->mouse_face_end_y = row->y;
9314 dpyinfo->mouse_face_window = window;
9315 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9316
9317 /* Display it as active. */
9318 show_mouse_face (dpyinfo, draw);
9319 dpyinfo->mouse_face_image_state = draw;
9320 }
9321
9322 set_help_echo:
9323
9324 /* Set help_echo_string to a help string to display for this tool-bar item.
9325 XTread_socket does the rest. */
9326 help_echo_object = help_echo_window = Qnil;
9327 help_echo_pos = -1;
9328 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9329 if (NILP (help_echo_string))
9330 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9331 }
9332
9333 #endif /* HAVE_WINDOW_SYSTEM */
9334
9335
9336 \f
9337 /************************************************************************
9338 Horizontal scrolling
9339 ************************************************************************/
9340
9341 static int hscroll_window_tree P_ ((Lisp_Object));
9342 static int hscroll_windows P_ ((Lisp_Object));
9343
9344 /* For all leaf windows in the window tree rooted at WINDOW, set their
9345 hscroll value so that PT is (i) visible in the window, and (ii) so
9346 that it is not within a certain margin at the window's left and
9347 right border. Value is non-zero if any window's hscroll has been
9348 changed. */
9349
9350 static int
9351 hscroll_window_tree (window)
9352 Lisp_Object window;
9353 {
9354 int hscrolled_p = 0;
9355 int hscroll_relative_p = FLOATP (Vhscroll_step);
9356 int hscroll_step_abs = 0;
9357 double hscroll_step_rel = 0;
9358
9359 if (hscroll_relative_p)
9360 {
9361 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9362 if (hscroll_step_rel < 0)
9363 {
9364 hscroll_relative_p = 0;
9365 hscroll_step_abs = 0;
9366 }
9367 }
9368 else if (INTEGERP (Vhscroll_step))
9369 {
9370 hscroll_step_abs = XINT (Vhscroll_step);
9371 if (hscroll_step_abs < 0)
9372 hscroll_step_abs = 0;
9373 }
9374 else
9375 hscroll_step_abs = 0;
9376
9377 while (WINDOWP (window))
9378 {
9379 struct window *w = XWINDOW (window);
9380
9381 if (WINDOWP (w->hchild))
9382 hscrolled_p |= hscroll_window_tree (w->hchild);
9383 else if (WINDOWP (w->vchild))
9384 hscrolled_p |= hscroll_window_tree (w->vchild);
9385 else if (w->cursor.vpos >= 0)
9386 {
9387 int h_margin;
9388 int text_area_width;
9389 struct glyph_row *current_cursor_row
9390 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9391 struct glyph_row *desired_cursor_row
9392 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9393 struct glyph_row *cursor_row
9394 = (desired_cursor_row->enabled_p
9395 ? desired_cursor_row
9396 : current_cursor_row);
9397
9398 text_area_width = window_box_width (w, TEXT_AREA);
9399
9400 /* Scroll when cursor is inside this scroll margin. */
9401 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9402
9403 if ((XFASTINT (w->hscroll)
9404 && w->cursor.x <= h_margin)
9405 || (cursor_row->enabled_p
9406 && cursor_row->truncated_on_right_p
9407 && (w->cursor.x >= text_area_width - h_margin)))
9408 {
9409 struct it it;
9410 int hscroll;
9411 struct buffer *saved_current_buffer;
9412 int pt;
9413 int wanted_x;
9414
9415 /* Find point in a display of infinite width. */
9416 saved_current_buffer = current_buffer;
9417 current_buffer = XBUFFER (w->buffer);
9418
9419 if (w == XWINDOW (selected_window))
9420 pt = BUF_PT (current_buffer);
9421 else
9422 {
9423 pt = marker_position (w->pointm);
9424 pt = max (BEGV, pt);
9425 pt = min (ZV, pt);
9426 }
9427
9428 /* Move iterator to pt starting at cursor_row->start in
9429 a line with infinite width. */
9430 init_to_row_start (&it, w, cursor_row);
9431 it.last_visible_x = INFINITY;
9432 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9433 current_buffer = saved_current_buffer;
9434
9435 /* Position cursor in window. */
9436 if (!hscroll_relative_p && hscroll_step_abs == 0)
9437 hscroll = max (0, (it.current_x
9438 - (ITERATOR_AT_END_OF_LINE_P (&it)
9439 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9440 : (text_area_width / 2))))
9441 / FRAME_COLUMN_WIDTH (it.f);
9442 else if (w->cursor.x >= text_area_width - h_margin)
9443 {
9444 if (hscroll_relative_p)
9445 wanted_x = text_area_width * (1 - hscroll_step_rel)
9446 - h_margin;
9447 else
9448 wanted_x = text_area_width
9449 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9450 - h_margin;
9451 hscroll
9452 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9453 }
9454 else
9455 {
9456 if (hscroll_relative_p)
9457 wanted_x = text_area_width * hscroll_step_rel
9458 + h_margin;
9459 else
9460 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9461 + h_margin;
9462 hscroll
9463 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9464 }
9465 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9466
9467 /* Don't call Fset_window_hscroll if value hasn't
9468 changed because it will prevent redisplay
9469 optimizations. */
9470 if (XFASTINT (w->hscroll) != hscroll)
9471 {
9472 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9473 w->hscroll = make_number (hscroll);
9474 hscrolled_p = 1;
9475 }
9476 }
9477 }
9478
9479 window = w->next;
9480 }
9481
9482 /* Value is non-zero if hscroll of any leaf window has been changed. */
9483 return hscrolled_p;
9484 }
9485
9486
9487 /* Set hscroll so that cursor is visible and not inside horizontal
9488 scroll margins for all windows in the tree rooted at WINDOW. See
9489 also hscroll_window_tree above. Value is non-zero if any window's
9490 hscroll has been changed. If it has, desired matrices on the frame
9491 of WINDOW are cleared. */
9492
9493 static int
9494 hscroll_windows (window)
9495 Lisp_Object window;
9496 {
9497 int hscrolled_p;
9498
9499 if (automatic_hscrolling_p)
9500 {
9501 hscrolled_p = hscroll_window_tree (window);
9502 if (hscrolled_p)
9503 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9504 }
9505 else
9506 hscrolled_p = 0;
9507 return hscrolled_p;
9508 }
9509
9510
9511 \f
9512 /************************************************************************
9513 Redisplay
9514 ************************************************************************/
9515
9516 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9517 to a non-zero value. This is sometimes handy to have in a debugger
9518 session. */
9519
9520 #if GLYPH_DEBUG
9521
9522 /* First and last unchanged row for try_window_id. */
9523
9524 int debug_first_unchanged_at_end_vpos;
9525 int debug_last_unchanged_at_beg_vpos;
9526
9527 /* Delta vpos and y. */
9528
9529 int debug_dvpos, debug_dy;
9530
9531 /* Delta in characters and bytes for try_window_id. */
9532
9533 int debug_delta, debug_delta_bytes;
9534
9535 /* Values of window_end_pos and window_end_vpos at the end of
9536 try_window_id. */
9537
9538 EMACS_INT debug_end_pos, debug_end_vpos;
9539
9540 /* Append a string to W->desired_matrix->method. FMT is a printf
9541 format string. A1...A9 are a supplement for a variable-length
9542 argument list. If trace_redisplay_p is non-zero also printf the
9543 resulting string to stderr. */
9544
9545 static void
9546 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9547 struct window *w;
9548 char *fmt;
9549 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9550 {
9551 char buffer[512];
9552 char *method = w->desired_matrix->method;
9553 int len = strlen (method);
9554 int size = sizeof w->desired_matrix->method;
9555 int remaining = size - len - 1;
9556
9557 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9558 if (len && remaining)
9559 {
9560 method[len] = '|';
9561 --remaining, ++len;
9562 }
9563
9564 strncpy (method + len, buffer, remaining);
9565
9566 if (trace_redisplay_p)
9567 fprintf (stderr, "%p (%s): %s\n",
9568 w,
9569 ((BUFFERP (w->buffer)
9570 && STRINGP (XBUFFER (w->buffer)->name))
9571 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9572 : "no buffer"),
9573 buffer);
9574 }
9575
9576 #endif /* GLYPH_DEBUG */
9577
9578
9579 /* Value is non-zero if all changes in window W, which displays
9580 current_buffer, are in the text between START and END. START is a
9581 buffer position, END is given as a distance from Z. Used in
9582 redisplay_internal for display optimization. */
9583
9584 static INLINE int
9585 text_outside_line_unchanged_p (w, start, end)
9586 struct window *w;
9587 int start, end;
9588 {
9589 int unchanged_p = 1;
9590
9591 /* If text or overlays have changed, see where. */
9592 if (XFASTINT (w->last_modified) < MODIFF
9593 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9594 {
9595 /* Gap in the line? */
9596 if (GPT < start || Z - GPT < end)
9597 unchanged_p = 0;
9598
9599 /* Changes start in front of the line, or end after it? */
9600 if (unchanged_p
9601 && (BEG_UNCHANGED < start - 1
9602 || END_UNCHANGED < end))
9603 unchanged_p = 0;
9604
9605 /* If selective display, can't optimize if changes start at the
9606 beginning of the line. */
9607 if (unchanged_p
9608 && INTEGERP (current_buffer->selective_display)
9609 && XINT (current_buffer->selective_display) > 0
9610 && (BEG_UNCHANGED < start || GPT <= start))
9611 unchanged_p = 0;
9612
9613 /* If there are overlays at the start or end of the line, these
9614 may have overlay strings with newlines in them. A change at
9615 START, for instance, may actually concern the display of such
9616 overlay strings as well, and they are displayed on different
9617 lines. So, quickly rule out this case. (For the future, it
9618 might be desirable to implement something more telling than
9619 just BEG/END_UNCHANGED.) */
9620 if (unchanged_p)
9621 {
9622 if (BEG + BEG_UNCHANGED == start
9623 && overlay_touches_p (start))
9624 unchanged_p = 0;
9625 if (END_UNCHANGED == end
9626 && overlay_touches_p (Z - end))
9627 unchanged_p = 0;
9628 }
9629 }
9630
9631 return unchanged_p;
9632 }
9633
9634
9635 /* Do a frame update, taking possible shortcuts into account. This is
9636 the main external entry point for redisplay.
9637
9638 If the last redisplay displayed an echo area message and that message
9639 is no longer requested, we clear the echo area or bring back the
9640 mini-buffer if that is in use. */
9641
9642 void
9643 redisplay ()
9644 {
9645 redisplay_internal (0);
9646 }
9647
9648
9649 static Lisp_Object
9650 overlay_arrow_string_or_property (var, pbitmap)
9651 Lisp_Object var;
9652 int *pbitmap;
9653 {
9654 Lisp_Object pstr = Fget (var, Qoverlay_arrow_string);
9655 Lisp_Object bitmap;
9656
9657 if (pbitmap)
9658 {
9659 *pbitmap = 0;
9660 if (bitmap = Fget (var, Qoverlay_arrow_bitmap), INTEGERP (bitmap))
9661 *pbitmap = XINT (bitmap);
9662 }
9663
9664 if (!NILP (pstr))
9665 return pstr;
9666 return Voverlay_arrow_string;
9667 }
9668
9669 /* Return 1 if there are any overlay-arrows in current_buffer. */
9670 static int
9671 overlay_arrow_in_current_buffer_p ()
9672 {
9673 Lisp_Object vlist;
9674
9675 for (vlist = Voverlay_arrow_variable_list;
9676 CONSP (vlist);
9677 vlist = XCDR (vlist))
9678 {
9679 Lisp_Object var = XCAR (vlist);
9680 Lisp_Object val;
9681
9682 if (!SYMBOLP (var))
9683 continue;
9684 val = find_symbol_value (var);
9685 if (MARKERP (val)
9686 && current_buffer == XMARKER (val)->buffer)
9687 return 1;
9688 }
9689 return 0;
9690 }
9691
9692
9693 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9694 has changed. */
9695
9696 static int
9697 overlay_arrows_changed_p ()
9698 {
9699 Lisp_Object vlist;
9700
9701 for (vlist = Voverlay_arrow_variable_list;
9702 CONSP (vlist);
9703 vlist = XCDR (vlist))
9704 {
9705 Lisp_Object var = XCAR (vlist);
9706 Lisp_Object val, pstr;
9707
9708 if (!SYMBOLP (var))
9709 continue;
9710 val = find_symbol_value (var);
9711 if (!MARKERP (val))
9712 continue;
9713 if (! EQ (COERCE_MARKER (val),
9714 Fget (var, Qlast_arrow_position))
9715 || ! (pstr = overlay_arrow_string_or_property (var, 0),
9716 EQ (pstr, Fget (var, Qlast_arrow_string))))
9717 return 1;
9718 }
9719 return 0;
9720 }
9721
9722 /* Mark overlay arrows to be updated on next redisplay. */
9723
9724 static void
9725 update_overlay_arrows (up_to_date)
9726 int up_to_date;
9727 {
9728 Lisp_Object vlist;
9729
9730 for (vlist = Voverlay_arrow_variable_list;
9731 CONSP (vlist);
9732 vlist = XCDR (vlist))
9733 {
9734 Lisp_Object var = XCAR (vlist);
9735
9736 if (!SYMBOLP (var))
9737 continue;
9738
9739 if (up_to_date > 0)
9740 {
9741 Lisp_Object val = find_symbol_value (var);
9742 Fput (var, Qlast_arrow_position,
9743 COERCE_MARKER (val));
9744 Fput (var, Qlast_arrow_string,
9745 overlay_arrow_string_or_property (var, 0));
9746 }
9747 else if (up_to_date < 0
9748 || !NILP (Fget (var, Qlast_arrow_position)))
9749 {
9750 Fput (var, Qlast_arrow_position, Qt);
9751 Fput (var, Qlast_arrow_string, Qt);
9752 }
9753 }
9754 }
9755
9756
9757 /* Return overlay arrow string to display at row.
9758 Return t if display as bitmap in left fringe.
9759 Return nil if no overlay arrow. */
9760
9761 static Lisp_Object
9762 overlay_arrow_at_row (it, row, pbitmap)
9763 struct it *it;
9764 struct glyph_row *row;
9765 int *pbitmap;
9766 {
9767 Lisp_Object vlist;
9768
9769 for (vlist = Voverlay_arrow_variable_list;
9770 CONSP (vlist);
9771 vlist = XCDR (vlist))
9772 {
9773 Lisp_Object var = XCAR (vlist);
9774 Lisp_Object val;
9775
9776 if (!SYMBOLP (var))
9777 continue;
9778
9779 val = find_symbol_value (var);
9780
9781 if (MARKERP (val)
9782 && current_buffer == XMARKER (val)->buffer
9783 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9784 {
9785 val = overlay_arrow_string_or_property (var, pbitmap);
9786 if (FRAME_WINDOW_P (it->f)
9787 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9788 return Qt;
9789 if (STRINGP (val))
9790 return val;
9791 break;
9792 }
9793 }
9794
9795 *pbitmap = 0;
9796 return Qnil;
9797 }
9798
9799 /* Return 1 if point moved out of or into a composition. Otherwise
9800 return 0. PREV_BUF and PREV_PT are the last point buffer and
9801 position. BUF and PT are the current point buffer and position. */
9802
9803 int
9804 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9805 struct buffer *prev_buf, *buf;
9806 int prev_pt, pt;
9807 {
9808 int start, end;
9809 Lisp_Object prop;
9810 Lisp_Object buffer;
9811
9812 XSETBUFFER (buffer, buf);
9813 /* Check a composition at the last point if point moved within the
9814 same buffer. */
9815 if (prev_buf == buf)
9816 {
9817 if (prev_pt == pt)
9818 /* Point didn't move. */
9819 return 0;
9820
9821 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9822 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9823 && COMPOSITION_VALID_P (start, end, prop)
9824 && start < prev_pt && end > prev_pt)
9825 /* The last point was within the composition. Return 1 iff
9826 point moved out of the composition. */
9827 return (pt <= start || pt >= end);
9828 }
9829
9830 /* Check a composition at the current point. */
9831 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9832 && find_composition (pt, -1, &start, &end, &prop, buffer)
9833 && COMPOSITION_VALID_P (start, end, prop)
9834 && start < pt && end > pt);
9835 }
9836
9837
9838 /* Reconsider the setting of B->clip_changed which is displayed
9839 in window W. */
9840
9841 static INLINE void
9842 reconsider_clip_changes (w, b)
9843 struct window *w;
9844 struct buffer *b;
9845 {
9846 if (b->clip_changed
9847 && !NILP (w->window_end_valid)
9848 && w->current_matrix->buffer == b
9849 && w->current_matrix->zv == BUF_ZV (b)
9850 && w->current_matrix->begv == BUF_BEGV (b))
9851 b->clip_changed = 0;
9852
9853 /* If display wasn't paused, and W is not a tool bar window, see if
9854 point has been moved into or out of a composition. In that case,
9855 we set b->clip_changed to 1 to force updating the screen. If
9856 b->clip_changed has already been set to 1, we can skip this
9857 check. */
9858 if (!b->clip_changed
9859 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9860 {
9861 int pt;
9862
9863 if (w == XWINDOW (selected_window))
9864 pt = BUF_PT (current_buffer);
9865 else
9866 pt = marker_position (w->pointm);
9867
9868 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9869 || pt != XINT (w->last_point))
9870 && check_point_in_composition (w->current_matrix->buffer,
9871 XINT (w->last_point),
9872 XBUFFER (w->buffer), pt))
9873 b->clip_changed = 1;
9874 }
9875 }
9876 \f
9877
9878 /* Select FRAME to forward the values of frame-local variables into C
9879 variables so that the redisplay routines can access those values
9880 directly. */
9881
9882 static void
9883 select_frame_for_redisplay (frame)
9884 Lisp_Object frame;
9885 {
9886 Lisp_Object tail, sym, val;
9887 Lisp_Object old = selected_frame;
9888
9889 selected_frame = frame;
9890
9891 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9892 if (CONSP (XCAR (tail))
9893 && (sym = XCAR (XCAR (tail)),
9894 SYMBOLP (sym))
9895 && (sym = indirect_variable (sym),
9896 val = SYMBOL_VALUE (sym),
9897 (BUFFER_LOCAL_VALUEP (val)
9898 || SOME_BUFFER_LOCAL_VALUEP (val)))
9899 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9900 Fsymbol_value (sym);
9901
9902 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9903 if (CONSP (XCAR (tail))
9904 && (sym = XCAR (XCAR (tail)),
9905 SYMBOLP (sym))
9906 && (sym = indirect_variable (sym),
9907 val = SYMBOL_VALUE (sym),
9908 (BUFFER_LOCAL_VALUEP (val)
9909 || SOME_BUFFER_LOCAL_VALUEP (val)))
9910 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9911 Fsymbol_value (sym);
9912 }
9913
9914
9915 #define STOP_POLLING \
9916 do { if (! polling_stopped_here) stop_polling (); \
9917 polling_stopped_here = 1; } while (0)
9918
9919 #define RESUME_POLLING \
9920 do { if (polling_stopped_here) start_polling (); \
9921 polling_stopped_here = 0; } while (0)
9922
9923
9924 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9925 response to any user action; therefore, we should preserve the echo
9926 area. (Actually, our caller does that job.) Perhaps in the future
9927 avoid recentering windows if it is not necessary; currently that
9928 causes some problems. */
9929
9930 static void
9931 redisplay_internal (preserve_echo_area)
9932 int preserve_echo_area;
9933 {
9934 struct window *w = XWINDOW (selected_window);
9935 struct frame *f = XFRAME (w->frame);
9936 int pause;
9937 int must_finish = 0;
9938 struct text_pos tlbufpos, tlendpos;
9939 int number_of_visible_frames;
9940 int count;
9941 struct frame *sf = SELECTED_FRAME ();
9942 int polling_stopped_here = 0;
9943
9944 /* Non-zero means redisplay has to consider all windows on all
9945 frames. Zero means, only selected_window is considered. */
9946 int consider_all_windows_p;
9947
9948 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9949
9950 /* No redisplay if running in batch mode or frame is not yet fully
9951 initialized, or redisplay is explicitly turned off by setting
9952 Vinhibit_redisplay. */
9953 if (noninteractive
9954 || !NILP (Vinhibit_redisplay)
9955 || !f->glyphs_initialized_p)
9956 return;
9957
9958 /* The flag redisplay_performed_directly_p is set by
9959 direct_output_for_insert when it already did the whole screen
9960 update necessary. */
9961 if (redisplay_performed_directly_p)
9962 {
9963 redisplay_performed_directly_p = 0;
9964 if (!hscroll_windows (selected_window))
9965 return;
9966 }
9967
9968 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9969 if (popup_activated ())
9970 return;
9971 #endif
9972
9973 /* I don't think this happens but let's be paranoid. */
9974 if (redisplaying_p)
9975 return;
9976
9977 /* Record a function that resets redisplaying_p to its old value
9978 when we leave this function. */
9979 count = SPECPDL_INDEX ();
9980 record_unwind_protect (unwind_redisplay,
9981 Fcons (make_number (redisplaying_p), selected_frame));
9982 ++redisplaying_p;
9983 specbind (Qinhibit_free_realized_faces, Qnil);
9984
9985 retry:
9986 pause = 0;
9987 reconsider_clip_changes (w, current_buffer);
9988
9989 /* If new fonts have been loaded that make a glyph matrix adjustment
9990 necessary, do it. */
9991 if (fonts_changed_p)
9992 {
9993 adjust_glyphs (NULL);
9994 ++windows_or_buffers_changed;
9995 fonts_changed_p = 0;
9996 }
9997
9998 /* If face_change_count is non-zero, init_iterator will free all
9999 realized faces, which includes the faces referenced from current
10000 matrices. So, we can't reuse current matrices in this case. */
10001 if (face_change_count)
10002 ++windows_or_buffers_changed;
10003
10004 if (! FRAME_WINDOW_P (sf)
10005 && previous_terminal_frame != sf)
10006 {
10007 /* Since frames on an ASCII terminal share the same display
10008 area, displaying a different frame means redisplay the whole
10009 thing. */
10010 windows_or_buffers_changed++;
10011 SET_FRAME_GARBAGED (sf);
10012 XSETFRAME (Vterminal_frame, sf);
10013 }
10014 previous_terminal_frame = sf;
10015
10016 /* Set the visible flags for all frames. Do this before checking
10017 for resized or garbaged frames; they want to know if their frames
10018 are visible. See the comment in frame.h for
10019 FRAME_SAMPLE_VISIBILITY. */
10020 {
10021 Lisp_Object tail, frame;
10022
10023 number_of_visible_frames = 0;
10024
10025 FOR_EACH_FRAME (tail, frame)
10026 {
10027 struct frame *f = XFRAME (frame);
10028
10029 FRAME_SAMPLE_VISIBILITY (f);
10030 if (FRAME_VISIBLE_P (f))
10031 ++number_of_visible_frames;
10032 clear_desired_matrices (f);
10033 }
10034 }
10035
10036 /* Notice any pending interrupt request to change frame size. */
10037 do_pending_window_change (1);
10038
10039 /* Clear frames marked as garbaged. */
10040 if (frame_garbaged)
10041 clear_garbaged_frames ();
10042
10043 /* Build menubar and tool-bar items. */
10044 prepare_menu_bars ();
10045
10046 if (windows_or_buffers_changed)
10047 update_mode_lines++;
10048
10049 /* Detect case that we need to write or remove a star in the mode line. */
10050 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10051 {
10052 w->update_mode_line = Qt;
10053 if (buffer_shared > 1)
10054 update_mode_lines++;
10055 }
10056
10057 /* If %c is in the mode line, update it if needed. */
10058 if (!NILP (w->column_number_displayed)
10059 /* This alternative quickly identifies a common case
10060 where no change is needed. */
10061 && !(PT == XFASTINT (w->last_point)
10062 && XFASTINT (w->last_modified) >= MODIFF
10063 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10064 && (XFASTINT (w->column_number_displayed)
10065 != (int) current_column ())) /* iftc */
10066 w->update_mode_line = Qt;
10067
10068 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10069
10070 /* The variable buffer_shared is set in redisplay_window and
10071 indicates that we redisplay a buffer in different windows. See
10072 there. */
10073 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10074 || cursor_type_changed);
10075
10076 /* If specs for an arrow have changed, do thorough redisplay
10077 to ensure we remove any arrow that should no longer exist. */
10078 if (overlay_arrows_changed_p ())
10079 consider_all_windows_p = windows_or_buffers_changed = 1;
10080
10081 /* Normally the message* functions will have already displayed and
10082 updated the echo area, but the frame may have been trashed, or
10083 the update may have been preempted, so display the echo area
10084 again here. Checking message_cleared_p captures the case that
10085 the echo area should be cleared. */
10086 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10087 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10088 || (message_cleared_p
10089 && minibuf_level == 0
10090 /* If the mini-window is currently selected, this means the
10091 echo-area doesn't show through. */
10092 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10093 {
10094 int window_height_changed_p = echo_area_display (0);
10095 must_finish = 1;
10096
10097 /* If we don't display the current message, don't clear the
10098 message_cleared_p flag, because, if we did, we wouldn't clear
10099 the echo area in the next redisplay which doesn't preserve
10100 the echo area. */
10101 if (!display_last_displayed_message_p)
10102 message_cleared_p = 0;
10103
10104 if (fonts_changed_p)
10105 goto retry;
10106 else if (window_height_changed_p)
10107 {
10108 consider_all_windows_p = 1;
10109 ++update_mode_lines;
10110 ++windows_or_buffers_changed;
10111
10112 /* If window configuration was changed, frames may have been
10113 marked garbaged. Clear them or we will experience
10114 surprises wrt scrolling. */
10115 if (frame_garbaged)
10116 clear_garbaged_frames ();
10117 }
10118 }
10119 else if (EQ (selected_window, minibuf_window)
10120 && (current_buffer->clip_changed
10121 || XFASTINT (w->last_modified) < MODIFF
10122 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10123 && resize_mini_window (w, 0))
10124 {
10125 /* Resized active mini-window to fit the size of what it is
10126 showing if its contents might have changed. */
10127 must_finish = 1;
10128 consider_all_windows_p = 1;
10129 ++windows_or_buffers_changed;
10130 ++update_mode_lines;
10131
10132 /* If window configuration was changed, frames may have been
10133 marked garbaged. Clear them or we will experience
10134 surprises wrt scrolling. */
10135 if (frame_garbaged)
10136 clear_garbaged_frames ();
10137 }
10138
10139
10140 /* If showing the region, and mark has changed, we must redisplay
10141 the whole window. The assignment to this_line_start_pos prevents
10142 the optimization directly below this if-statement. */
10143 if (((!NILP (Vtransient_mark_mode)
10144 && !NILP (XBUFFER (w->buffer)->mark_active))
10145 != !NILP (w->region_showing))
10146 || (!NILP (w->region_showing)
10147 && !EQ (w->region_showing,
10148 Fmarker_position (XBUFFER (w->buffer)->mark))))
10149 CHARPOS (this_line_start_pos) = 0;
10150
10151 /* Optimize the case that only the line containing the cursor in the
10152 selected window has changed. Variables starting with this_ are
10153 set in display_line and record information about the line
10154 containing the cursor. */
10155 tlbufpos = this_line_start_pos;
10156 tlendpos = this_line_end_pos;
10157 if (!consider_all_windows_p
10158 && CHARPOS (tlbufpos) > 0
10159 && NILP (w->update_mode_line)
10160 && !current_buffer->clip_changed
10161 && !current_buffer->prevent_redisplay_optimizations_p
10162 && FRAME_VISIBLE_P (XFRAME (w->frame))
10163 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10164 /* Make sure recorded data applies to current buffer, etc. */
10165 && this_line_buffer == current_buffer
10166 && current_buffer == XBUFFER (w->buffer)
10167 && NILP (w->force_start)
10168 && NILP (w->optional_new_start)
10169 /* Point must be on the line that we have info recorded about. */
10170 && PT >= CHARPOS (tlbufpos)
10171 && PT <= Z - CHARPOS (tlendpos)
10172 /* All text outside that line, including its final newline,
10173 must be unchanged */
10174 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10175 CHARPOS (tlendpos)))
10176 {
10177 if (CHARPOS (tlbufpos) > BEGV
10178 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10179 && (CHARPOS (tlbufpos) == ZV
10180 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10181 /* Former continuation line has disappeared by becoming empty */
10182 goto cancel;
10183 else if (XFASTINT (w->last_modified) < MODIFF
10184 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10185 || MINI_WINDOW_P (w))
10186 {
10187 /* We have to handle the case of continuation around a
10188 wide-column character (See the comment in indent.c around
10189 line 885).
10190
10191 For instance, in the following case:
10192
10193 -------- Insert --------
10194 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10195 J_I_ ==> J_I_ `^^' are cursors.
10196 ^^ ^^
10197 -------- --------
10198
10199 As we have to redraw the line above, we should goto cancel. */
10200
10201 struct it it;
10202 int line_height_before = this_line_pixel_height;
10203
10204 /* Note that start_display will handle the case that the
10205 line starting at tlbufpos is a continuation lines. */
10206 start_display (&it, w, tlbufpos);
10207
10208 /* Implementation note: It this still necessary? */
10209 if (it.current_x != this_line_start_x)
10210 goto cancel;
10211
10212 TRACE ((stderr, "trying display optimization 1\n"));
10213 w->cursor.vpos = -1;
10214 overlay_arrow_seen = 0;
10215 it.vpos = this_line_vpos;
10216 it.current_y = this_line_y;
10217 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10218 display_line (&it);
10219
10220 /* If line contains point, is not continued,
10221 and ends at same distance from eob as before, we win */
10222 if (w->cursor.vpos >= 0
10223 /* Line is not continued, otherwise this_line_start_pos
10224 would have been set to 0 in display_line. */
10225 && CHARPOS (this_line_start_pos)
10226 /* Line ends as before. */
10227 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10228 /* Line has same height as before. Otherwise other lines
10229 would have to be shifted up or down. */
10230 && this_line_pixel_height == line_height_before)
10231 {
10232 /* If this is not the window's last line, we must adjust
10233 the charstarts of the lines below. */
10234 if (it.current_y < it.last_visible_y)
10235 {
10236 struct glyph_row *row
10237 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10238 int delta, delta_bytes;
10239
10240 if (Z - CHARPOS (tlendpos) == ZV)
10241 {
10242 /* This line ends at end of (accessible part of)
10243 buffer. There is no newline to count. */
10244 delta = (Z
10245 - CHARPOS (tlendpos)
10246 - MATRIX_ROW_START_CHARPOS (row));
10247 delta_bytes = (Z_BYTE
10248 - BYTEPOS (tlendpos)
10249 - MATRIX_ROW_START_BYTEPOS (row));
10250 }
10251 else
10252 {
10253 /* This line ends in a newline. Must take
10254 account of the newline and the rest of the
10255 text that follows. */
10256 delta = (Z
10257 - CHARPOS (tlendpos)
10258 - MATRIX_ROW_START_CHARPOS (row));
10259 delta_bytes = (Z_BYTE
10260 - BYTEPOS (tlendpos)
10261 - MATRIX_ROW_START_BYTEPOS (row));
10262 }
10263
10264 increment_matrix_positions (w->current_matrix,
10265 this_line_vpos + 1,
10266 w->current_matrix->nrows,
10267 delta, delta_bytes);
10268 }
10269
10270 /* If this row displays text now but previously didn't,
10271 or vice versa, w->window_end_vpos may have to be
10272 adjusted. */
10273 if ((it.glyph_row - 1)->displays_text_p)
10274 {
10275 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10276 XSETINT (w->window_end_vpos, this_line_vpos);
10277 }
10278 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10279 && this_line_vpos > 0)
10280 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10281 w->window_end_valid = Qnil;
10282
10283 /* Update hint: No need to try to scroll in update_window. */
10284 w->desired_matrix->no_scrolling_p = 1;
10285
10286 #if GLYPH_DEBUG
10287 *w->desired_matrix->method = 0;
10288 debug_method_add (w, "optimization 1");
10289 #endif
10290 #ifdef HAVE_WINDOW_SYSTEM
10291 update_window_fringes (w, 0);
10292 #endif
10293 goto update;
10294 }
10295 else
10296 goto cancel;
10297 }
10298 else if (/* Cursor position hasn't changed. */
10299 PT == XFASTINT (w->last_point)
10300 /* Make sure the cursor was last displayed
10301 in this window. Otherwise we have to reposition it. */
10302 && 0 <= w->cursor.vpos
10303 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10304 {
10305 if (!must_finish)
10306 {
10307 do_pending_window_change (1);
10308
10309 /* We used to always goto end_of_redisplay here, but this
10310 isn't enough if we have a blinking cursor. */
10311 if (w->cursor_off_p == w->last_cursor_off_p)
10312 goto end_of_redisplay;
10313 }
10314 goto update;
10315 }
10316 /* If highlighting the region, or if the cursor is in the echo area,
10317 then we can't just move the cursor. */
10318 else if (! (!NILP (Vtransient_mark_mode)
10319 && !NILP (current_buffer->mark_active))
10320 && (EQ (selected_window, current_buffer->last_selected_window)
10321 || highlight_nonselected_windows)
10322 && NILP (w->region_showing)
10323 && NILP (Vshow_trailing_whitespace)
10324 && !cursor_in_echo_area)
10325 {
10326 struct it it;
10327 struct glyph_row *row;
10328
10329 /* Skip from tlbufpos to PT and see where it is. Note that
10330 PT may be in invisible text. If so, we will end at the
10331 next visible position. */
10332 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10333 NULL, DEFAULT_FACE_ID);
10334 it.current_x = this_line_start_x;
10335 it.current_y = this_line_y;
10336 it.vpos = this_line_vpos;
10337
10338 /* The call to move_it_to stops in front of PT, but
10339 moves over before-strings. */
10340 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10341
10342 if (it.vpos == this_line_vpos
10343 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10344 row->enabled_p))
10345 {
10346 xassert (this_line_vpos == it.vpos);
10347 xassert (this_line_y == it.current_y);
10348 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10349 #if GLYPH_DEBUG
10350 *w->desired_matrix->method = 0;
10351 debug_method_add (w, "optimization 3");
10352 #endif
10353 goto update;
10354 }
10355 else
10356 goto cancel;
10357 }
10358
10359 cancel:
10360 /* Text changed drastically or point moved off of line. */
10361 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10362 }
10363
10364 CHARPOS (this_line_start_pos) = 0;
10365 consider_all_windows_p |= buffer_shared > 1;
10366 ++clear_face_cache_count;
10367 #ifdef HAVE_WINDOW_SYSTEM
10368 ++clear_image_cache_count;
10369 #endif
10370
10371 /* Build desired matrices, and update the display. If
10372 consider_all_windows_p is non-zero, do it for all windows on all
10373 frames. Otherwise do it for selected_window, only. */
10374
10375 if (consider_all_windows_p)
10376 {
10377 Lisp_Object tail, frame;
10378 int i, n = 0, size = 50;
10379 struct frame **updated
10380 = (struct frame **) alloca (size * sizeof *updated);
10381
10382 /* Recompute # windows showing selected buffer. This will be
10383 incremented each time such a window is displayed. */
10384 buffer_shared = 0;
10385
10386 FOR_EACH_FRAME (tail, frame)
10387 {
10388 struct frame *f = XFRAME (frame);
10389
10390 if (FRAME_WINDOW_P (f) || f == sf)
10391 {
10392 if (! EQ (frame, selected_frame))
10393 /* Select the frame, for the sake of frame-local
10394 variables. */
10395 select_frame_for_redisplay (frame);
10396
10397 /* Mark all the scroll bars to be removed; we'll redeem
10398 the ones we want when we redisplay their windows. */
10399 if (condemn_scroll_bars_hook)
10400 condemn_scroll_bars_hook (f);
10401
10402 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10403 redisplay_windows (FRAME_ROOT_WINDOW (f));
10404
10405 /* Any scroll bars which redisplay_windows should have
10406 nuked should now go away. */
10407 if (judge_scroll_bars_hook)
10408 judge_scroll_bars_hook (f);
10409
10410 /* If fonts changed, display again. */
10411 /* ??? rms: I suspect it is a mistake to jump all the way
10412 back to retry here. It should just retry this frame. */
10413 if (fonts_changed_p)
10414 goto retry;
10415
10416 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10417 {
10418 /* See if we have to hscroll. */
10419 if (hscroll_windows (f->root_window))
10420 goto retry;
10421
10422 /* Prevent various kinds of signals during display
10423 update. stdio is not robust about handling
10424 signals, which can cause an apparent I/O
10425 error. */
10426 if (interrupt_input)
10427 unrequest_sigio ();
10428 STOP_POLLING;
10429
10430 /* Update the display. */
10431 set_window_update_flags (XWINDOW (f->root_window), 1);
10432 pause |= update_frame (f, 0, 0);
10433 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10434 if (pause)
10435 break;
10436 #endif
10437
10438 if (n == size)
10439 {
10440 int nbytes = size * sizeof *updated;
10441 struct frame **p = (struct frame **) alloca (2 * nbytes);
10442 bcopy (updated, p, nbytes);
10443 size *= 2;
10444 }
10445
10446 updated[n++] = f;
10447 }
10448 }
10449 }
10450
10451 if (!pause)
10452 {
10453 /* Do the mark_window_display_accurate after all windows have
10454 been redisplayed because this call resets flags in buffers
10455 which are needed for proper redisplay. */
10456 for (i = 0; i < n; ++i)
10457 {
10458 struct frame *f = updated[i];
10459 mark_window_display_accurate (f->root_window, 1);
10460 if (frame_up_to_date_hook)
10461 frame_up_to_date_hook (f);
10462 }
10463 }
10464 }
10465 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10466 {
10467 Lisp_Object mini_window;
10468 struct frame *mini_frame;
10469
10470 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10471 /* Use list_of_error, not Qerror, so that
10472 we catch only errors and don't run the debugger. */
10473 internal_condition_case_1 (redisplay_window_1, selected_window,
10474 list_of_error,
10475 redisplay_window_error);
10476
10477 /* Compare desired and current matrices, perform output. */
10478
10479 update:
10480 /* If fonts changed, display again. */
10481 if (fonts_changed_p)
10482 goto retry;
10483
10484 /* Prevent various kinds of signals during display update.
10485 stdio is not robust about handling signals,
10486 which can cause an apparent I/O error. */
10487 if (interrupt_input)
10488 unrequest_sigio ();
10489 STOP_POLLING;
10490
10491 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10492 {
10493 if (hscroll_windows (selected_window))
10494 goto retry;
10495
10496 XWINDOW (selected_window)->must_be_updated_p = 1;
10497 pause = update_frame (sf, 0, 0);
10498 }
10499
10500 /* We may have called echo_area_display at the top of this
10501 function. If the echo area is on another frame, that may
10502 have put text on a frame other than the selected one, so the
10503 above call to update_frame would not have caught it. Catch
10504 it here. */
10505 mini_window = FRAME_MINIBUF_WINDOW (sf);
10506 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10507
10508 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10509 {
10510 XWINDOW (mini_window)->must_be_updated_p = 1;
10511 pause |= update_frame (mini_frame, 0, 0);
10512 if (!pause && hscroll_windows (mini_window))
10513 goto retry;
10514 }
10515 }
10516
10517 /* If display was paused because of pending input, make sure we do a
10518 thorough update the next time. */
10519 if (pause)
10520 {
10521 /* Prevent the optimization at the beginning of
10522 redisplay_internal that tries a single-line update of the
10523 line containing the cursor in the selected window. */
10524 CHARPOS (this_line_start_pos) = 0;
10525
10526 /* Let the overlay arrow be updated the next time. */
10527 update_overlay_arrows (0);
10528
10529 /* If we pause after scrolling, some rows in the current
10530 matrices of some windows are not valid. */
10531 if (!WINDOW_FULL_WIDTH_P (w)
10532 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10533 update_mode_lines = 1;
10534 }
10535 else
10536 {
10537 if (!consider_all_windows_p)
10538 {
10539 /* This has already been done above if
10540 consider_all_windows_p is set. */
10541 mark_window_display_accurate_1 (w, 1);
10542
10543 /* Say overlay arrows are up to date. */
10544 update_overlay_arrows (1);
10545
10546 if (frame_up_to_date_hook != 0)
10547 frame_up_to_date_hook (sf);
10548 }
10549
10550 update_mode_lines = 0;
10551 windows_or_buffers_changed = 0;
10552 cursor_type_changed = 0;
10553 }
10554
10555 /* Start SIGIO interrupts coming again. Having them off during the
10556 code above makes it less likely one will discard output, but not
10557 impossible, since there might be stuff in the system buffer here.
10558 But it is much hairier to try to do anything about that. */
10559 if (interrupt_input)
10560 request_sigio ();
10561 RESUME_POLLING;
10562
10563 /* If a frame has become visible which was not before, redisplay
10564 again, so that we display it. Expose events for such a frame
10565 (which it gets when becoming visible) don't call the parts of
10566 redisplay constructing glyphs, so simply exposing a frame won't
10567 display anything in this case. So, we have to display these
10568 frames here explicitly. */
10569 if (!pause)
10570 {
10571 Lisp_Object tail, frame;
10572 int new_count = 0;
10573
10574 FOR_EACH_FRAME (tail, frame)
10575 {
10576 int this_is_visible = 0;
10577
10578 if (XFRAME (frame)->visible)
10579 this_is_visible = 1;
10580 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10581 if (XFRAME (frame)->visible)
10582 this_is_visible = 1;
10583
10584 if (this_is_visible)
10585 new_count++;
10586 }
10587
10588 if (new_count != number_of_visible_frames)
10589 windows_or_buffers_changed++;
10590 }
10591
10592 /* Change frame size now if a change is pending. */
10593 do_pending_window_change (1);
10594
10595 /* If we just did a pending size change, or have additional
10596 visible frames, redisplay again. */
10597 if (windows_or_buffers_changed && !pause)
10598 goto retry;
10599
10600 /* Clear the face cache eventually. */
10601 if (consider_all_windows_p)
10602 {
10603 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10604 {
10605 clear_face_cache (0);
10606 clear_face_cache_count = 0;
10607 }
10608 #ifdef HAVE_WINDOW_SYSTEM
10609 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
10610 {
10611 Lisp_Object tail, frame;
10612 FOR_EACH_FRAME (tail, frame)
10613 {
10614 struct frame *f = XFRAME (frame);
10615 if (FRAME_WINDOW_P (f))
10616 clear_image_cache (f, 0);
10617 }
10618 clear_image_cache_count = 0;
10619 }
10620 #endif /* HAVE_WINDOW_SYSTEM */
10621 }
10622
10623 end_of_redisplay:
10624 unbind_to (count, Qnil);
10625 RESUME_POLLING;
10626 }
10627
10628
10629 /* Redisplay, but leave alone any recent echo area message unless
10630 another message has been requested in its place.
10631
10632 This is useful in situations where you need to redisplay but no
10633 user action has occurred, making it inappropriate for the message
10634 area to be cleared. See tracking_off and
10635 wait_reading_process_output for examples of these situations.
10636
10637 FROM_WHERE is an integer saying from where this function was
10638 called. This is useful for debugging. */
10639
10640 void
10641 redisplay_preserve_echo_area (from_where)
10642 int from_where;
10643 {
10644 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10645
10646 if (!NILP (echo_area_buffer[1]))
10647 {
10648 /* We have a previously displayed message, but no current
10649 message. Redisplay the previous message. */
10650 display_last_displayed_message_p = 1;
10651 redisplay_internal (1);
10652 display_last_displayed_message_p = 0;
10653 }
10654 else
10655 redisplay_internal (1);
10656
10657 if (rif != NULL && rif->flush_display_optional)
10658 rif->flush_display_optional (NULL);
10659 }
10660
10661
10662 /* Function registered with record_unwind_protect in
10663 redisplay_internal. Reset redisplaying_p to the value it had
10664 before redisplay_internal was called, and clear
10665 prevent_freeing_realized_faces_p. It also selects the previously
10666 selected frame. */
10667
10668 static Lisp_Object
10669 unwind_redisplay (val)
10670 Lisp_Object val;
10671 {
10672 Lisp_Object old_redisplaying_p, old_frame;
10673
10674 old_redisplaying_p = XCAR (val);
10675 redisplaying_p = XFASTINT (old_redisplaying_p);
10676 old_frame = XCDR (val);
10677 if (! EQ (old_frame, selected_frame))
10678 select_frame_for_redisplay (old_frame);
10679 return Qnil;
10680 }
10681
10682
10683 /* Mark the display of window W as accurate or inaccurate. If
10684 ACCURATE_P is non-zero mark display of W as accurate. If
10685 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10686 redisplay_internal is called. */
10687
10688 static void
10689 mark_window_display_accurate_1 (w, accurate_p)
10690 struct window *w;
10691 int accurate_p;
10692 {
10693 if (BUFFERP (w->buffer))
10694 {
10695 struct buffer *b = XBUFFER (w->buffer);
10696
10697 w->last_modified
10698 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10699 w->last_overlay_modified
10700 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10701 w->last_had_star
10702 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10703
10704 if (accurate_p)
10705 {
10706 b->clip_changed = 0;
10707 b->prevent_redisplay_optimizations_p = 0;
10708
10709 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10710 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10711 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10712 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10713
10714 w->current_matrix->buffer = b;
10715 w->current_matrix->begv = BUF_BEGV (b);
10716 w->current_matrix->zv = BUF_ZV (b);
10717
10718 w->last_cursor = w->cursor;
10719 w->last_cursor_off_p = w->cursor_off_p;
10720
10721 if (w == XWINDOW (selected_window))
10722 w->last_point = make_number (BUF_PT (b));
10723 else
10724 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10725 }
10726 }
10727
10728 if (accurate_p)
10729 {
10730 w->window_end_valid = w->buffer;
10731 #if 0 /* This is incorrect with variable-height lines. */
10732 xassert (XINT (w->window_end_vpos)
10733 < (WINDOW_TOTAL_LINES (w)
10734 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10735 #endif
10736 w->update_mode_line = Qnil;
10737 }
10738 }
10739
10740
10741 /* Mark the display of windows in the window tree rooted at WINDOW as
10742 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10743 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10744 be redisplayed the next time redisplay_internal is called. */
10745
10746 void
10747 mark_window_display_accurate (window, accurate_p)
10748 Lisp_Object window;
10749 int accurate_p;
10750 {
10751 struct window *w;
10752
10753 for (; !NILP (window); window = w->next)
10754 {
10755 w = XWINDOW (window);
10756 mark_window_display_accurate_1 (w, accurate_p);
10757
10758 if (!NILP (w->vchild))
10759 mark_window_display_accurate (w->vchild, accurate_p);
10760 if (!NILP (w->hchild))
10761 mark_window_display_accurate (w->hchild, accurate_p);
10762 }
10763
10764 if (accurate_p)
10765 {
10766 update_overlay_arrows (1);
10767 }
10768 else
10769 {
10770 /* Force a thorough redisplay the next time by setting
10771 last_arrow_position and last_arrow_string to t, which is
10772 unequal to any useful value of Voverlay_arrow_... */
10773 update_overlay_arrows (-1);
10774 }
10775 }
10776
10777
10778 /* Return value in display table DP (Lisp_Char_Table *) for character
10779 C. Since a display table doesn't have any parent, we don't have to
10780 follow parent. Do not call this function directly but use the
10781 macro DISP_CHAR_VECTOR. */
10782
10783 Lisp_Object
10784 disp_char_vector (dp, c)
10785 struct Lisp_Char_Table *dp;
10786 int c;
10787 {
10788 int code[4], i;
10789 Lisp_Object val;
10790
10791 if (SINGLE_BYTE_CHAR_P (c))
10792 return (dp->contents[c]);
10793
10794 SPLIT_CHAR (c, code[0], code[1], code[2]);
10795 if (code[1] < 32)
10796 code[1] = -1;
10797 else if (code[2] < 32)
10798 code[2] = -1;
10799
10800 /* Here, the possible range of code[0] (== charset ID) is
10801 128..max_charset. Since the top level char table contains data
10802 for multibyte characters after 256th element, we must increment
10803 code[0] by 128 to get a correct index. */
10804 code[0] += 128;
10805 code[3] = -1; /* anchor */
10806
10807 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10808 {
10809 val = dp->contents[code[i]];
10810 if (!SUB_CHAR_TABLE_P (val))
10811 return (NILP (val) ? dp->defalt : val);
10812 }
10813
10814 /* Here, val is a sub char table. We return the default value of
10815 it. */
10816 return (dp->defalt);
10817 }
10818
10819
10820 \f
10821 /***********************************************************************
10822 Window Redisplay
10823 ***********************************************************************/
10824
10825 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10826
10827 static void
10828 redisplay_windows (window)
10829 Lisp_Object window;
10830 {
10831 while (!NILP (window))
10832 {
10833 struct window *w = XWINDOW (window);
10834
10835 if (!NILP (w->hchild))
10836 redisplay_windows (w->hchild);
10837 else if (!NILP (w->vchild))
10838 redisplay_windows (w->vchild);
10839 else
10840 {
10841 displayed_buffer = XBUFFER (w->buffer);
10842 /* Use list_of_error, not Qerror, so that
10843 we catch only errors and don't run the debugger. */
10844 internal_condition_case_1 (redisplay_window_0, window,
10845 list_of_error,
10846 redisplay_window_error);
10847 }
10848
10849 window = w->next;
10850 }
10851 }
10852
10853 static Lisp_Object
10854 redisplay_window_error ()
10855 {
10856 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10857 return Qnil;
10858 }
10859
10860 static Lisp_Object
10861 redisplay_window_0 (window)
10862 Lisp_Object window;
10863 {
10864 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10865 redisplay_window (window, 0);
10866 return Qnil;
10867 }
10868
10869 static Lisp_Object
10870 redisplay_window_1 (window)
10871 Lisp_Object window;
10872 {
10873 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10874 redisplay_window (window, 1);
10875 return Qnil;
10876 }
10877 \f
10878
10879 /* Increment GLYPH until it reaches END or CONDITION fails while
10880 adding (GLYPH)->pixel_width to X. */
10881
10882 #define SKIP_GLYPHS(glyph, end, x, condition) \
10883 do \
10884 { \
10885 (x) += (glyph)->pixel_width; \
10886 ++(glyph); \
10887 } \
10888 while ((glyph) < (end) && (condition))
10889
10890
10891 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10892 DELTA is the number of bytes by which positions recorded in ROW
10893 differ from current buffer positions. */
10894
10895 void
10896 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10897 struct window *w;
10898 struct glyph_row *row;
10899 struct glyph_matrix *matrix;
10900 int delta, delta_bytes, dy, dvpos;
10901 {
10902 struct glyph *glyph = row->glyphs[TEXT_AREA];
10903 struct glyph *end = glyph + row->used[TEXT_AREA];
10904 struct glyph *cursor = NULL;
10905 /* The first glyph that starts a sequence of glyphs from string. */
10906 struct glyph *string_start;
10907 /* The X coordinate of string_start. */
10908 int string_start_x;
10909 /* The last known character position. */
10910 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10911 /* The last known character position before string_start. */
10912 int string_before_pos;
10913 int x = row->x;
10914 int cursor_x = x;
10915 int cursor_from_overlay_pos = 0;
10916 int pt_old = PT - delta;
10917
10918 /* Skip over glyphs not having an object at the start of the row.
10919 These are special glyphs like truncation marks on terminal
10920 frames. */
10921 if (row->displays_text_p)
10922 while (glyph < end
10923 && INTEGERP (glyph->object)
10924 && glyph->charpos < 0)
10925 {
10926 x += glyph->pixel_width;
10927 ++glyph;
10928 }
10929
10930 string_start = NULL;
10931 while (glyph < end
10932 && !INTEGERP (glyph->object)
10933 && (!BUFFERP (glyph->object)
10934 || (last_pos = glyph->charpos) < pt_old))
10935 {
10936 if (! STRINGP (glyph->object))
10937 {
10938 string_start = NULL;
10939 x += glyph->pixel_width;
10940 ++glyph;
10941 if (cursor_from_overlay_pos
10942 && last_pos > cursor_from_overlay_pos)
10943 {
10944 cursor_from_overlay_pos = 0;
10945 cursor = 0;
10946 }
10947 }
10948 else
10949 {
10950 string_before_pos = last_pos;
10951 string_start = glyph;
10952 string_start_x = x;
10953 /* Skip all glyphs from string. */
10954 do
10955 {
10956 int pos;
10957 if ((cursor == NULL || glyph > cursor)
10958 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10959 Qcursor, (glyph)->object))
10960 && (pos = string_buffer_position (w, glyph->object,
10961 string_before_pos),
10962 (pos == 0 /* From overlay */
10963 || pos == pt_old)))
10964 {
10965 /* Estimate overlay buffer position from the buffer
10966 positions of the glyphs before and after the overlay.
10967 Add 1 to last_pos so that if point corresponds to the
10968 glyph right after the overlay, we still use a 'cursor'
10969 property found in that overlay. */
10970 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10971 cursor = glyph;
10972 cursor_x = x;
10973 }
10974 x += glyph->pixel_width;
10975 ++glyph;
10976 }
10977 while (glyph < end && STRINGP (glyph->object));
10978 }
10979 }
10980
10981 if (cursor != NULL)
10982 {
10983 glyph = cursor;
10984 x = cursor_x;
10985 }
10986 else if (row->ends_in_ellipsis_p && glyph == end)
10987 {
10988 /* Scan back over the ellipsis glyphs, decrementing positions. */
10989 while (glyph > row->glyphs[TEXT_AREA]
10990 && (glyph - 1)->charpos == last_pos)
10991 glyph--, x -= glyph->pixel_width;
10992 /* That loop always goes one position too far,
10993 including the glyph before the ellipsis.
10994 So scan forward over that one. */
10995 x += glyph->pixel_width;
10996 glyph++;
10997 }
10998 else if (string_start
10999 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11000 {
11001 /* We may have skipped over point because the previous glyphs
11002 are from string. As there's no easy way to know the
11003 character position of the current glyph, find the correct
11004 glyph on point by scanning from string_start again. */
11005 Lisp_Object limit;
11006 Lisp_Object string;
11007 int pos;
11008
11009 limit = make_number (pt_old + 1);
11010 end = glyph;
11011 glyph = string_start;
11012 x = string_start_x;
11013 string = glyph->object;
11014 pos = string_buffer_position (w, string, string_before_pos);
11015 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11016 because we always put cursor after overlay strings. */
11017 while (pos == 0 && glyph < end)
11018 {
11019 string = glyph->object;
11020 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11021 if (glyph < end)
11022 pos = string_buffer_position (w, glyph->object, string_before_pos);
11023 }
11024
11025 while (glyph < end)
11026 {
11027 pos = XINT (Fnext_single_char_property_change
11028 (make_number (pos), Qdisplay, Qnil, limit));
11029 if (pos > pt_old)
11030 break;
11031 /* Skip glyphs from the same string. */
11032 string = glyph->object;
11033 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11034 /* Skip glyphs from an overlay. */
11035 while (glyph < end
11036 && ! string_buffer_position (w, glyph->object, pos))
11037 {
11038 string = glyph->object;
11039 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11040 }
11041 }
11042 }
11043
11044 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
11045 w->cursor.x = x;
11046 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
11047 w->cursor.y = row->y + dy;
11048
11049 if (w == XWINDOW (selected_window))
11050 {
11051 if (!row->continued_p
11052 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
11053 && row->x == 0)
11054 {
11055 this_line_buffer = XBUFFER (w->buffer);
11056
11057 CHARPOS (this_line_start_pos)
11058 = MATRIX_ROW_START_CHARPOS (row) + delta;
11059 BYTEPOS (this_line_start_pos)
11060 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
11061
11062 CHARPOS (this_line_end_pos)
11063 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
11064 BYTEPOS (this_line_end_pos)
11065 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
11066
11067 this_line_y = w->cursor.y;
11068 this_line_pixel_height = row->height;
11069 this_line_vpos = w->cursor.vpos;
11070 this_line_start_x = row->x;
11071 }
11072 else
11073 CHARPOS (this_line_start_pos) = 0;
11074 }
11075 }
11076
11077
11078 /* Run window scroll functions, if any, for WINDOW with new window
11079 start STARTP. Sets the window start of WINDOW to that position.
11080
11081 We assume that the window's buffer is really current. */
11082
11083 static INLINE struct text_pos
11084 run_window_scroll_functions (window, startp)
11085 Lisp_Object window;
11086 struct text_pos startp;
11087 {
11088 struct window *w = XWINDOW (window);
11089 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11090
11091 if (current_buffer != XBUFFER (w->buffer))
11092 abort ();
11093
11094 if (!NILP (Vwindow_scroll_functions))
11095 {
11096 run_hook_with_args_2 (Qwindow_scroll_functions, window,
11097 make_number (CHARPOS (startp)));
11098 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11099 /* In case the hook functions switch buffers. */
11100 if (current_buffer != XBUFFER (w->buffer))
11101 set_buffer_internal_1 (XBUFFER (w->buffer));
11102 }
11103
11104 return startp;
11105 }
11106
11107
11108 /* Make sure the line containing the cursor is fully visible.
11109 A value of 1 means there is nothing to be done.
11110 (Either the line is fully visible, or it cannot be made so,
11111 or we cannot tell.)
11112
11113 If FORCE_P is non-zero, return 0 even if partial visible cursor row
11114 is higher than window.
11115
11116 A value of 0 means the caller should do scrolling
11117 as if point had gone off the screen. */
11118
11119 static int
11120 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11121 struct window *w;
11122 int force_p;
11123 {
11124 struct glyph_matrix *matrix;
11125 struct glyph_row *row;
11126 int window_height;
11127
11128 if (!make_cursor_line_fully_visible_p)
11129 return 1;
11130
11131 /* It's not always possible to find the cursor, e.g, when a window
11132 is full of overlay strings. Don't do anything in that case. */
11133 if (w->cursor.vpos < 0)
11134 return 1;
11135
11136 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11137 row = MATRIX_ROW (matrix, w->cursor.vpos);
11138
11139 /* If the cursor row is not partially visible, there's nothing to do. */
11140 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
11141 return 1;
11142
11143 /* If the row the cursor is in is taller than the window's height,
11144 it's not clear what to do, so do nothing. */
11145 window_height = window_box_height (w);
11146 if (row->height >= window_height)
11147 {
11148 if (!force_p || w->vscroll)
11149 return 1;
11150 }
11151 return 0;
11152
11153 #if 0
11154 /* This code used to try to scroll the window just enough to make
11155 the line visible. It returned 0 to say that the caller should
11156 allocate larger glyph matrices. */
11157
11158 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11159 {
11160 int dy = row->height - row->visible_height;
11161 w->vscroll = 0;
11162 w->cursor.y += dy;
11163 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11164 }
11165 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11166 {
11167 int dy = - (row->height - row->visible_height);
11168 w->vscroll = dy;
11169 w->cursor.y += dy;
11170 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11171 }
11172
11173 /* When we change the cursor y-position of the selected window,
11174 change this_line_y as well so that the display optimization for
11175 the cursor line of the selected window in redisplay_internal uses
11176 the correct y-position. */
11177 if (w == XWINDOW (selected_window))
11178 this_line_y = w->cursor.y;
11179
11180 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11181 redisplay with larger matrices. */
11182 if (matrix->nrows < required_matrix_height (w))
11183 {
11184 fonts_changed_p = 1;
11185 return 0;
11186 }
11187
11188 return 1;
11189 #endif /* 0 */
11190 }
11191
11192
11193 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11194 non-zero means only WINDOW is redisplayed in redisplay_internal.
11195 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11196 in redisplay_window to bring a partially visible line into view in
11197 the case that only the cursor has moved.
11198
11199 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11200 last screen line's vertical height extends past the end of the screen.
11201
11202 Value is
11203
11204 1 if scrolling succeeded
11205
11206 0 if scrolling didn't find point.
11207
11208 -1 if new fonts have been loaded so that we must interrupt
11209 redisplay, adjust glyph matrices, and try again. */
11210
11211 enum
11212 {
11213 SCROLLING_SUCCESS,
11214 SCROLLING_FAILED,
11215 SCROLLING_NEED_LARGER_MATRICES
11216 };
11217
11218 static int
11219 try_scrolling (window, just_this_one_p, scroll_conservatively,
11220 scroll_step, temp_scroll_step, last_line_misfit)
11221 Lisp_Object window;
11222 int just_this_one_p;
11223 EMACS_INT scroll_conservatively, scroll_step;
11224 int temp_scroll_step;
11225 int last_line_misfit;
11226 {
11227 struct window *w = XWINDOW (window);
11228 struct frame *f = XFRAME (w->frame);
11229 struct text_pos scroll_margin_pos;
11230 struct text_pos pos;
11231 struct text_pos startp;
11232 struct it it;
11233 Lisp_Object window_end;
11234 int this_scroll_margin;
11235 int dy = 0;
11236 int scroll_max;
11237 int rc;
11238 int amount_to_scroll = 0;
11239 Lisp_Object aggressive;
11240 int height;
11241 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11242
11243 #if GLYPH_DEBUG
11244 debug_method_add (w, "try_scrolling");
11245 #endif
11246
11247 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11248
11249 /* Compute scroll margin height in pixels. We scroll when point is
11250 within this distance from the top or bottom of the window. */
11251 if (scroll_margin > 0)
11252 {
11253 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11254 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11255 }
11256 else
11257 this_scroll_margin = 0;
11258
11259 /* Force scroll_conservatively to have a reasonable value so it doesn't
11260 cause an overflow while computing how much to scroll. */
11261 if (scroll_conservatively)
11262 scroll_conservatively = min (scroll_conservatively,
11263 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11264
11265 /* Compute how much we should try to scroll maximally to bring point
11266 into view. */
11267 if (scroll_step || scroll_conservatively || temp_scroll_step)
11268 scroll_max = max (scroll_step,
11269 max (scroll_conservatively, temp_scroll_step));
11270 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11271 || NUMBERP (current_buffer->scroll_up_aggressively))
11272 /* We're trying to scroll because of aggressive scrolling
11273 but no scroll_step is set. Choose an arbitrary one. Maybe
11274 there should be a variable for this. */
11275 scroll_max = 10;
11276 else
11277 scroll_max = 0;
11278 scroll_max *= FRAME_LINE_HEIGHT (f);
11279
11280 /* Decide whether we have to scroll down. Start at the window end
11281 and move this_scroll_margin up to find the position of the scroll
11282 margin. */
11283 window_end = Fwindow_end (window, Qt);
11284
11285 too_near_end:
11286
11287 CHARPOS (scroll_margin_pos) = XINT (window_end);
11288 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11289
11290 if (this_scroll_margin || extra_scroll_margin_lines)
11291 {
11292 start_display (&it, w, scroll_margin_pos);
11293 if (this_scroll_margin)
11294 move_it_vertically_backward (&it, this_scroll_margin);
11295 if (extra_scroll_margin_lines)
11296 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11297 scroll_margin_pos = it.current.pos;
11298 }
11299
11300 if (PT >= CHARPOS (scroll_margin_pos))
11301 {
11302 int y0;
11303
11304 /* Point is in the scroll margin at the bottom of the window, or
11305 below. Compute a new window start that makes point visible. */
11306
11307 /* Compute the distance from the scroll margin to PT.
11308 Give up if the distance is greater than scroll_max. */
11309 start_display (&it, w, scroll_margin_pos);
11310 y0 = it.current_y;
11311 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11312 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11313
11314 /* To make point visible, we have to move the window start
11315 down so that the line the cursor is in is visible, which
11316 means we have to add in the height of the cursor line. */
11317 dy = line_bottom_y (&it) - y0;
11318
11319 if (dy > scroll_max)
11320 return SCROLLING_FAILED;
11321
11322 /* Move the window start down. If scrolling conservatively,
11323 move it just enough down to make point visible. If
11324 scroll_step is set, move it down by scroll_step. */
11325 start_display (&it, w, startp);
11326
11327 if (scroll_conservatively)
11328 /* Set AMOUNT_TO_SCROLL to at least one line,
11329 and at most scroll_conservatively lines. */
11330 amount_to_scroll
11331 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11332 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11333 else if (scroll_step || temp_scroll_step)
11334 amount_to_scroll = scroll_max;
11335 else
11336 {
11337 aggressive = current_buffer->scroll_up_aggressively;
11338 height = WINDOW_BOX_TEXT_HEIGHT (w);
11339 if (NUMBERP (aggressive))
11340 {
11341 double float_amount = XFLOATINT (aggressive) * height;
11342 amount_to_scroll = float_amount;
11343 if (amount_to_scroll == 0 && float_amount > 0)
11344 amount_to_scroll = 1;
11345 }
11346 }
11347
11348 if (amount_to_scroll <= 0)
11349 return SCROLLING_FAILED;
11350
11351 /* If moving by amount_to_scroll leaves STARTP unchanged,
11352 move it down one screen line. */
11353
11354 move_it_vertically (&it, amount_to_scroll);
11355 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11356 move_it_by_lines (&it, 1, 1);
11357 startp = it.current.pos;
11358 }
11359 else
11360 {
11361 /* See if point is inside the scroll margin at the top of the
11362 window. */
11363 scroll_margin_pos = startp;
11364 if (this_scroll_margin)
11365 {
11366 start_display (&it, w, startp);
11367 move_it_vertically (&it, this_scroll_margin);
11368 scroll_margin_pos = it.current.pos;
11369 }
11370
11371 if (PT < CHARPOS (scroll_margin_pos))
11372 {
11373 /* Point is in the scroll margin at the top of the window or
11374 above what is displayed in the window. */
11375 int y0;
11376
11377 /* Compute the vertical distance from PT to the scroll
11378 margin position. Give up if distance is greater than
11379 scroll_max. */
11380 SET_TEXT_POS (pos, PT, PT_BYTE);
11381 start_display (&it, w, pos);
11382 y0 = it.current_y;
11383 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11384 it.last_visible_y, -1,
11385 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11386 dy = it.current_y - y0;
11387 if (dy > scroll_max)
11388 return SCROLLING_FAILED;
11389
11390 /* Compute new window start. */
11391 start_display (&it, w, startp);
11392
11393 if (scroll_conservatively)
11394 amount_to_scroll
11395 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11396 else if (scroll_step || temp_scroll_step)
11397 amount_to_scroll = scroll_max;
11398 else
11399 {
11400 aggressive = current_buffer->scroll_down_aggressively;
11401 height = WINDOW_BOX_TEXT_HEIGHT (w);
11402 if (NUMBERP (aggressive))
11403 {
11404 double float_amount = XFLOATINT (aggressive) * height;
11405 amount_to_scroll = float_amount;
11406 if (amount_to_scroll == 0 && float_amount > 0)
11407 amount_to_scroll = 1;
11408 }
11409 }
11410
11411 if (amount_to_scroll <= 0)
11412 return SCROLLING_FAILED;
11413
11414 move_it_vertically_backward (&it, amount_to_scroll);
11415 startp = it.current.pos;
11416 }
11417 }
11418
11419 /* Run window scroll functions. */
11420 startp = run_window_scroll_functions (window, startp);
11421
11422 /* Display the window. Give up if new fonts are loaded, or if point
11423 doesn't appear. */
11424 if (!try_window (window, startp))
11425 rc = SCROLLING_NEED_LARGER_MATRICES;
11426 else if (w->cursor.vpos < 0)
11427 {
11428 clear_glyph_matrix (w->desired_matrix);
11429 rc = SCROLLING_FAILED;
11430 }
11431 else
11432 {
11433 /* Maybe forget recorded base line for line number display. */
11434 if (!just_this_one_p
11435 || current_buffer->clip_changed
11436 || BEG_UNCHANGED < CHARPOS (startp))
11437 w->base_line_number = Qnil;
11438
11439 /* If cursor ends up on a partially visible line,
11440 treat that as being off the bottom of the screen. */
11441 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
11442 {
11443 clear_glyph_matrix (w->desired_matrix);
11444 ++extra_scroll_margin_lines;
11445 goto too_near_end;
11446 }
11447 rc = SCROLLING_SUCCESS;
11448 }
11449
11450 return rc;
11451 }
11452
11453
11454 /* Compute a suitable window start for window W if display of W starts
11455 on a continuation line. Value is non-zero if a new window start
11456 was computed.
11457
11458 The new window start will be computed, based on W's width, starting
11459 from the start of the continued line. It is the start of the
11460 screen line with the minimum distance from the old start W->start. */
11461
11462 static int
11463 compute_window_start_on_continuation_line (w)
11464 struct window *w;
11465 {
11466 struct text_pos pos, start_pos;
11467 int window_start_changed_p = 0;
11468
11469 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11470
11471 /* If window start is on a continuation line... Window start may be
11472 < BEGV in case there's invisible text at the start of the
11473 buffer (M-x rmail, for example). */
11474 if (CHARPOS (start_pos) > BEGV
11475 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11476 {
11477 struct it it;
11478 struct glyph_row *row;
11479
11480 /* Handle the case that the window start is out of range. */
11481 if (CHARPOS (start_pos) < BEGV)
11482 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11483 else if (CHARPOS (start_pos) > ZV)
11484 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11485
11486 /* Find the start of the continued line. This should be fast
11487 because scan_buffer is fast (newline cache). */
11488 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11489 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11490 row, DEFAULT_FACE_ID);
11491 reseat_at_previous_visible_line_start (&it);
11492
11493 /* If the line start is "too far" away from the window start,
11494 say it takes too much time to compute a new window start. */
11495 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11496 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11497 {
11498 int min_distance, distance;
11499
11500 /* Move forward by display lines to find the new window
11501 start. If window width was enlarged, the new start can
11502 be expected to be > the old start. If window width was
11503 decreased, the new window start will be < the old start.
11504 So, we're looking for the display line start with the
11505 minimum distance from the old window start. */
11506 pos = it.current.pos;
11507 min_distance = INFINITY;
11508 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11509 distance < min_distance)
11510 {
11511 min_distance = distance;
11512 pos = it.current.pos;
11513 move_it_by_lines (&it, 1, 0);
11514 }
11515
11516 /* Set the window start there. */
11517 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11518 window_start_changed_p = 1;
11519 }
11520 }
11521
11522 return window_start_changed_p;
11523 }
11524
11525
11526 /* Try cursor movement in case text has not changed in window WINDOW,
11527 with window start STARTP. Value is
11528
11529 CURSOR_MOVEMENT_SUCCESS if successful
11530
11531 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11532
11533 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11534 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11535 we want to scroll as if scroll-step were set to 1. See the code.
11536
11537 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11538 which case we have to abort this redisplay, and adjust matrices
11539 first. */
11540
11541 enum
11542 {
11543 CURSOR_MOVEMENT_SUCCESS,
11544 CURSOR_MOVEMENT_CANNOT_BE_USED,
11545 CURSOR_MOVEMENT_MUST_SCROLL,
11546 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11547 };
11548
11549 static int
11550 try_cursor_movement (window, startp, scroll_step)
11551 Lisp_Object window;
11552 struct text_pos startp;
11553 int *scroll_step;
11554 {
11555 struct window *w = XWINDOW (window);
11556 struct frame *f = XFRAME (w->frame);
11557 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11558
11559 #if GLYPH_DEBUG
11560 if (inhibit_try_cursor_movement)
11561 return rc;
11562 #endif
11563
11564 /* Handle case where text has not changed, only point, and it has
11565 not moved off the frame. */
11566 if (/* Point may be in this window. */
11567 PT >= CHARPOS (startp)
11568 /* Selective display hasn't changed. */
11569 && !current_buffer->clip_changed
11570 /* Function force-mode-line-update is used to force a thorough
11571 redisplay. It sets either windows_or_buffers_changed or
11572 update_mode_lines. So don't take a shortcut here for these
11573 cases. */
11574 && !update_mode_lines
11575 && !windows_or_buffers_changed
11576 && !cursor_type_changed
11577 /* Can't use this case if highlighting a region. When a
11578 region exists, cursor movement has to do more than just
11579 set the cursor. */
11580 && !(!NILP (Vtransient_mark_mode)
11581 && !NILP (current_buffer->mark_active))
11582 && NILP (w->region_showing)
11583 && NILP (Vshow_trailing_whitespace)
11584 /* Right after splitting windows, last_point may be nil. */
11585 && INTEGERP (w->last_point)
11586 /* This code is not used for mini-buffer for the sake of the case
11587 of redisplaying to replace an echo area message; since in
11588 that case the mini-buffer contents per se are usually
11589 unchanged. This code is of no real use in the mini-buffer
11590 since the handling of this_line_start_pos, etc., in redisplay
11591 handles the same cases. */
11592 && !EQ (window, minibuf_window)
11593 /* When splitting windows or for new windows, it happens that
11594 redisplay is called with a nil window_end_vpos or one being
11595 larger than the window. This should really be fixed in
11596 window.c. I don't have this on my list, now, so we do
11597 approximately the same as the old redisplay code. --gerd. */
11598 && INTEGERP (w->window_end_vpos)
11599 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11600 && (FRAME_WINDOW_P (f)
11601 || !overlay_arrow_in_current_buffer_p ()))
11602 {
11603 int this_scroll_margin, top_scroll_margin;
11604 struct glyph_row *row = NULL;
11605
11606 #if GLYPH_DEBUG
11607 debug_method_add (w, "cursor movement");
11608 #endif
11609
11610 /* Scroll if point within this distance from the top or bottom
11611 of the window. This is a pixel value. */
11612 this_scroll_margin = max (0, scroll_margin);
11613 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11614 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11615
11616 top_scroll_margin = this_scroll_margin;
11617 if (WINDOW_WANTS_HEADER_LINE_P (w))
11618 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11619
11620 /* Start with the row the cursor was displayed during the last
11621 not paused redisplay. Give up if that row is not valid. */
11622 if (w->last_cursor.vpos < 0
11623 || w->last_cursor.vpos >= w->current_matrix->nrows)
11624 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11625 else
11626 {
11627 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11628 if (row->mode_line_p)
11629 ++row;
11630 if (!row->enabled_p)
11631 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11632 }
11633
11634 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11635 {
11636 int scroll_p = 0;
11637 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11638
11639 if (PT > XFASTINT (w->last_point))
11640 {
11641 /* Point has moved forward. */
11642 while (MATRIX_ROW_END_CHARPOS (row) < PT
11643 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11644 {
11645 xassert (row->enabled_p);
11646 ++row;
11647 }
11648
11649 /* The end position of a row equals the start position
11650 of the next row. If PT is there, we would rather
11651 display it in the next line. */
11652 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11653 && MATRIX_ROW_END_CHARPOS (row) == PT
11654 && !cursor_row_p (w, row))
11655 ++row;
11656
11657 /* If within the scroll margin, scroll. Note that
11658 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11659 the next line would be drawn, and that
11660 this_scroll_margin can be zero. */
11661 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11662 || PT > MATRIX_ROW_END_CHARPOS (row)
11663 /* Line is completely visible last line in window
11664 and PT is to be set in the next line. */
11665 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11666 && PT == MATRIX_ROW_END_CHARPOS (row)
11667 && !row->ends_at_zv_p
11668 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11669 scroll_p = 1;
11670 }
11671 else if (PT < XFASTINT (w->last_point))
11672 {
11673 /* Cursor has to be moved backward. Note that PT >=
11674 CHARPOS (startp) because of the outer if-statement. */
11675 while (!row->mode_line_p
11676 && (MATRIX_ROW_START_CHARPOS (row) > PT
11677 || (MATRIX_ROW_START_CHARPOS (row) == PT
11678 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11679 && (row->y > top_scroll_margin
11680 || CHARPOS (startp) == BEGV))
11681 {
11682 xassert (row->enabled_p);
11683 --row;
11684 }
11685
11686 /* Consider the following case: Window starts at BEGV,
11687 there is invisible, intangible text at BEGV, so that
11688 display starts at some point START > BEGV. It can
11689 happen that we are called with PT somewhere between
11690 BEGV and START. Try to handle that case. */
11691 if (row < w->current_matrix->rows
11692 || row->mode_line_p)
11693 {
11694 row = w->current_matrix->rows;
11695 if (row->mode_line_p)
11696 ++row;
11697 }
11698
11699 /* Due to newlines in overlay strings, we may have to
11700 skip forward over overlay strings. */
11701 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11702 && MATRIX_ROW_END_CHARPOS (row) == PT
11703 && !cursor_row_p (w, row))
11704 ++row;
11705
11706 /* If within the scroll margin, scroll. */
11707 if (row->y < top_scroll_margin
11708 && CHARPOS (startp) != BEGV)
11709 scroll_p = 1;
11710 }
11711 else
11712 {
11713 /* Cursor did not move. So don't scroll even if cursor line
11714 is partially visible, as it was so before. */
11715 rc = CURSOR_MOVEMENT_SUCCESS;
11716 }
11717
11718 if (PT < MATRIX_ROW_START_CHARPOS (row)
11719 || PT > MATRIX_ROW_END_CHARPOS (row))
11720 {
11721 /* if PT is not in the glyph row, give up. */
11722 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11723 }
11724 else if (rc != CURSOR_MOVEMENT_SUCCESS
11725 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11726 && make_cursor_line_fully_visible_p)
11727 {
11728 if (PT == MATRIX_ROW_END_CHARPOS (row)
11729 && !row->ends_at_zv_p
11730 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11731 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11732 else if (row->height > window_box_height (w))
11733 {
11734 /* If we end up in a partially visible line, let's
11735 make it fully visible, except when it's taller
11736 than the window, in which case we can't do much
11737 about it. */
11738 *scroll_step = 1;
11739 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11740 }
11741 else
11742 {
11743 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11744 if (!cursor_row_fully_visible_p (w, 0, 1))
11745 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11746 else
11747 rc = CURSOR_MOVEMENT_SUCCESS;
11748 }
11749 }
11750 else if (scroll_p)
11751 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11752 else
11753 {
11754 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11755 rc = CURSOR_MOVEMENT_SUCCESS;
11756 }
11757 }
11758 }
11759
11760 return rc;
11761 }
11762
11763 void
11764 set_vertical_scroll_bar (w)
11765 struct window *w;
11766 {
11767 int start, end, whole;
11768
11769 /* Calculate the start and end positions for the current window.
11770 At some point, it would be nice to choose between scrollbars
11771 which reflect the whole buffer size, with special markers
11772 indicating narrowing, and scrollbars which reflect only the
11773 visible region.
11774
11775 Note that mini-buffers sometimes aren't displaying any text. */
11776 if (!MINI_WINDOW_P (w)
11777 || (w == XWINDOW (minibuf_window)
11778 && NILP (echo_area_buffer[0])))
11779 {
11780 struct buffer *buf = XBUFFER (w->buffer);
11781 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11782 start = marker_position (w->start) - BUF_BEGV (buf);
11783 /* I don't think this is guaranteed to be right. For the
11784 moment, we'll pretend it is. */
11785 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11786
11787 if (end < start)
11788 end = start;
11789 if (whole < (end - start))
11790 whole = end - start;
11791 }
11792 else
11793 start = end = whole = 0;
11794
11795 /* Indicate what this scroll bar ought to be displaying now. */
11796 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11797 }
11798
11799
11800 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11801 selected_window is redisplayed.
11802
11803 We can return without actually redisplaying the window if
11804 fonts_changed_p is nonzero. In that case, redisplay_internal will
11805 retry. */
11806
11807 static void
11808 redisplay_window (window, just_this_one_p)
11809 Lisp_Object window;
11810 int just_this_one_p;
11811 {
11812 struct window *w = XWINDOW (window);
11813 struct frame *f = XFRAME (w->frame);
11814 struct buffer *buffer = XBUFFER (w->buffer);
11815 struct buffer *old = current_buffer;
11816 struct text_pos lpoint, opoint, startp;
11817 int update_mode_line;
11818 int tem;
11819 struct it it;
11820 /* Record it now because it's overwritten. */
11821 int current_matrix_up_to_date_p = 0;
11822 int used_current_matrix_p = 0;
11823 /* This is less strict than current_matrix_up_to_date_p.
11824 It indictes that the buffer contents and narrowing are unchanged. */
11825 int buffer_unchanged_p = 0;
11826 int temp_scroll_step = 0;
11827 int count = SPECPDL_INDEX ();
11828 int rc;
11829 int centering_position = -1;
11830 int last_line_misfit = 0;
11831
11832 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11833 opoint = lpoint;
11834
11835 /* W must be a leaf window here. */
11836 xassert (!NILP (w->buffer));
11837 #if GLYPH_DEBUG
11838 *w->desired_matrix->method = 0;
11839 #endif
11840
11841 specbind (Qinhibit_point_motion_hooks, Qt);
11842
11843 reconsider_clip_changes (w, buffer);
11844
11845 /* Has the mode line to be updated? */
11846 update_mode_line = (!NILP (w->update_mode_line)
11847 || update_mode_lines
11848 || buffer->clip_changed
11849 || buffer->prevent_redisplay_optimizations_p);
11850
11851 if (MINI_WINDOW_P (w))
11852 {
11853 if (w == XWINDOW (echo_area_window)
11854 && !NILP (echo_area_buffer[0]))
11855 {
11856 if (update_mode_line)
11857 /* We may have to update a tty frame's menu bar or a
11858 tool-bar. Example `M-x C-h C-h C-g'. */
11859 goto finish_menu_bars;
11860 else
11861 /* We've already displayed the echo area glyphs in this window. */
11862 goto finish_scroll_bars;
11863 }
11864 else if ((w != XWINDOW (minibuf_window)
11865 || minibuf_level == 0)
11866 /* When buffer is nonempty, redisplay window normally. */
11867 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11868 /* Quail displays non-mini buffers in minibuffer window.
11869 In that case, redisplay the window normally. */
11870 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11871 {
11872 /* W is a mini-buffer window, but it's not active, so clear
11873 it. */
11874 int yb = window_text_bottom_y (w);
11875 struct glyph_row *row;
11876 int y;
11877
11878 for (y = 0, row = w->desired_matrix->rows;
11879 y < yb;
11880 y += row->height, ++row)
11881 blank_row (w, row, y);
11882 goto finish_scroll_bars;
11883 }
11884
11885 clear_glyph_matrix (w->desired_matrix);
11886 }
11887
11888 /* Otherwise set up data on this window; select its buffer and point
11889 value. */
11890 /* Really select the buffer, for the sake of buffer-local
11891 variables. */
11892 set_buffer_internal_1 (XBUFFER (w->buffer));
11893 SET_TEXT_POS (opoint, PT, PT_BYTE);
11894
11895 current_matrix_up_to_date_p
11896 = (!NILP (w->window_end_valid)
11897 && !current_buffer->clip_changed
11898 && !current_buffer->prevent_redisplay_optimizations_p
11899 && XFASTINT (w->last_modified) >= MODIFF
11900 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11901
11902 buffer_unchanged_p
11903 = (!NILP (w->window_end_valid)
11904 && !current_buffer->clip_changed
11905 && XFASTINT (w->last_modified) >= MODIFF
11906 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11907
11908 /* When windows_or_buffers_changed is non-zero, we can't rely on
11909 the window end being valid, so set it to nil there. */
11910 if (windows_or_buffers_changed)
11911 {
11912 /* If window starts on a continuation line, maybe adjust the
11913 window start in case the window's width changed. */
11914 if (XMARKER (w->start)->buffer == current_buffer)
11915 compute_window_start_on_continuation_line (w);
11916
11917 w->window_end_valid = Qnil;
11918 }
11919
11920 /* Some sanity checks. */
11921 CHECK_WINDOW_END (w);
11922 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11923 abort ();
11924 if (BYTEPOS (opoint) < CHARPOS (opoint))
11925 abort ();
11926
11927 /* If %c is in mode line, update it if needed. */
11928 if (!NILP (w->column_number_displayed)
11929 /* This alternative quickly identifies a common case
11930 where no change is needed. */
11931 && !(PT == XFASTINT (w->last_point)
11932 && XFASTINT (w->last_modified) >= MODIFF
11933 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11934 && (XFASTINT (w->column_number_displayed)
11935 != (int) current_column ())) /* iftc */
11936 update_mode_line = 1;
11937
11938 /* Count number of windows showing the selected buffer. An indirect
11939 buffer counts as its base buffer. */
11940 if (!just_this_one_p)
11941 {
11942 struct buffer *current_base, *window_base;
11943 current_base = current_buffer;
11944 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11945 if (current_base->base_buffer)
11946 current_base = current_base->base_buffer;
11947 if (window_base->base_buffer)
11948 window_base = window_base->base_buffer;
11949 if (current_base == window_base)
11950 buffer_shared++;
11951 }
11952
11953 /* Point refers normally to the selected window. For any other
11954 window, set up appropriate value. */
11955 if (!EQ (window, selected_window))
11956 {
11957 int new_pt = XMARKER (w->pointm)->charpos;
11958 int new_pt_byte = marker_byte_position (w->pointm);
11959 if (new_pt < BEGV)
11960 {
11961 new_pt = BEGV;
11962 new_pt_byte = BEGV_BYTE;
11963 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11964 }
11965 else if (new_pt > (ZV - 1))
11966 {
11967 new_pt = ZV;
11968 new_pt_byte = ZV_BYTE;
11969 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11970 }
11971
11972 /* We don't use SET_PT so that the point-motion hooks don't run. */
11973 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11974 }
11975
11976 /* If any of the character widths specified in the display table
11977 have changed, invalidate the width run cache. It's true that
11978 this may be a bit late to catch such changes, but the rest of
11979 redisplay goes (non-fatally) haywire when the display table is
11980 changed, so why should we worry about doing any better? */
11981 if (current_buffer->width_run_cache)
11982 {
11983 struct Lisp_Char_Table *disptab = buffer_display_table ();
11984
11985 if (! disptab_matches_widthtab (disptab,
11986 XVECTOR (current_buffer->width_table)))
11987 {
11988 invalidate_region_cache (current_buffer,
11989 current_buffer->width_run_cache,
11990 BEG, Z);
11991 recompute_width_table (current_buffer, disptab);
11992 }
11993 }
11994
11995 /* If window-start is screwed up, choose a new one. */
11996 if (XMARKER (w->start)->buffer != current_buffer)
11997 goto recenter;
11998
11999 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12000
12001 /* If someone specified a new starting point but did not insist,
12002 check whether it can be used. */
12003 if (!NILP (w->optional_new_start)
12004 && CHARPOS (startp) >= BEGV
12005 && CHARPOS (startp) <= ZV)
12006 {
12007 w->optional_new_start = Qnil;
12008 start_display (&it, w, startp);
12009 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12010 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12011 if (IT_CHARPOS (it) == PT)
12012 w->force_start = Qt;
12013 /* IT may overshoot PT if text at PT is invisible. */
12014 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12015 w->force_start = Qt;
12016
12017
12018 }
12019
12020 /* Handle case where place to start displaying has been specified,
12021 unless the specified location is outside the accessible range. */
12022 if (!NILP (w->force_start)
12023 || w->frozen_window_start_p)
12024 {
12025 /* We set this later on if we have to adjust point. */
12026 int new_vpos = -1;
12027
12028 w->force_start = Qnil;
12029 w->vscroll = 0;
12030 w->window_end_valid = Qnil;
12031
12032 /* Forget any recorded base line for line number display. */
12033 if (!buffer_unchanged_p)
12034 w->base_line_number = Qnil;
12035
12036 /* Redisplay the mode line. Select the buffer properly for that.
12037 Also, run the hook window-scroll-functions
12038 because we have scrolled. */
12039 /* Note, we do this after clearing force_start because
12040 if there's an error, it is better to forget about force_start
12041 than to get into an infinite loop calling the hook functions
12042 and having them get more errors. */
12043 if (!update_mode_line
12044 || ! NILP (Vwindow_scroll_functions))
12045 {
12046 update_mode_line = 1;
12047 w->update_mode_line = Qt;
12048 startp = run_window_scroll_functions (window, startp);
12049 }
12050
12051 w->last_modified = make_number (0);
12052 w->last_overlay_modified = make_number (0);
12053 if (CHARPOS (startp) < BEGV)
12054 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12055 else if (CHARPOS (startp) > ZV)
12056 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12057
12058 /* Redisplay, then check if cursor has been set during the
12059 redisplay. Give up if new fonts were loaded. */
12060 if (!try_window (window, startp))
12061 {
12062 w->force_start = Qt;
12063 clear_glyph_matrix (w->desired_matrix);
12064 goto need_larger_matrices;
12065 }
12066
12067 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12068 {
12069 /* If point does not appear, try to move point so it does
12070 appear. The desired matrix has been built above, so we
12071 can use it here. */
12072 new_vpos = window_box_height (w) / 2;
12073 }
12074
12075 if (!cursor_row_fully_visible_p (w, 0, 0))
12076 {
12077 /* Point does appear, but on a line partly visible at end of window.
12078 Move it back to a fully-visible line. */
12079 new_vpos = window_box_height (w);
12080 }
12081
12082 /* If we need to move point for either of the above reasons,
12083 now actually do it. */
12084 if (new_vpos >= 0)
12085 {
12086 struct glyph_row *row;
12087
12088 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
12089 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
12090 ++row;
12091
12092 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
12093 MATRIX_ROW_START_BYTEPOS (row));
12094
12095 if (w != XWINDOW (selected_window))
12096 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
12097 else if (current_buffer == old)
12098 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12099
12100 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
12101
12102 /* If we are highlighting the region, then we just changed
12103 the region, so redisplay to show it. */
12104 if (!NILP (Vtransient_mark_mode)
12105 && !NILP (current_buffer->mark_active))
12106 {
12107 clear_glyph_matrix (w->desired_matrix);
12108 if (!try_window (window, startp))
12109 goto need_larger_matrices;
12110 }
12111 }
12112
12113 #if GLYPH_DEBUG
12114 debug_method_add (w, "forced window start");
12115 #endif
12116 goto done;
12117 }
12118
12119 /* Handle case where text has not changed, only point, and it has
12120 not moved off the frame, and we are not retrying after hscroll.
12121 (current_matrix_up_to_date_p is nonzero when retrying.) */
12122 if (current_matrix_up_to_date_p
12123 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
12124 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
12125 {
12126 switch (rc)
12127 {
12128 case CURSOR_MOVEMENT_SUCCESS:
12129 used_current_matrix_p = 1;
12130 goto done;
12131
12132 #if 0 /* try_cursor_movement never returns this value. */
12133 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
12134 goto need_larger_matrices;
12135 #endif
12136
12137 case CURSOR_MOVEMENT_MUST_SCROLL:
12138 goto try_to_scroll;
12139
12140 default:
12141 abort ();
12142 }
12143 }
12144 /* If current starting point was originally the beginning of a line
12145 but no longer is, find a new starting point. */
12146 else if (!NILP (w->start_at_line_beg)
12147 && !(CHARPOS (startp) <= BEGV
12148 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
12149 {
12150 #if GLYPH_DEBUG
12151 debug_method_add (w, "recenter 1");
12152 #endif
12153 goto recenter;
12154 }
12155
12156 /* Try scrolling with try_window_id. Value is > 0 if update has
12157 been done, it is -1 if we know that the same window start will
12158 not work. It is 0 if unsuccessful for some other reason. */
12159 else if ((tem = try_window_id (w)) != 0)
12160 {
12161 #if GLYPH_DEBUG
12162 debug_method_add (w, "try_window_id %d", tem);
12163 #endif
12164
12165 if (fonts_changed_p)
12166 goto need_larger_matrices;
12167 if (tem > 0)
12168 goto done;
12169
12170 /* Otherwise try_window_id has returned -1 which means that we
12171 don't want the alternative below this comment to execute. */
12172 }
12173 else if (CHARPOS (startp) >= BEGV
12174 && CHARPOS (startp) <= ZV
12175 && PT >= CHARPOS (startp)
12176 && (CHARPOS (startp) < ZV
12177 /* Avoid starting at end of buffer. */
12178 || CHARPOS (startp) == BEGV
12179 || (XFASTINT (w->last_modified) >= MODIFF
12180 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12181 {
12182 #if GLYPH_DEBUG
12183 debug_method_add (w, "same window start");
12184 #endif
12185
12186 /* Try to redisplay starting at same place as before.
12187 If point has not moved off frame, accept the results. */
12188 if (!current_matrix_up_to_date_p
12189 /* Don't use try_window_reusing_current_matrix in this case
12190 because a window scroll function can have changed the
12191 buffer. */
12192 || !NILP (Vwindow_scroll_functions)
12193 || MINI_WINDOW_P (w)
12194 || !(used_current_matrix_p
12195 = try_window_reusing_current_matrix (w)))
12196 {
12197 IF_DEBUG (debug_method_add (w, "1"));
12198 try_window (window, startp);
12199 }
12200
12201 if (fonts_changed_p)
12202 goto need_larger_matrices;
12203
12204 if (w->cursor.vpos >= 0)
12205 {
12206 if (!just_this_one_p
12207 || current_buffer->clip_changed
12208 || BEG_UNCHANGED < CHARPOS (startp))
12209 /* Forget any recorded base line for line number display. */
12210 w->base_line_number = Qnil;
12211
12212 if (!cursor_row_fully_visible_p (w, 1, 0))
12213 {
12214 clear_glyph_matrix (w->desired_matrix);
12215 last_line_misfit = 1;
12216 }
12217 /* Drop through and scroll. */
12218 else
12219 goto done;
12220 }
12221 else
12222 clear_glyph_matrix (w->desired_matrix);
12223 }
12224
12225 try_to_scroll:
12226
12227 w->last_modified = make_number (0);
12228 w->last_overlay_modified = make_number (0);
12229
12230 /* Redisplay the mode line. Select the buffer properly for that. */
12231 if (!update_mode_line)
12232 {
12233 update_mode_line = 1;
12234 w->update_mode_line = Qt;
12235 }
12236
12237 /* Try to scroll by specified few lines. */
12238 if ((scroll_conservatively
12239 || scroll_step
12240 || temp_scroll_step
12241 || NUMBERP (current_buffer->scroll_up_aggressively)
12242 || NUMBERP (current_buffer->scroll_down_aggressively))
12243 && !current_buffer->clip_changed
12244 && CHARPOS (startp) >= BEGV
12245 && CHARPOS (startp) <= ZV)
12246 {
12247 /* The function returns -1 if new fonts were loaded, 1 if
12248 successful, 0 if not successful. */
12249 int rc = try_scrolling (window, just_this_one_p,
12250 scroll_conservatively,
12251 scroll_step,
12252 temp_scroll_step, last_line_misfit);
12253 switch (rc)
12254 {
12255 case SCROLLING_SUCCESS:
12256 goto done;
12257
12258 case SCROLLING_NEED_LARGER_MATRICES:
12259 goto need_larger_matrices;
12260
12261 case SCROLLING_FAILED:
12262 break;
12263
12264 default:
12265 abort ();
12266 }
12267 }
12268
12269 /* Finally, just choose place to start which centers point */
12270
12271 recenter:
12272 if (centering_position < 0)
12273 centering_position = window_box_height (w) / 2;
12274
12275 #if GLYPH_DEBUG
12276 debug_method_add (w, "recenter");
12277 #endif
12278
12279 /* w->vscroll = 0; */
12280
12281 /* Forget any previously recorded base line for line number display. */
12282 if (!buffer_unchanged_p)
12283 w->base_line_number = Qnil;
12284
12285 /* Move backward half the height of the window. */
12286 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12287 it.current_y = it.last_visible_y;
12288 move_it_vertically_backward (&it, centering_position);
12289 xassert (IT_CHARPOS (it) >= BEGV);
12290
12291 /* The function move_it_vertically_backward may move over more
12292 than the specified y-distance. If it->w is small, e.g. a
12293 mini-buffer window, we may end up in front of the window's
12294 display area. Start displaying at the start of the line
12295 containing PT in this case. */
12296 if (it.current_y <= 0)
12297 {
12298 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12299 move_it_vertically_backward (&it, 0);
12300 #if 0
12301 /* I think this assert is bogus if buffer contains
12302 invisible text or images. KFS. */
12303 xassert (IT_CHARPOS (it) <= PT);
12304 #endif
12305 it.current_y = 0;
12306 }
12307
12308 it.current_x = it.hpos = 0;
12309
12310 /* Set startp here explicitly in case that helps avoid an infinite loop
12311 in case the window-scroll-functions functions get errors. */
12312 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12313
12314 /* Run scroll hooks. */
12315 startp = run_window_scroll_functions (window, it.current.pos);
12316
12317 /* Redisplay the window. */
12318 if (!current_matrix_up_to_date_p
12319 || windows_or_buffers_changed
12320 || cursor_type_changed
12321 /* Don't use try_window_reusing_current_matrix in this case
12322 because it can have changed the buffer. */
12323 || !NILP (Vwindow_scroll_functions)
12324 || !just_this_one_p
12325 || MINI_WINDOW_P (w)
12326 || !(used_current_matrix_p
12327 = try_window_reusing_current_matrix (w)))
12328 try_window (window, startp);
12329
12330 /* If new fonts have been loaded (due to fontsets), give up. We
12331 have to start a new redisplay since we need to re-adjust glyph
12332 matrices. */
12333 if (fonts_changed_p)
12334 goto need_larger_matrices;
12335
12336 /* If cursor did not appear assume that the middle of the window is
12337 in the first line of the window. Do it again with the next line.
12338 (Imagine a window of height 100, displaying two lines of height
12339 60. Moving back 50 from it->last_visible_y will end in the first
12340 line.) */
12341 if (w->cursor.vpos < 0)
12342 {
12343 if (!NILP (w->window_end_valid)
12344 && PT >= Z - XFASTINT (w->window_end_pos))
12345 {
12346 clear_glyph_matrix (w->desired_matrix);
12347 move_it_by_lines (&it, 1, 0);
12348 try_window (window, it.current.pos);
12349 }
12350 else if (PT < IT_CHARPOS (it))
12351 {
12352 clear_glyph_matrix (w->desired_matrix);
12353 move_it_by_lines (&it, -1, 0);
12354 try_window (window, it.current.pos);
12355 }
12356 else
12357 {
12358 /* Not much we can do about it. */
12359 }
12360 }
12361
12362 /* Consider the following case: Window starts at BEGV, there is
12363 invisible, intangible text at BEGV, so that display starts at
12364 some point START > BEGV. It can happen that we are called with
12365 PT somewhere between BEGV and START. Try to handle that case. */
12366 if (w->cursor.vpos < 0)
12367 {
12368 struct glyph_row *row = w->current_matrix->rows;
12369 if (row->mode_line_p)
12370 ++row;
12371 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12372 }
12373
12374 if (!cursor_row_fully_visible_p (w, 0, 0))
12375 {
12376 /* If vscroll is enabled, disable it and try again. */
12377 if (w->vscroll)
12378 {
12379 w->vscroll = 0;
12380 clear_glyph_matrix (w->desired_matrix);
12381 goto recenter;
12382 }
12383
12384 /* If centering point failed to make the whole line visible,
12385 put point at the top instead. That has to make the whole line
12386 visible, if it can be done. */
12387 if (centering_position == 0)
12388 goto done;
12389
12390 clear_glyph_matrix (w->desired_matrix);
12391 centering_position = 0;
12392 goto recenter;
12393 }
12394
12395 done:
12396
12397 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12398 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12399 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12400 ? Qt : Qnil);
12401
12402 /* Display the mode line, if we must. */
12403 if ((update_mode_line
12404 /* If window not full width, must redo its mode line
12405 if (a) the window to its side is being redone and
12406 (b) we do a frame-based redisplay. This is a consequence
12407 of how inverted lines are drawn in frame-based redisplay. */
12408 || (!just_this_one_p
12409 && !FRAME_WINDOW_P (f)
12410 && !WINDOW_FULL_WIDTH_P (w))
12411 /* Line number to display. */
12412 || INTEGERP (w->base_line_pos)
12413 /* Column number is displayed and different from the one displayed. */
12414 || (!NILP (w->column_number_displayed)
12415 && (XFASTINT (w->column_number_displayed)
12416 != (int) current_column ()))) /* iftc */
12417 /* This means that the window has a mode line. */
12418 && (WINDOW_WANTS_MODELINE_P (w)
12419 || WINDOW_WANTS_HEADER_LINE_P (w)))
12420 {
12421 display_mode_lines (w);
12422
12423 /* If mode line height has changed, arrange for a thorough
12424 immediate redisplay using the correct mode line height. */
12425 if (WINDOW_WANTS_MODELINE_P (w)
12426 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12427 {
12428 fonts_changed_p = 1;
12429 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12430 = DESIRED_MODE_LINE_HEIGHT (w);
12431 }
12432
12433 /* If top line height has changed, arrange for a thorough
12434 immediate redisplay using the correct mode line height. */
12435 if (WINDOW_WANTS_HEADER_LINE_P (w)
12436 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12437 {
12438 fonts_changed_p = 1;
12439 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12440 = DESIRED_HEADER_LINE_HEIGHT (w);
12441 }
12442
12443 if (fonts_changed_p)
12444 goto need_larger_matrices;
12445 }
12446
12447 if (!line_number_displayed
12448 && !BUFFERP (w->base_line_pos))
12449 {
12450 w->base_line_pos = Qnil;
12451 w->base_line_number = Qnil;
12452 }
12453
12454 finish_menu_bars:
12455
12456 /* When we reach a frame's selected window, redo the frame's menu bar. */
12457 if (update_mode_line
12458 && EQ (FRAME_SELECTED_WINDOW (f), window))
12459 {
12460 int redisplay_menu_p = 0;
12461 int redisplay_tool_bar_p = 0;
12462
12463 if (FRAME_WINDOW_P (f))
12464 {
12465 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12466 || defined (USE_GTK)
12467 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12468 #else
12469 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12470 #endif
12471 }
12472 else
12473 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12474
12475 if (redisplay_menu_p)
12476 display_menu_bar (w);
12477
12478 #ifdef HAVE_WINDOW_SYSTEM
12479 #ifdef USE_GTK
12480 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12481 #else
12482 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12483 && (FRAME_TOOL_BAR_LINES (f) > 0
12484 || auto_resize_tool_bars_p);
12485
12486 #endif
12487
12488 if (redisplay_tool_bar_p)
12489 redisplay_tool_bar (f);
12490 #endif
12491 }
12492
12493 #ifdef HAVE_WINDOW_SYSTEM
12494 if (FRAME_WINDOW_P (f)
12495 && update_window_fringes (w, 0)
12496 && !just_this_one_p
12497 && (used_current_matrix_p || overlay_arrow_seen)
12498 && !w->pseudo_window_p)
12499 {
12500 update_begin (f);
12501 BLOCK_INPUT;
12502 if (draw_window_fringes (w, 1))
12503 x_draw_vertical_border (w);
12504 UNBLOCK_INPUT;
12505 update_end (f);
12506 }
12507 #endif /* HAVE_WINDOW_SYSTEM */
12508
12509 /* We go to this label, with fonts_changed_p nonzero,
12510 if it is necessary to try again using larger glyph matrices.
12511 We have to redeem the scroll bar even in this case,
12512 because the loop in redisplay_internal expects that. */
12513 need_larger_matrices:
12514 ;
12515 finish_scroll_bars:
12516
12517 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12518 {
12519 /* Set the thumb's position and size. */
12520 set_vertical_scroll_bar (w);
12521
12522 /* Note that we actually used the scroll bar attached to this
12523 window, so it shouldn't be deleted at the end of redisplay. */
12524 redeem_scroll_bar_hook (w);
12525 }
12526
12527 /* Restore current_buffer and value of point in it. */
12528 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12529 set_buffer_internal_1 (old);
12530 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12531
12532 unbind_to (count, Qnil);
12533 }
12534
12535
12536 /* Build the complete desired matrix of WINDOW with a window start
12537 buffer position POS. Value is non-zero if successful. It is zero
12538 if fonts were loaded during redisplay which makes re-adjusting
12539 glyph matrices necessary. */
12540
12541 int
12542 try_window (window, pos)
12543 Lisp_Object window;
12544 struct text_pos pos;
12545 {
12546 struct window *w = XWINDOW (window);
12547 struct it it;
12548 struct glyph_row *last_text_row = NULL;
12549
12550 /* Make POS the new window start. */
12551 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12552
12553 /* Mark cursor position as unknown. No overlay arrow seen. */
12554 w->cursor.vpos = -1;
12555 overlay_arrow_seen = 0;
12556
12557 /* Initialize iterator and info to start at POS. */
12558 start_display (&it, w, pos);
12559
12560 /* Display all lines of W. */
12561 while (it.current_y < it.last_visible_y)
12562 {
12563 if (display_line (&it))
12564 last_text_row = it.glyph_row - 1;
12565 if (fonts_changed_p)
12566 return 0;
12567 }
12568
12569 /* If bottom moved off end of frame, change mode line percentage. */
12570 if (XFASTINT (w->window_end_pos) <= 0
12571 && Z != IT_CHARPOS (it))
12572 w->update_mode_line = Qt;
12573
12574 /* Set window_end_pos to the offset of the last character displayed
12575 on the window from the end of current_buffer. Set
12576 window_end_vpos to its row number. */
12577 if (last_text_row)
12578 {
12579 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12580 w->window_end_bytepos
12581 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12582 w->window_end_pos
12583 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12584 w->window_end_vpos
12585 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12586 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12587 ->displays_text_p);
12588 }
12589 else
12590 {
12591 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12592 w->window_end_pos = make_number (Z - ZV);
12593 w->window_end_vpos = make_number (0);
12594 }
12595
12596 /* But that is not valid info until redisplay finishes. */
12597 w->window_end_valid = Qnil;
12598 return 1;
12599 }
12600
12601
12602 \f
12603 /************************************************************************
12604 Window redisplay reusing current matrix when buffer has not changed
12605 ************************************************************************/
12606
12607 /* Try redisplay of window W showing an unchanged buffer with a
12608 different window start than the last time it was displayed by
12609 reusing its current matrix. Value is non-zero if successful.
12610 W->start is the new window start. */
12611
12612 static int
12613 try_window_reusing_current_matrix (w)
12614 struct window *w;
12615 {
12616 struct frame *f = XFRAME (w->frame);
12617 struct glyph_row *row, *bottom_row;
12618 struct it it;
12619 struct run run;
12620 struct text_pos start, new_start;
12621 int nrows_scrolled, i;
12622 struct glyph_row *last_text_row;
12623 struct glyph_row *last_reused_text_row;
12624 struct glyph_row *start_row;
12625 int start_vpos, min_y, max_y;
12626
12627 #if GLYPH_DEBUG
12628 if (inhibit_try_window_reusing)
12629 return 0;
12630 #endif
12631
12632 if (/* This function doesn't handle terminal frames. */
12633 !FRAME_WINDOW_P (f)
12634 /* Don't try to reuse the display if windows have been split
12635 or such. */
12636 || windows_or_buffers_changed
12637 || cursor_type_changed)
12638 return 0;
12639
12640 /* Can't do this if region may have changed. */
12641 if ((!NILP (Vtransient_mark_mode)
12642 && !NILP (current_buffer->mark_active))
12643 || !NILP (w->region_showing)
12644 || !NILP (Vshow_trailing_whitespace))
12645 return 0;
12646
12647 /* If top-line visibility has changed, give up. */
12648 if (WINDOW_WANTS_HEADER_LINE_P (w)
12649 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12650 return 0;
12651
12652 /* Give up if old or new display is scrolled vertically. We could
12653 make this function handle this, but right now it doesn't. */
12654 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12655 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12656 return 0;
12657
12658 /* The variable new_start now holds the new window start. The old
12659 start `start' can be determined from the current matrix. */
12660 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12661 start = start_row->start.pos;
12662 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12663
12664 /* Clear the desired matrix for the display below. */
12665 clear_glyph_matrix (w->desired_matrix);
12666
12667 if (CHARPOS (new_start) <= CHARPOS (start))
12668 {
12669 int first_row_y;
12670
12671 /* Don't use this method if the display starts with an ellipsis
12672 displayed for invisible text. It's not easy to handle that case
12673 below, and it's certainly not worth the effort since this is
12674 not a frequent case. */
12675 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12676 return 0;
12677
12678 IF_DEBUG (debug_method_add (w, "twu1"));
12679
12680 /* Display up to a row that can be reused. The variable
12681 last_text_row is set to the last row displayed that displays
12682 text. Note that it.vpos == 0 if or if not there is a
12683 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12684 start_display (&it, w, new_start);
12685 first_row_y = it.current_y;
12686 w->cursor.vpos = -1;
12687 last_text_row = last_reused_text_row = NULL;
12688
12689 while (it.current_y < it.last_visible_y
12690 && !fonts_changed_p)
12691 {
12692 /* If we have reached into the characters in the START row,
12693 that means the line boundaries have changed. So we
12694 can't start copying with the row START. Maybe it will
12695 work to start copying with the following row. */
12696 while (IT_CHARPOS (it) > CHARPOS (start))
12697 {
12698 /* Advance to the next row as the "start". */
12699 start_row++;
12700 start = start_row->start.pos;
12701 /* If there are no more rows to try, or just one, give up. */
12702 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12703 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12704 || CHARPOS (start) == ZV)
12705 {
12706 clear_glyph_matrix (w->desired_matrix);
12707 return 0;
12708 }
12709
12710 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12711 }
12712 /* If we have reached alignment,
12713 we can copy the rest of the rows. */
12714 if (IT_CHARPOS (it) == CHARPOS (start))
12715 break;
12716
12717 if (display_line (&it))
12718 last_text_row = it.glyph_row - 1;
12719 }
12720
12721 /* A value of current_y < last_visible_y means that we stopped
12722 at the previous window start, which in turn means that we
12723 have at least one reusable row. */
12724 if (it.current_y < it.last_visible_y)
12725 {
12726 /* IT.vpos always starts from 0; it counts text lines. */
12727 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12728
12729 /* Find PT if not already found in the lines displayed. */
12730 if (w->cursor.vpos < 0)
12731 {
12732 int dy = it.current_y - start_row->y;
12733
12734 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12735 row = row_containing_pos (w, PT, row, NULL, dy);
12736 if (row)
12737 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12738 dy, nrows_scrolled);
12739 else
12740 {
12741 clear_glyph_matrix (w->desired_matrix);
12742 return 0;
12743 }
12744 }
12745
12746 /* Scroll the display. Do it before the current matrix is
12747 changed. The problem here is that update has not yet
12748 run, i.e. part of the current matrix is not up to date.
12749 scroll_run_hook will clear the cursor, and use the
12750 current matrix to get the height of the row the cursor is
12751 in. */
12752 run.current_y = start_row->y;
12753 run.desired_y = it.current_y;
12754 run.height = it.last_visible_y - it.current_y;
12755
12756 if (run.height > 0 && run.current_y != run.desired_y)
12757 {
12758 update_begin (f);
12759 rif->update_window_begin_hook (w);
12760 rif->clear_window_mouse_face (w);
12761 rif->scroll_run_hook (w, &run);
12762 rif->update_window_end_hook (w, 0, 0);
12763 update_end (f);
12764 }
12765
12766 /* Shift current matrix down by nrows_scrolled lines. */
12767 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12768 rotate_matrix (w->current_matrix,
12769 start_vpos,
12770 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12771 nrows_scrolled);
12772
12773 /* Disable lines that must be updated. */
12774 for (i = 0; i < it.vpos; ++i)
12775 (start_row + i)->enabled_p = 0;
12776
12777 /* Re-compute Y positions. */
12778 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12779 max_y = it.last_visible_y;
12780 for (row = start_row + nrows_scrolled;
12781 row < bottom_row;
12782 ++row)
12783 {
12784 row->y = it.current_y;
12785 row->visible_height = row->height;
12786
12787 if (row->y < min_y)
12788 row->visible_height -= min_y - row->y;
12789 if (row->y + row->height > max_y)
12790 row->visible_height -= row->y + row->height - max_y;
12791 row->redraw_fringe_bitmaps_p = 1;
12792
12793 it.current_y += row->height;
12794
12795 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12796 last_reused_text_row = row;
12797 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12798 break;
12799 }
12800
12801 /* Disable lines in the current matrix which are now
12802 below the window. */
12803 for (++row; row < bottom_row; ++row)
12804 row->enabled_p = 0;
12805 }
12806
12807 /* Update window_end_pos etc.; last_reused_text_row is the last
12808 reused row from the current matrix containing text, if any.
12809 The value of last_text_row is the last displayed line
12810 containing text. */
12811 if (last_reused_text_row)
12812 {
12813 w->window_end_bytepos
12814 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12815 w->window_end_pos
12816 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12817 w->window_end_vpos
12818 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12819 w->current_matrix));
12820 }
12821 else if (last_text_row)
12822 {
12823 w->window_end_bytepos
12824 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12825 w->window_end_pos
12826 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12827 w->window_end_vpos
12828 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12829 }
12830 else
12831 {
12832 /* This window must be completely empty. */
12833 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12834 w->window_end_pos = make_number (Z - ZV);
12835 w->window_end_vpos = make_number (0);
12836 }
12837 w->window_end_valid = Qnil;
12838
12839 /* Update hint: don't try scrolling again in update_window. */
12840 w->desired_matrix->no_scrolling_p = 1;
12841
12842 #if GLYPH_DEBUG
12843 debug_method_add (w, "try_window_reusing_current_matrix 1");
12844 #endif
12845 return 1;
12846 }
12847 else if (CHARPOS (new_start) > CHARPOS (start))
12848 {
12849 struct glyph_row *pt_row, *row;
12850 struct glyph_row *first_reusable_row;
12851 struct glyph_row *first_row_to_display;
12852 int dy;
12853 int yb = window_text_bottom_y (w);
12854
12855 /* Find the row starting at new_start, if there is one. Don't
12856 reuse a partially visible line at the end. */
12857 first_reusable_row = start_row;
12858 while (first_reusable_row->enabled_p
12859 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12860 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12861 < CHARPOS (new_start)))
12862 ++first_reusable_row;
12863
12864 /* Give up if there is no row to reuse. */
12865 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12866 || !first_reusable_row->enabled_p
12867 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12868 != CHARPOS (new_start)))
12869 return 0;
12870
12871 /* We can reuse fully visible rows beginning with
12872 first_reusable_row to the end of the window. Set
12873 first_row_to_display to the first row that cannot be reused.
12874 Set pt_row to the row containing point, if there is any. */
12875 pt_row = NULL;
12876 for (first_row_to_display = first_reusable_row;
12877 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12878 ++first_row_to_display)
12879 {
12880 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12881 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12882 pt_row = first_row_to_display;
12883 }
12884
12885 /* Start displaying at the start of first_row_to_display. */
12886 xassert (first_row_to_display->y < yb);
12887 init_to_row_start (&it, w, first_row_to_display);
12888
12889 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12890 - start_vpos);
12891 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12892 - nrows_scrolled);
12893 it.current_y = (first_row_to_display->y - first_reusable_row->y
12894 + WINDOW_HEADER_LINE_HEIGHT (w));
12895
12896 /* Display lines beginning with first_row_to_display in the
12897 desired matrix. Set last_text_row to the last row displayed
12898 that displays text. */
12899 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12900 if (pt_row == NULL)
12901 w->cursor.vpos = -1;
12902 last_text_row = NULL;
12903 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12904 if (display_line (&it))
12905 last_text_row = it.glyph_row - 1;
12906
12907 /* Give up If point isn't in a row displayed or reused. */
12908 if (w->cursor.vpos < 0)
12909 {
12910 clear_glyph_matrix (w->desired_matrix);
12911 return 0;
12912 }
12913
12914 /* If point is in a reused row, adjust y and vpos of the cursor
12915 position. */
12916 if (pt_row)
12917 {
12918 w->cursor.vpos -= nrows_scrolled;
12919 w->cursor.y -= first_reusable_row->y - start_row->y;
12920 }
12921
12922 /* Scroll the display. */
12923 run.current_y = first_reusable_row->y;
12924 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12925 run.height = it.last_visible_y - run.current_y;
12926 dy = run.current_y - run.desired_y;
12927
12928 if (run.height)
12929 {
12930 update_begin (f);
12931 rif->update_window_begin_hook (w);
12932 rif->clear_window_mouse_face (w);
12933 rif->scroll_run_hook (w, &run);
12934 rif->update_window_end_hook (w, 0, 0);
12935 update_end (f);
12936 }
12937
12938 /* Adjust Y positions of reused rows. */
12939 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12940 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12941 max_y = it.last_visible_y;
12942 for (row = first_reusable_row; row < first_row_to_display; ++row)
12943 {
12944 row->y -= dy;
12945 row->visible_height = row->height;
12946 if (row->y < min_y)
12947 row->visible_height -= min_y - row->y;
12948 if (row->y + row->height > max_y)
12949 row->visible_height -= row->y + row->height - max_y;
12950 row->redraw_fringe_bitmaps_p = 1;
12951 }
12952
12953 /* Scroll the current matrix. */
12954 xassert (nrows_scrolled > 0);
12955 rotate_matrix (w->current_matrix,
12956 start_vpos,
12957 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12958 -nrows_scrolled);
12959
12960 /* Disable rows not reused. */
12961 for (row -= nrows_scrolled; row < bottom_row; ++row)
12962 row->enabled_p = 0;
12963
12964 /* Point may have moved to a different line, so we cannot assume that
12965 the previous cursor position is valid; locate the correct row. */
12966 if (pt_row)
12967 {
12968 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12969 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12970 row++)
12971 {
12972 w->cursor.vpos++;
12973 w->cursor.y = row->y;
12974 }
12975 if (row < bottom_row)
12976 {
12977 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12978 while (glyph->charpos < PT)
12979 {
12980 w->cursor.hpos++;
12981 w->cursor.x += glyph->pixel_width;
12982 glyph++;
12983 }
12984 }
12985 }
12986
12987 /* Adjust window end. A null value of last_text_row means that
12988 the window end is in reused rows which in turn means that
12989 only its vpos can have changed. */
12990 if (last_text_row)
12991 {
12992 w->window_end_bytepos
12993 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12994 w->window_end_pos
12995 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12996 w->window_end_vpos
12997 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12998 }
12999 else
13000 {
13001 w->window_end_vpos
13002 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
13003 }
13004
13005 w->window_end_valid = Qnil;
13006 w->desired_matrix->no_scrolling_p = 1;
13007
13008 #if GLYPH_DEBUG
13009 debug_method_add (w, "try_window_reusing_current_matrix 2");
13010 #endif
13011 return 1;
13012 }
13013
13014 return 0;
13015 }
13016
13017
13018 \f
13019 /************************************************************************
13020 Window redisplay reusing current matrix when buffer has changed
13021 ************************************************************************/
13022
13023 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
13024 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
13025 int *, int *));
13026 static struct glyph_row *
13027 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
13028 struct glyph_row *));
13029
13030
13031 /* Return the last row in MATRIX displaying text. If row START is
13032 non-null, start searching with that row. IT gives the dimensions
13033 of the display. Value is null if matrix is empty; otherwise it is
13034 a pointer to the row found. */
13035
13036 static struct glyph_row *
13037 find_last_row_displaying_text (matrix, it, start)
13038 struct glyph_matrix *matrix;
13039 struct it *it;
13040 struct glyph_row *start;
13041 {
13042 struct glyph_row *row, *row_found;
13043
13044 /* Set row_found to the last row in IT->w's current matrix
13045 displaying text. The loop looks funny but think of partially
13046 visible lines. */
13047 row_found = NULL;
13048 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
13049 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13050 {
13051 xassert (row->enabled_p);
13052 row_found = row;
13053 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
13054 break;
13055 ++row;
13056 }
13057
13058 return row_found;
13059 }
13060
13061
13062 /* Return the last row in the current matrix of W that is not affected
13063 by changes at the start of current_buffer that occurred since W's
13064 current matrix was built. Value is null if no such row exists.
13065
13066 BEG_UNCHANGED us the number of characters unchanged at the start of
13067 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13068 first changed character in current_buffer. Characters at positions <
13069 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13070 when the current matrix was built. */
13071
13072 static struct glyph_row *
13073 find_last_unchanged_at_beg_row (w)
13074 struct window *w;
13075 {
13076 int first_changed_pos = BEG + BEG_UNCHANGED;
13077 struct glyph_row *row;
13078 struct glyph_row *row_found = NULL;
13079 int yb = window_text_bottom_y (w);
13080
13081 /* Find the last row displaying unchanged text. */
13082 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13083 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13084 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
13085 {
13086 if (/* If row ends before first_changed_pos, it is unchanged,
13087 except in some case. */
13088 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
13089 /* When row ends in ZV and we write at ZV it is not
13090 unchanged. */
13091 && !row->ends_at_zv_p
13092 /* When first_changed_pos is the end of a continued line,
13093 row is not unchanged because it may be no longer
13094 continued. */
13095 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
13096 && (row->continued_p
13097 || row->exact_window_width_line_p)))
13098 row_found = row;
13099
13100 /* Stop if last visible row. */
13101 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
13102 break;
13103
13104 ++row;
13105 }
13106
13107 return row_found;
13108 }
13109
13110
13111 /* Find the first glyph row in the current matrix of W that is not
13112 affected by changes at the end of current_buffer since the
13113 time W's current matrix was built.
13114
13115 Return in *DELTA the number of chars by which buffer positions in
13116 unchanged text at the end of current_buffer must be adjusted.
13117
13118 Return in *DELTA_BYTES the corresponding number of bytes.
13119
13120 Value is null if no such row exists, i.e. all rows are affected by
13121 changes. */
13122
13123 static struct glyph_row *
13124 find_first_unchanged_at_end_row (w, delta, delta_bytes)
13125 struct window *w;
13126 int *delta, *delta_bytes;
13127 {
13128 struct glyph_row *row;
13129 struct glyph_row *row_found = NULL;
13130
13131 *delta = *delta_bytes = 0;
13132
13133 /* Display must not have been paused, otherwise the current matrix
13134 is not up to date. */
13135 if (NILP (w->window_end_valid))
13136 abort ();
13137
13138 /* A value of window_end_pos >= END_UNCHANGED means that the window
13139 end is in the range of changed text. If so, there is no
13140 unchanged row at the end of W's current matrix. */
13141 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
13142 return NULL;
13143
13144 /* Set row to the last row in W's current matrix displaying text. */
13145 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13146
13147 /* If matrix is entirely empty, no unchanged row exists. */
13148 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13149 {
13150 /* The value of row is the last glyph row in the matrix having a
13151 meaningful buffer position in it. The end position of row
13152 corresponds to window_end_pos. This allows us to translate
13153 buffer positions in the current matrix to current buffer
13154 positions for characters not in changed text. */
13155 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13156 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13157 int last_unchanged_pos, last_unchanged_pos_old;
13158 struct glyph_row *first_text_row
13159 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13160
13161 *delta = Z - Z_old;
13162 *delta_bytes = Z_BYTE - Z_BYTE_old;
13163
13164 /* Set last_unchanged_pos to the buffer position of the last
13165 character in the buffer that has not been changed. Z is the
13166 index + 1 of the last character in current_buffer, i.e. by
13167 subtracting END_UNCHANGED we get the index of the last
13168 unchanged character, and we have to add BEG to get its buffer
13169 position. */
13170 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13171 last_unchanged_pos_old = last_unchanged_pos - *delta;
13172
13173 /* Search backward from ROW for a row displaying a line that
13174 starts at a minimum position >= last_unchanged_pos_old. */
13175 for (; row > first_text_row; --row)
13176 {
13177 /* This used to abort, but it can happen.
13178 It is ok to just stop the search instead here. KFS. */
13179 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13180 break;
13181
13182 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13183 row_found = row;
13184 }
13185 }
13186
13187 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13188 abort ();
13189
13190 return row_found;
13191 }
13192
13193
13194 /* Make sure that glyph rows in the current matrix of window W
13195 reference the same glyph memory as corresponding rows in the
13196 frame's frame matrix. This function is called after scrolling W's
13197 current matrix on a terminal frame in try_window_id and
13198 try_window_reusing_current_matrix. */
13199
13200 static void
13201 sync_frame_with_window_matrix_rows (w)
13202 struct window *w;
13203 {
13204 struct frame *f = XFRAME (w->frame);
13205 struct glyph_row *window_row, *window_row_end, *frame_row;
13206
13207 /* Preconditions: W must be a leaf window and full-width. Its frame
13208 must have a frame matrix. */
13209 xassert (NILP (w->hchild) && NILP (w->vchild));
13210 xassert (WINDOW_FULL_WIDTH_P (w));
13211 xassert (!FRAME_WINDOW_P (f));
13212
13213 /* If W is a full-width window, glyph pointers in W's current matrix
13214 have, by definition, to be the same as glyph pointers in the
13215 corresponding frame matrix. Note that frame matrices have no
13216 marginal areas (see build_frame_matrix). */
13217 window_row = w->current_matrix->rows;
13218 window_row_end = window_row + w->current_matrix->nrows;
13219 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13220 while (window_row < window_row_end)
13221 {
13222 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13223 struct glyph *end = window_row->glyphs[LAST_AREA];
13224
13225 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13226 frame_row->glyphs[TEXT_AREA] = start;
13227 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13228 frame_row->glyphs[LAST_AREA] = end;
13229
13230 /* Disable frame rows whose corresponding window rows have
13231 been disabled in try_window_id. */
13232 if (!window_row->enabled_p)
13233 frame_row->enabled_p = 0;
13234
13235 ++window_row, ++frame_row;
13236 }
13237 }
13238
13239
13240 /* Find the glyph row in window W containing CHARPOS. Consider all
13241 rows between START and END (not inclusive). END null means search
13242 all rows to the end of the display area of W. Value is the row
13243 containing CHARPOS or null. */
13244
13245 struct glyph_row *
13246 row_containing_pos (w, charpos, start, end, dy)
13247 struct window *w;
13248 int charpos;
13249 struct glyph_row *start, *end;
13250 int dy;
13251 {
13252 struct glyph_row *row = start;
13253 int last_y;
13254
13255 /* If we happen to start on a header-line, skip that. */
13256 if (row->mode_line_p)
13257 ++row;
13258
13259 if ((end && row >= end) || !row->enabled_p)
13260 return NULL;
13261
13262 last_y = window_text_bottom_y (w) - dy;
13263
13264 while (1)
13265 {
13266 /* Give up if we have gone too far. */
13267 if (end && row >= end)
13268 return NULL;
13269 /* This formerly returned if they were equal.
13270 I think that both quantities are of a "last plus one" type;
13271 if so, when they are equal, the row is within the screen. -- rms. */
13272 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13273 return NULL;
13274
13275 /* If it is in this row, return this row. */
13276 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13277 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13278 /* The end position of a row equals the start
13279 position of the next row. If CHARPOS is there, we
13280 would rather display it in the next line, except
13281 when this line ends in ZV. */
13282 && !row->ends_at_zv_p
13283 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13284 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13285 return row;
13286 ++row;
13287 }
13288 }
13289
13290
13291 /* Try to redisplay window W by reusing its existing display. W's
13292 current matrix must be up to date when this function is called,
13293 i.e. window_end_valid must not be nil.
13294
13295 Value is
13296
13297 1 if display has been updated
13298 0 if otherwise unsuccessful
13299 -1 if redisplay with same window start is known not to succeed
13300
13301 The following steps are performed:
13302
13303 1. Find the last row in the current matrix of W that is not
13304 affected by changes at the start of current_buffer. If no such row
13305 is found, give up.
13306
13307 2. Find the first row in W's current matrix that is not affected by
13308 changes at the end of current_buffer. Maybe there is no such row.
13309
13310 3. Display lines beginning with the row + 1 found in step 1 to the
13311 row found in step 2 or, if step 2 didn't find a row, to the end of
13312 the window.
13313
13314 4. If cursor is not known to appear on the window, give up.
13315
13316 5. If display stopped at the row found in step 2, scroll the
13317 display and current matrix as needed.
13318
13319 6. Maybe display some lines at the end of W, if we must. This can
13320 happen under various circumstances, like a partially visible line
13321 becoming fully visible, or because newly displayed lines are displayed
13322 in smaller font sizes.
13323
13324 7. Update W's window end information. */
13325
13326 static int
13327 try_window_id (w)
13328 struct window *w;
13329 {
13330 struct frame *f = XFRAME (w->frame);
13331 struct glyph_matrix *current_matrix = w->current_matrix;
13332 struct glyph_matrix *desired_matrix = w->desired_matrix;
13333 struct glyph_row *last_unchanged_at_beg_row;
13334 struct glyph_row *first_unchanged_at_end_row;
13335 struct glyph_row *row;
13336 struct glyph_row *bottom_row;
13337 int bottom_vpos;
13338 struct it it;
13339 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13340 struct text_pos start_pos;
13341 struct run run;
13342 int first_unchanged_at_end_vpos = 0;
13343 struct glyph_row *last_text_row, *last_text_row_at_end;
13344 struct text_pos start;
13345 int first_changed_charpos, last_changed_charpos;
13346
13347 #if GLYPH_DEBUG
13348 if (inhibit_try_window_id)
13349 return 0;
13350 #endif
13351
13352 /* This is handy for debugging. */
13353 #if 0
13354 #define GIVE_UP(X) \
13355 do { \
13356 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13357 return 0; \
13358 } while (0)
13359 #else
13360 #define GIVE_UP(X) return 0
13361 #endif
13362
13363 SET_TEXT_POS_FROM_MARKER (start, w->start);
13364
13365 /* Don't use this for mini-windows because these can show
13366 messages and mini-buffers, and we don't handle that here. */
13367 if (MINI_WINDOW_P (w))
13368 GIVE_UP (1);
13369
13370 /* This flag is used to prevent redisplay optimizations. */
13371 if (windows_or_buffers_changed || cursor_type_changed)
13372 GIVE_UP (2);
13373
13374 /* Verify that narrowing has not changed.
13375 Also verify that we were not told to prevent redisplay optimizations.
13376 It would be nice to further
13377 reduce the number of cases where this prevents try_window_id. */
13378 if (current_buffer->clip_changed
13379 || current_buffer->prevent_redisplay_optimizations_p)
13380 GIVE_UP (3);
13381
13382 /* Window must either use window-based redisplay or be full width. */
13383 if (!FRAME_WINDOW_P (f)
13384 && (!line_ins_del_ok
13385 || !WINDOW_FULL_WIDTH_P (w)))
13386 GIVE_UP (4);
13387
13388 /* Give up if point is not known NOT to appear in W. */
13389 if (PT < CHARPOS (start))
13390 GIVE_UP (5);
13391
13392 /* Another way to prevent redisplay optimizations. */
13393 if (XFASTINT (w->last_modified) == 0)
13394 GIVE_UP (6);
13395
13396 /* Verify that window is not hscrolled. */
13397 if (XFASTINT (w->hscroll) != 0)
13398 GIVE_UP (7);
13399
13400 /* Verify that display wasn't paused. */
13401 if (NILP (w->window_end_valid))
13402 GIVE_UP (8);
13403
13404 /* Can't use this if highlighting a region because a cursor movement
13405 will do more than just set the cursor. */
13406 if (!NILP (Vtransient_mark_mode)
13407 && !NILP (current_buffer->mark_active))
13408 GIVE_UP (9);
13409
13410 /* Likewise if highlighting trailing whitespace. */
13411 if (!NILP (Vshow_trailing_whitespace))
13412 GIVE_UP (11);
13413
13414 /* Likewise if showing a region. */
13415 if (!NILP (w->region_showing))
13416 GIVE_UP (10);
13417
13418 /* Can use this if overlay arrow position and or string have changed. */
13419 if (overlay_arrows_changed_p ())
13420 GIVE_UP (12);
13421
13422
13423 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13424 only if buffer has really changed. The reason is that the gap is
13425 initially at Z for freshly visited files. The code below would
13426 set end_unchanged to 0 in that case. */
13427 if (MODIFF > SAVE_MODIFF
13428 /* This seems to happen sometimes after saving a buffer. */
13429 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13430 {
13431 if (GPT - BEG < BEG_UNCHANGED)
13432 BEG_UNCHANGED = GPT - BEG;
13433 if (Z - GPT < END_UNCHANGED)
13434 END_UNCHANGED = Z - GPT;
13435 }
13436
13437 /* The position of the first and last character that has been changed. */
13438 first_changed_charpos = BEG + BEG_UNCHANGED;
13439 last_changed_charpos = Z - END_UNCHANGED;
13440
13441 /* If window starts after a line end, and the last change is in
13442 front of that newline, then changes don't affect the display.
13443 This case happens with stealth-fontification. Note that although
13444 the display is unchanged, glyph positions in the matrix have to
13445 be adjusted, of course. */
13446 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13447 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13448 && ((last_changed_charpos < CHARPOS (start)
13449 && CHARPOS (start) == BEGV)
13450 || (last_changed_charpos < CHARPOS (start) - 1
13451 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13452 {
13453 int Z_old, delta, Z_BYTE_old, delta_bytes;
13454 struct glyph_row *r0;
13455
13456 /* Compute how many chars/bytes have been added to or removed
13457 from the buffer. */
13458 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13459 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13460 delta = Z - Z_old;
13461 delta_bytes = Z_BYTE - Z_BYTE_old;
13462
13463 /* Give up if PT is not in the window. Note that it already has
13464 been checked at the start of try_window_id that PT is not in
13465 front of the window start. */
13466 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13467 GIVE_UP (13);
13468
13469 /* If window start is unchanged, we can reuse the whole matrix
13470 as is, after adjusting glyph positions. No need to compute
13471 the window end again, since its offset from Z hasn't changed. */
13472 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13473 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13474 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13475 /* PT must not be in a partially visible line. */
13476 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13477 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13478 {
13479 /* Adjust positions in the glyph matrix. */
13480 if (delta || delta_bytes)
13481 {
13482 struct glyph_row *r1
13483 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13484 increment_matrix_positions (w->current_matrix,
13485 MATRIX_ROW_VPOS (r0, current_matrix),
13486 MATRIX_ROW_VPOS (r1, current_matrix),
13487 delta, delta_bytes);
13488 }
13489
13490 /* Set the cursor. */
13491 row = row_containing_pos (w, PT, r0, NULL, 0);
13492 if (row)
13493 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13494 else
13495 abort ();
13496 return 1;
13497 }
13498 }
13499
13500 /* Handle the case that changes are all below what is displayed in
13501 the window, and that PT is in the window. This shortcut cannot
13502 be taken if ZV is visible in the window, and text has been added
13503 there that is visible in the window. */
13504 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13505 /* ZV is not visible in the window, or there are no
13506 changes at ZV, actually. */
13507 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13508 || first_changed_charpos == last_changed_charpos))
13509 {
13510 struct glyph_row *r0;
13511
13512 /* Give up if PT is not in the window. Note that it already has
13513 been checked at the start of try_window_id that PT is not in
13514 front of the window start. */
13515 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13516 GIVE_UP (14);
13517
13518 /* If window start is unchanged, we can reuse the whole matrix
13519 as is, without changing glyph positions since no text has
13520 been added/removed in front of the window end. */
13521 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13522 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13523 /* PT must not be in a partially visible line. */
13524 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13525 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13526 {
13527 /* We have to compute the window end anew since text
13528 can have been added/removed after it. */
13529 w->window_end_pos
13530 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13531 w->window_end_bytepos
13532 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13533
13534 /* Set the cursor. */
13535 row = row_containing_pos (w, PT, r0, NULL, 0);
13536 if (row)
13537 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13538 else
13539 abort ();
13540 return 2;
13541 }
13542 }
13543
13544 /* Give up if window start is in the changed area.
13545
13546 The condition used to read
13547
13548 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13549
13550 but why that was tested escapes me at the moment. */
13551 if (CHARPOS (start) >= first_changed_charpos
13552 && CHARPOS (start) <= last_changed_charpos)
13553 GIVE_UP (15);
13554
13555 /* Check that window start agrees with the start of the first glyph
13556 row in its current matrix. Check this after we know the window
13557 start is not in changed text, otherwise positions would not be
13558 comparable. */
13559 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13560 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13561 GIVE_UP (16);
13562
13563 /* Give up if the window ends in strings. Overlay strings
13564 at the end are difficult to handle, so don't try. */
13565 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13566 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13567 GIVE_UP (20);
13568
13569 /* Compute the position at which we have to start displaying new
13570 lines. Some of the lines at the top of the window might be
13571 reusable because they are not displaying changed text. Find the
13572 last row in W's current matrix not affected by changes at the
13573 start of current_buffer. Value is null if changes start in the
13574 first line of window. */
13575 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13576 if (last_unchanged_at_beg_row)
13577 {
13578 /* Avoid starting to display in the moddle of a character, a TAB
13579 for instance. This is easier than to set up the iterator
13580 exactly, and it's not a frequent case, so the additional
13581 effort wouldn't really pay off. */
13582 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13583 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13584 && last_unchanged_at_beg_row > w->current_matrix->rows)
13585 --last_unchanged_at_beg_row;
13586
13587 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13588 GIVE_UP (17);
13589
13590 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13591 GIVE_UP (18);
13592 start_pos = it.current.pos;
13593
13594 /* Start displaying new lines in the desired matrix at the same
13595 vpos we would use in the current matrix, i.e. below
13596 last_unchanged_at_beg_row. */
13597 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13598 current_matrix);
13599 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13600 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13601
13602 xassert (it.hpos == 0 && it.current_x == 0);
13603 }
13604 else
13605 {
13606 /* There are no reusable lines at the start of the window.
13607 Start displaying in the first text line. */
13608 start_display (&it, w, start);
13609 it.vpos = it.first_vpos;
13610 start_pos = it.current.pos;
13611 }
13612
13613 /* Find the first row that is not affected by changes at the end of
13614 the buffer. Value will be null if there is no unchanged row, in
13615 which case we must redisplay to the end of the window. delta
13616 will be set to the value by which buffer positions beginning with
13617 first_unchanged_at_end_row have to be adjusted due to text
13618 changes. */
13619 first_unchanged_at_end_row
13620 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13621 IF_DEBUG (debug_delta = delta);
13622 IF_DEBUG (debug_delta_bytes = delta_bytes);
13623
13624 /* Set stop_pos to the buffer position up to which we will have to
13625 display new lines. If first_unchanged_at_end_row != NULL, this
13626 is the buffer position of the start of the line displayed in that
13627 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13628 that we don't stop at a buffer position. */
13629 stop_pos = 0;
13630 if (first_unchanged_at_end_row)
13631 {
13632 xassert (last_unchanged_at_beg_row == NULL
13633 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13634
13635 /* If this is a continuation line, move forward to the next one
13636 that isn't. Changes in lines above affect this line.
13637 Caution: this may move first_unchanged_at_end_row to a row
13638 not displaying text. */
13639 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13640 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13641 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13642 < it.last_visible_y))
13643 ++first_unchanged_at_end_row;
13644
13645 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13646 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13647 >= it.last_visible_y))
13648 first_unchanged_at_end_row = NULL;
13649 else
13650 {
13651 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13652 + delta);
13653 first_unchanged_at_end_vpos
13654 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13655 xassert (stop_pos >= Z - END_UNCHANGED);
13656 }
13657 }
13658 else if (last_unchanged_at_beg_row == NULL)
13659 GIVE_UP (19);
13660
13661
13662 #if GLYPH_DEBUG
13663
13664 /* Either there is no unchanged row at the end, or the one we have
13665 now displays text. This is a necessary condition for the window
13666 end pos calculation at the end of this function. */
13667 xassert (first_unchanged_at_end_row == NULL
13668 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13669
13670 debug_last_unchanged_at_beg_vpos
13671 = (last_unchanged_at_beg_row
13672 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13673 : -1);
13674 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13675
13676 #endif /* GLYPH_DEBUG != 0 */
13677
13678
13679 /* Display new lines. Set last_text_row to the last new line
13680 displayed which has text on it, i.e. might end up as being the
13681 line where the window_end_vpos is. */
13682 w->cursor.vpos = -1;
13683 last_text_row = NULL;
13684 overlay_arrow_seen = 0;
13685 while (it.current_y < it.last_visible_y
13686 && !fonts_changed_p
13687 && (first_unchanged_at_end_row == NULL
13688 || IT_CHARPOS (it) < stop_pos))
13689 {
13690 if (display_line (&it))
13691 last_text_row = it.glyph_row - 1;
13692 }
13693
13694 if (fonts_changed_p)
13695 return -1;
13696
13697
13698 /* Compute differences in buffer positions, y-positions etc. for
13699 lines reused at the bottom of the window. Compute what we can
13700 scroll. */
13701 if (first_unchanged_at_end_row
13702 /* No lines reused because we displayed everything up to the
13703 bottom of the window. */
13704 && it.current_y < it.last_visible_y)
13705 {
13706 dvpos = (it.vpos
13707 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13708 current_matrix));
13709 dy = it.current_y - first_unchanged_at_end_row->y;
13710 run.current_y = first_unchanged_at_end_row->y;
13711 run.desired_y = run.current_y + dy;
13712 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13713 }
13714 else
13715 {
13716 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13717 first_unchanged_at_end_row = NULL;
13718 }
13719 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13720
13721
13722 /* Find the cursor if not already found. We have to decide whether
13723 PT will appear on this window (it sometimes doesn't, but this is
13724 not a very frequent case.) This decision has to be made before
13725 the current matrix is altered. A value of cursor.vpos < 0 means
13726 that PT is either in one of the lines beginning at
13727 first_unchanged_at_end_row or below the window. Don't care for
13728 lines that might be displayed later at the window end; as
13729 mentioned, this is not a frequent case. */
13730 if (w->cursor.vpos < 0)
13731 {
13732 /* Cursor in unchanged rows at the top? */
13733 if (PT < CHARPOS (start_pos)
13734 && last_unchanged_at_beg_row)
13735 {
13736 row = row_containing_pos (w, PT,
13737 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13738 last_unchanged_at_beg_row + 1, 0);
13739 if (row)
13740 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13741 }
13742
13743 /* Start from first_unchanged_at_end_row looking for PT. */
13744 else if (first_unchanged_at_end_row)
13745 {
13746 row = row_containing_pos (w, PT - delta,
13747 first_unchanged_at_end_row, NULL, 0);
13748 if (row)
13749 set_cursor_from_row (w, row, w->current_matrix, delta,
13750 delta_bytes, dy, dvpos);
13751 }
13752
13753 /* Give up if cursor was not found. */
13754 if (w->cursor.vpos < 0)
13755 {
13756 clear_glyph_matrix (w->desired_matrix);
13757 return -1;
13758 }
13759 }
13760
13761 /* Don't let the cursor end in the scroll margins. */
13762 {
13763 int this_scroll_margin, cursor_height;
13764
13765 this_scroll_margin = max (0, scroll_margin);
13766 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13767 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13768 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13769
13770 if ((w->cursor.y < this_scroll_margin
13771 && CHARPOS (start) > BEGV)
13772 /* Old redisplay didn't take scroll margin into account at the bottom,
13773 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13774 || (w->cursor.y + (make_cursor_line_fully_visible_p
13775 ? cursor_height + this_scroll_margin
13776 : 1)) > it.last_visible_y)
13777 {
13778 w->cursor.vpos = -1;
13779 clear_glyph_matrix (w->desired_matrix);
13780 return -1;
13781 }
13782 }
13783
13784 /* Scroll the display. Do it before changing the current matrix so
13785 that xterm.c doesn't get confused about where the cursor glyph is
13786 found. */
13787 if (dy && run.height)
13788 {
13789 update_begin (f);
13790
13791 if (FRAME_WINDOW_P (f))
13792 {
13793 rif->update_window_begin_hook (w);
13794 rif->clear_window_mouse_face (w);
13795 rif->scroll_run_hook (w, &run);
13796 rif->update_window_end_hook (w, 0, 0);
13797 }
13798 else
13799 {
13800 /* Terminal frame. In this case, dvpos gives the number of
13801 lines to scroll by; dvpos < 0 means scroll up. */
13802 int first_unchanged_at_end_vpos
13803 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13804 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13805 int end = (WINDOW_TOP_EDGE_LINE (w)
13806 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13807 + window_internal_height (w));
13808
13809 /* Perform the operation on the screen. */
13810 if (dvpos > 0)
13811 {
13812 /* Scroll last_unchanged_at_beg_row to the end of the
13813 window down dvpos lines. */
13814 set_terminal_window (end);
13815
13816 /* On dumb terminals delete dvpos lines at the end
13817 before inserting dvpos empty lines. */
13818 if (!scroll_region_ok)
13819 ins_del_lines (end - dvpos, -dvpos);
13820
13821 /* Insert dvpos empty lines in front of
13822 last_unchanged_at_beg_row. */
13823 ins_del_lines (from, dvpos);
13824 }
13825 else if (dvpos < 0)
13826 {
13827 /* Scroll up last_unchanged_at_beg_vpos to the end of
13828 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13829 set_terminal_window (end);
13830
13831 /* Delete dvpos lines in front of
13832 last_unchanged_at_beg_vpos. ins_del_lines will set
13833 the cursor to the given vpos and emit |dvpos| delete
13834 line sequences. */
13835 ins_del_lines (from + dvpos, dvpos);
13836
13837 /* On a dumb terminal insert dvpos empty lines at the
13838 end. */
13839 if (!scroll_region_ok)
13840 ins_del_lines (end + dvpos, -dvpos);
13841 }
13842
13843 set_terminal_window (0);
13844 }
13845
13846 update_end (f);
13847 }
13848
13849 /* Shift reused rows of the current matrix to the right position.
13850 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13851 text. */
13852 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13853 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13854 if (dvpos < 0)
13855 {
13856 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13857 bottom_vpos, dvpos);
13858 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13859 bottom_vpos, 0);
13860 }
13861 else if (dvpos > 0)
13862 {
13863 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13864 bottom_vpos, dvpos);
13865 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13866 first_unchanged_at_end_vpos + dvpos, 0);
13867 }
13868
13869 /* For frame-based redisplay, make sure that current frame and window
13870 matrix are in sync with respect to glyph memory. */
13871 if (!FRAME_WINDOW_P (f))
13872 sync_frame_with_window_matrix_rows (w);
13873
13874 /* Adjust buffer positions in reused rows. */
13875 if (delta)
13876 increment_matrix_positions (current_matrix,
13877 first_unchanged_at_end_vpos + dvpos,
13878 bottom_vpos, delta, delta_bytes);
13879
13880 /* Adjust Y positions. */
13881 if (dy)
13882 shift_glyph_matrix (w, current_matrix,
13883 first_unchanged_at_end_vpos + dvpos,
13884 bottom_vpos, dy);
13885
13886 if (first_unchanged_at_end_row)
13887 {
13888 first_unchanged_at_end_row += dvpos;
13889 if (first_unchanged_at_end_row->y >= it.last_visible_y
13890 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
13891 first_unchanged_at_end_row = NULL;
13892 }
13893
13894 /* If scrolling up, there may be some lines to display at the end of
13895 the window. */
13896 last_text_row_at_end = NULL;
13897 if (dy < 0)
13898 {
13899 /* Scrolling up can leave for example a partially visible line
13900 at the end of the window to be redisplayed. */
13901 /* Set last_row to the glyph row in the current matrix where the
13902 window end line is found. It has been moved up or down in
13903 the matrix by dvpos. */
13904 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13905 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13906
13907 /* If last_row is the window end line, it should display text. */
13908 xassert (last_row->displays_text_p);
13909
13910 /* If window end line was partially visible before, begin
13911 displaying at that line. Otherwise begin displaying with the
13912 line following it. */
13913 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13914 {
13915 init_to_row_start (&it, w, last_row);
13916 it.vpos = last_vpos;
13917 it.current_y = last_row->y;
13918 }
13919 else
13920 {
13921 init_to_row_end (&it, w, last_row);
13922 it.vpos = 1 + last_vpos;
13923 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13924 ++last_row;
13925 }
13926
13927 /* We may start in a continuation line. If so, we have to
13928 get the right continuation_lines_width and current_x. */
13929 it.continuation_lines_width = last_row->continuation_lines_width;
13930 it.hpos = it.current_x = 0;
13931
13932 /* Display the rest of the lines at the window end. */
13933 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13934 while (it.current_y < it.last_visible_y
13935 && !fonts_changed_p)
13936 {
13937 /* Is it always sure that the display agrees with lines in
13938 the current matrix? I don't think so, so we mark rows
13939 displayed invalid in the current matrix by setting their
13940 enabled_p flag to zero. */
13941 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13942 if (display_line (&it))
13943 last_text_row_at_end = it.glyph_row - 1;
13944 }
13945 }
13946
13947 /* Update window_end_pos and window_end_vpos. */
13948 if (first_unchanged_at_end_row
13949 && !last_text_row_at_end)
13950 {
13951 /* Window end line if one of the preserved rows from the current
13952 matrix. Set row to the last row displaying text in current
13953 matrix starting at first_unchanged_at_end_row, after
13954 scrolling. */
13955 xassert (first_unchanged_at_end_row->displays_text_p);
13956 row = find_last_row_displaying_text (w->current_matrix, &it,
13957 first_unchanged_at_end_row);
13958 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13959
13960 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13961 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13962 w->window_end_vpos
13963 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13964 xassert (w->window_end_bytepos >= 0);
13965 IF_DEBUG (debug_method_add (w, "A"));
13966 }
13967 else if (last_text_row_at_end)
13968 {
13969 w->window_end_pos
13970 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13971 w->window_end_bytepos
13972 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13973 w->window_end_vpos
13974 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13975 xassert (w->window_end_bytepos >= 0);
13976 IF_DEBUG (debug_method_add (w, "B"));
13977 }
13978 else if (last_text_row)
13979 {
13980 /* We have displayed either to the end of the window or at the
13981 end of the window, i.e. the last row with text is to be found
13982 in the desired matrix. */
13983 w->window_end_pos
13984 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13985 w->window_end_bytepos
13986 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13987 w->window_end_vpos
13988 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13989 xassert (w->window_end_bytepos >= 0);
13990 }
13991 else if (first_unchanged_at_end_row == NULL
13992 && last_text_row == NULL
13993 && last_text_row_at_end == NULL)
13994 {
13995 /* Displayed to end of window, but no line containing text was
13996 displayed. Lines were deleted at the end of the window. */
13997 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13998 int vpos = XFASTINT (w->window_end_vpos);
13999 struct glyph_row *current_row = current_matrix->rows + vpos;
14000 struct glyph_row *desired_row = desired_matrix->rows + vpos;
14001
14002 for (row = NULL;
14003 row == NULL && vpos >= first_vpos;
14004 --vpos, --current_row, --desired_row)
14005 {
14006 if (desired_row->enabled_p)
14007 {
14008 if (desired_row->displays_text_p)
14009 row = desired_row;
14010 }
14011 else if (current_row->displays_text_p)
14012 row = current_row;
14013 }
14014
14015 xassert (row != NULL);
14016 w->window_end_vpos = make_number (vpos + 1);
14017 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14018 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14019 xassert (w->window_end_bytepos >= 0);
14020 IF_DEBUG (debug_method_add (w, "C"));
14021 }
14022 else
14023 abort ();
14024
14025 #if 0 /* This leads to problems, for instance when the cursor is
14026 at ZV, and the cursor line displays no text. */
14027 /* Disable rows below what's displayed in the window. This makes
14028 debugging easier. */
14029 enable_glyph_matrix_rows (current_matrix,
14030 XFASTINT (w->window_end_vpos) + 1,
14031 bottom_vpos, 0);
14032 #endif
14033
14034 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
14035 debug_end_vpos = XFASTINT (w->window_end_vpos));
14036
14037 /* Record that display has not been completed. */
14038 w->window_end_valid = Qnil;
14039 w->desired_matrix->no_scrolling_p = 1;
14040 return 3;
14041
14042 #undef GIVE_UP
14043 }
14044
14045
14046 \f
14047 /***********************************************************************
14048 More debugging support
14049 ***********************************************************************/
14050
14051 #if GLYPH_DEBUG
14052
14053 void dump_glyph_row P_ ((struct glyph_row *, int, int));
14054 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
14055 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
14056
14057
14058 /* Dump the contents of glyph matrix MATRIX on stderr.
14059
14060 GLYPHS 0 means don't show glyph contents.
14061 GLYPHS 1 means show glyphs in short form
14062 GLYPHS > 1 means show glyphs in long form. */
14063
14064 void
14065 dump_glyph_matrix (matrix, glyphs)
14066 struct glyph_matrix *matrix;
14067 int glyphs;
14068 {
14069 int i;
14070 for (i = 0; i < matrix->nrows; ++i)
14071 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
14072 }
14073
14074
14075 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14076 the glyph row and area where the glyph comes from. */
14077
14078 void
14079 dump_glyph (row, glyph, area)
14080 struct glyph_row *row;
14081 struct glyph *glyph;
14082 int area;
14083 {
14084 if (glyph->type == CHAR_GLYPH)
14085 {
14086 fprintf (stderr,
14087 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14088 glyph - row->glyphs[TEXT_AREA],
14089 'C',
14090 glyph->charpos,
14091 (BUFFERP (glyph->object)
14092 ? 'B'
14093 : (STRINGP (glyph->object)
14094 ? 'S'
14095 : '-')),
14096 glyph->pixel_width,
14097 glyph->u.ch,
14098 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
14099 ? glyph->u.ch
14100 : '.'),
14101 glyph->face_id,
14102 glyph->left_box_line_p,
14103 glyph->right_box_line_p);
14104 }
14105 else if (glyph->type == STRETCH_GLYPH)
14106 {
14107 fprintf (stderr,
14108 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14109 glyph - row->glyphs[TEXT_AREA],
14110 'S',
14111 glyph->charpos,
14112 (BUFFERP (glyph->object)
14113 ? 'B'
14114 : (STRINGP (glyph->object)
14115 ? 'S'
14116 : '-')),
14117 glyph->pixel_width,
14118 0,
14119 '.',
14120 glyph->face_id,
14121 glyph->left_box_line_p,
14122 glyph->right_box_line_p);
14123 }
14124 else if (glyph->type == IMAGE_GLYPH)
14125 {
14126 fprintf (stderr,
14127 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14128 glyph - row->glyphs[TEXT_AREA],
14129 'I',
14130 glyph->charpos,
14131 (BUFFERP (glyph->object)
14132 ? 'B'
14133 : (STRINGP (glyph->object)
14134 ? 'S'
14135 : '-')),
14136 glyph->pixel_width,
14137 glyph->u.img_id,
14138 '.',
14139 glyph->face_id,
14140 glyph->left_box_line_p,
14141 glyph->right_box_line_p);
14142 }
14143 }
14144
14145
14146 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14147 GLYPHS 0 means don't show glyph contents.
14148 GLYPHS 1 means show glyphs in short form
14149 GLYPHS > 1 means show glyphs in long form. */
14150
14151 void
14152 dump_glyph_row (row, vpos, glyphs)
14153 struct glyph_row *row;
14154 int vpos, glyphs;
14155 {
14156 if (glyphs != 1)
14157 {
14158 fprintf (stderr, "Row Start End Used oEI><O\\CTZFesm X Y W H V A P\n");
14159 fprintf (stderr, "=======================================================================\n");
14160
14161 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d%1.1d\
14162 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14163 vpos,
14164 MATRIX_ROW_START_CHARPOS (row),
14165 MATRIX_ROW_END_CHARPOS (row),
14166 row->used[TEXT_AREA],
14167 row->contains_overlapping_glyphs_p,
14168 row->enabled_p,
14169 row->truncated_on_left_p,
14170 row->truncated_on_right_p,
14171 row->overlay_arrow_p,
14172 row->continued_p,
14173 MATRIX_ROW_CONTINUATION_LINE_P (row),
14174 row->displays_text_p,
14175 row->ends_at_zv_p,
14176 row->fill_line_p,
14177 row->ends_in_middle_of_char_p,
14178 row->starts_in_middle_of_char_p,
14179 row->mouse_face_p,
14180 row->x,
14181 row->y,
14182 row->pixel_width,
14183 row->height,
14184 row->visible_height,
14185 row->ascent,
14186 row->phys_ascent);
14187 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14188 row->end.overlay_string_index,
14189 row->continuation_lines_width);
14190 fprintf (stderr, "%9d %5d\n",
14191 CHARPOS (row->start.string_pos),
14192 CHARPOS (row->end.string_pos));
14193 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14194 row->end.dpvec_index);
14195 }
14196
14197 if (glyphs > 1)
14198 {
14199 int area;
14200
14201 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14202 {
14203 struct glyph *glyph = row->glyphs[area];
14204 struct glyph *glyph_end = glyph + row->used[area];
14205
14206 /* Glyph for a line end in text. */
14207 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14208 ++glyph_end;
14209
14210 if (glyph < glyph_end)
14211 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14212
14213 for (; glyph < glyph_end; ++glyph)
14214 dump_glyph (row, glyph, area);
14215 }
14216 }
14217 else if (glyphs == 1)
14218 {
14219 int area;
14220
14221 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14222 {
14223 char *s = (char *) alloca (row->used[area] + 1);
14224 int i;
14225
14226 for (i = 0; i < row->used[area]; ++i)
14227 {
14228 struct glyph *glyph = row->glyphs[area] + i;
14229 if (glyph->type == CHAR_GLYPH
14230 && glyph->u.ch < 0x80
14231 && glyph->u.ch >= ' ')
14232 s[i] = glyph->u.ch;
14233 else
14234 s[i] = '.';
14235 }
14236
14237 s[i] = '\0';
14238 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14239 }
14240 }
14241 }
14242
14243
14244 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14245 Sdump_glyph_matrix, 0, 1, "p",
14246 doc: /* Dump the current matrix of the selected window to stderr.
14247 Shows contents of glyph row structures. With non-nil
14248 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14249 glyphs in short form, otherwise show glyphs in long form. */)
14250 (glyphs)
14251 Lisp_Object glyphs;
14252 {
14253 struct window *w = XWINDOW (selected_window);
14254 struct buffer *buffer = XBUFFER (w->buffer);
14255
14256 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14257 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14258 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14259 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14260 fprintf (stderr, "=============================================\n");
14261 dump_glyph_matrix (w->current_matrix,
14262 NILP (glyphs) ? 0 : XINT (glyphs));
14263 return Qnil;
14264 }
14265
14266
14267 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14268 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14269 ()
14270 {
14271 struct frame *f = XFRAME (selected_frame);
14272 dump_glyph_matrix (f->current_matrix, 1);
14273 return Qnil;
14274 }
14275
14276
14277 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14278 doc: /* Dump glyph row ROW to stderr.
14279 GLYPH 0 means don't dump glyphs.
14280 GLYPH 1 means dump glyphs in short form.
14281 GLYPH > 1 or omitted means dump glyphs in long form. */)
14282 (row, glyphs)
14283 Lisp_Object row, glyphs;
14284 {
14285 struct glyph_matrix *matrix;
14286 int vpos;
14287
14288 CHECK_NUMBER (row);
14289 matrix = XWINDOW (selected_window)->current_matrix;
14290 vpos = XINT (row);
14291 if (vpos >= 0 && vpos < matrix->nrows)
14292 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14293 vpos,
14294 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14295 return Qnil;
14296 }
14297
14298
14299 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14300 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14301 GLYPH 0 means don't dump glyphs.
14302 GLYPH 1 means dump glyphs in short form.
14303 GLYPH > 1 or omitted means dump glyphs in long form. */)
14304 (row, glyphs)
14305 Lisp_Object row, glyphs;
14306 {
14307 struct frame *sf = SELECTED_FRAME ();
14308 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14309 int vpos;
14310
14311 CHECK_NUMBER (row);
14312 vpos = XINT (row);
14313 if (vpos >= 0 && vpos < m->nrows)
14314 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14315 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14316 return Qnil;
14317 }
14318
14319
14320 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14321 doc: /* Toggle tracing of redisplay.
14322 With ARG, turn tracing on if and only if ARG is positive. */)
14323 (arg)
14324 Lisp_Object arg;
14325 {
14326 if (NILP (arg))
14327 trace_redisplay_p = !trace_redisplay_p;
14328 else
14329 {
14330 arg = Fprefix_numeric_value (arg);
14331 trace_redisplay_p = XINT (arg) > 0;
14332 }
14333
14334 return Qnil;
14335 }
14336
14337
14338 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14339 doc: /* Like `format', but print result to stderr.
14340 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14341 (nargs, args)
14342 int nargs;
14343 Lisp_Object *args;
14344 {
14345 Lisp_Object s = Fformat (nargs, args);
14346 fprintf (stderr, "%s", SDATA (s));
14347 return Qnil;
14348 }
14349
14350 #endif /* GLYPH_DEBUG */
14351
14352
14353 \f
14354 /***********************************************************************
14355 Building Desired Matrix Rows
14356 ***********************************************************************/
14357
14358 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14359 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14360
14361 static struct glyph_row *
14362 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14363 struct window *w;
14364 Lisp_Object overlay_arrow_string;
14365 {
14366 struct frame *f = XFRAME (WINDOW_FRAME (w));
14367 struct buffer *buffer = XBUFFER (w->buffer);
14368 struct buffer *old = current_buffer;
14369 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14370 int arrow_len = SCHARS (overlay_arrow_string);
14371 const unsigned char *arrow_end = arrow_string + arrow_len;
14372 const unsigned char *p;
14373 struct it it;
14374 int multibyte_p;
14375 int n_glyphs_before;
14376
14377 set_buffer_temp (buffer);
14378 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14379 it.glyph_row->used[TEXT_AREA] = 0;
14380 SET_TEXT_POS (it.position, 0, 0);
14381
14382 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14383 p = arrow_string;
14384 while (p < arrow_end)
14385 {
14386 Lisp_Object face, ilisp;
14387
14388 /* Get the next character. */
14389 if (multibyte_p)
14390 it.c = string_char_and_length (p, arrow_len, &it.len);
14391 else
14392 it.c = *p, it.len = 1;
14393 p += it.len;
14394
14395 /* Get its face. */
14396 ilisp = make_number (p - arrow_string);
14397 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14398 it.face_id = compute_char_face (f, it.c, face);
14399
14400 /* Compute its width, get its glyphs. */
14401 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14402 SET_TEXT_POS (it.position, -1, -1);
14403 PRODUCE_GLYPHS (&it);
14404
14405 /* If this character doesn't fit any more in the line, we have
14406 to remove some glyphs. */
14407 if (it.current_x > it.last_visible_x)
14408 {
14409 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14410 break;
14411 }
14412 }
14413
14414 set_buffer_temp (old);
14415 return it.glyph_row;
14416 }
14417
14418
14419 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14420 glyphs are only inserted for terminal frames since we can't really
14421 win with truncation glyphs when partially visible glyphs are
14422 involved. Which glyphs to insert is determined by
14423 produce_special_glyphs. */
14424
14425 static void
14426 insert_left_trunc_glyphs (it)
14427 struct it *it;
14428 {
14429 struct it truncate_it;
14430 struct glyph *from, *end, *to, *toend;
14431
14432 xassert (!FRAME_WINDOW_P (it->f));
14433
14434 /* Get the truncation glyphs. */
14435 truncate_it = *it;
14436 truncate_it.current_x = 0;
14437 truncate_it.face_id = DEFAULT_FACE_ID;
14438 truncate_it.glyph_row = &scratch_glyph_row;
14439 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14440 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14441 truncate_it.object = make_number (0);
14442 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14443
14444 /* Overwrite glyphs from IT with truncation glyphs. */
14445 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14446 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14447 to = it->glyph_row->glyphs[TEXT_AREA];
14448 toend = to + it->glyph_row->used[TEXT_AREA];
14449
14450 while (from < end)
14451 *to++ = *from++;
14452
14453 /* There may be padding glyphs left over. Overwrite them too. */
14454 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14455 {
14456 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14457 while (from < end)
14458 *to++ = *from++;
14459 }
14460
14461 if (to > toend)
14462 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14463 }
14464
14465
14466 /* Compute the pixel height and width of IT->glyph_row.
14467
14468 Most of the time, ascent and height of a display line will be equal
14469 to the max_ascent and max_height values of the display iterator
14470 structure. This is not the case if
14471
14472 1. We hit ZV without displaying anything. In this case, max_ascent
14473 and max_height will be zero.
14474
14475 2. We have some glyphs that don't contribute to the line height.
14476 (The glyph row flag contributes_to_line_height_p is for future
14477 pixmap extensions).
14478
14479 The first case is easily covered by using default values because in
14480 these cases, the line height does not really matter, except that it
14481 must not be zero. */
14482
14483 static void
14484 compute_line_metrics (it)
14485 struct it *it;
14486 {
14487 struct glyph_row *row = it->glyph_row;
14488 int area, i;
14489
14490 if (FRAME_WINDOW_P (it->f))
14491 {
14492 int i, min_y, max_y;
14493
14494 /* The line may consist of one space only, that was added to
14495 place the cursor on it. If so, the row's height hasn't been
14496 computed yet. */
14497 if (row->height == 0)
14498 {
14499 if (it->max_ascent + it->max_descent == 0)
14500 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14501 row->ascent = it->max_ascent;
14502 row->height = it->max_ascent + it->max_descent;
14503 row->phys_ascent = it->max_phys_ascent;
14504 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14505 row->extra_line_spacing = it->max_extra_line_spacing;
14506 }
14507
14508 /* Compute the width of this line. */
14509 row->pixel_width = row->x;
14510 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14511 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14512
14513 xassert (row->pixel_width >= 0);
14514 xassert (row->ascent >= 0 && row->height > 0);
14515
14516 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14517 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14518
14519 /* If first line's physical ascent is larger than its logical
14520 ascent, use the physical ascent, and make the row taller.
14521 This makes accented characters fully visible. */
14522 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14523 && row->phys_ascent > row->ascent)
14524 {
14525 row->height += row->phys_ascent - row->ascent;
14526 row->ascent = row->phys_ascent;
14527 }
14528
14529 /* Compute how much of the line is visible. */
14530 row->visible_height = row->height;
14531
14532 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14533 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14534
14535 if (row->y < min_y)
14536 row->visible_height -= min_y - row->y;
14537 if (row->y + row->height > max_y)
14538 row->visible_height -= row->y + row->height - max_y;
14539 }
14540 else
14541 {
14542 row->pixel_width = row->used[TEXT_AREA];
14543 if (row->continued_p)
14544 row->pixel_width -= it->continuation_pixel_width;
14545 else if (row->truncated_on_right_p)
14546 row->pixel_width -= it->truncation_pixel_width;
14547 row->ascent = row->phys_ascent = 0;
14548 row->height = row->phys_height = row->visible_height = 1;
14549 row->extra_line_spacing = 0;
14550 }
14551
14552 /* Compute a hash code for this row. */
14553 row->hash = 0;
14554 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14555 for (i = 0; i < row->used[area]; ++i)
14556 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14557 + row->glyphs[area][i].u.val
14558 + row->glyphs[area][i].face_id
14559 + row->glyphs[area][i].padding_p
14560 + (row->glyphs[area][i].type << 2));
14561
14562 it->max_ascent = it->max_descent = 0;
14563 it->max_phys_ascent = it->max_phys_descent = 0;
14564 }
14565
14566
14567 /* Append one space to the glyph row of iterator IT if doing a
14568 window-based redisplay. The space has the same face as
14569 IT->face_id. Value is non-zero if a space was added.
14570
14571 This function is called to make sure that there is always one glyph
14572 at the end of a glyph row that the cursor can be set on under
14573 window-systems. (If there weren't such a glyph we would not know
14574 how wide and tall a box cursor should be displayed).
14575
14576 At the same time this space let's a nicely handle clearing to the
14577 end of the line if the row ends in italic text. */
14578
14579 static int
14580 append_space_for_newline (it, default_face_p)
14581 struct it *it;
14582 int default_face_p;
14583 {
14584 if (FRAME_WINDOW_P (it->f))
14585 {
14586 int n = it->glyph_row->used[TEXT_AREA];
14587
14588 if (it->glyph_row->glyphs[TEXT_AREA] + n
14589 < it->glyph_row->glyphs[1 + TEXT_AREA])
14590 {
14591 /* Save some values that must not be changed.
14592 Must save IT->c and IT->len because otherwise
14593 ITERATOR_AT_END_P wouldn't work anymore after
14594 append_space_for_newline has been called. */
14595 enum display_element_type saved_what = it->what;
14596 int saved_c = it->c, saved_len = it->len;
14597 int saved_x = it->current_x;
14598 int saved_face_id = it->face_id;
14599 struct text_pos saved_pos;
14600 Lisp_Object saved_object;
14601 struct face *face;
14602
14603 saved_object = it->object;
14604 saved_pos = it->position;
14605
14606 it->what = IT_CHARACTER;
14607 bzero (&it->position, sizeof it->position);
14608 it->object = make_number (0);
14609 it->c = ' ';
14610 it->len = 1;
14611
14612 if (default_face_p)
14613 it->face_id = DEFAULT_FACE_ID;
14614 else if (it->face_before_selective_p)
14615 it->face_id = it->saved_face_id;
14616 face = FACE_FROM_ID (it->f, it->face_id);
14617 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14618
14619 PRODUCE_GLYPHS (it);
14620
14621 it->override_ascent = -1;
14622 it->constrain_row_ascent_descent_p = 0;
14623 it->current_x = saved_x;
14624 it->object = saved_object;
14625 it->position = saved_pos;
14626 it->what = saved_what;
14627 it->face_id = saved_face_id;
14628 it->len = saved_len;
14629 it->c = saved_c;
14630 return 1;
14631 }
14632 }
14633
14634 return 0;
14635 }
14636
14637
14638 /* Extend the face of the last glyph in the text area of IT->glyph_row
14639 to the end of the display line. Called from display_line.
14640 If the glyph row is empty, add a space glyph to it so that we
14641 know the face to draw. Set the glyph row flag fill_line_p. */
14642
14643 static void
14644 extend_face_to_end_of_line (it)
14645 struct it *it;
14646 {
14647 struct face *face;
14648 struct frame *f = it->f;
14649
14650 /* If line is already filled, do nothing. */
14651 if (it->current_x >= it->last_visible_x)
14652 return;
14653
14654 /* Face extension extends the background and box of IT->face_id
14655 to the end of the line. If the background equals the background
14656 of the frame, we don't have to do anything. */
14657 if (it->face_before_selective_p)
14658 face = FACE_FROM_ID (it->f, it->saved_face_id);
14659 else
14660 face = FACE_FROM_ID (f, it->face_id);
14661
14662 if (FRAME_WINDOW_P (f)
14663 && face->box == FACE_NO_BOX
14664 && face->background == FRAME_BACKGROUND_PIXEL (f)
14665 && !face->stipple)
14666 return;
14667
14668 /* Set the glyph row flag indicating that the face of the last glyph
14669 in the text area has to be drawn to the end of the text area. */
14670 it->glyph_row->fill_line_p = 1;
14671
14672 /* If current character of IT is not ASCII, make sure we have the
14673 ASCII face. This will be automatically undone the next time
14674 get_next_display_element returns a multibyte character. Note
14675 that the character will always be single byte in unibyte text. */
14676 if (!SINGLE_BYTE_CHAR_P (it->c))
14677 {
14678 it->face_id = FACE_FOR_CHAR (f, face, 0);
14679 }
14680
14681 if (FRAME_WINDOW_P (f))
14682 {
14683 /* If the row is empty, add a space with the current face of IT,
14684 so that we know which face to draw. */
14685 if (it->glyph_row->used[TEXT_AREA] == 0)
14686 {
14687 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14688 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14689 it->glyph_row->used[TEXT_AREA] = 1;
14690 }
14691 }
14692 else
14693 {
14694 /* Save some values that must not be changed. */
14695 int saved_x = it->current_x;
14696 struct text_pos saved_pos;
14697 Lisp_Object saved_object;
14698 enum display_element_type saved_what = it->what;
14699 int saved_face_id = it->face_id;
14700
14701 saved_object = it->object;
14702 saved_pos = it->position;
14703
14704 it->what = IT_CHARACTER;
14705 bzero (&it->position, sizeof it->position);
14706 it->object = make_number (0);
14707 it->c = ' ';
14708 it->len = 1;
14709 it->face_id = face->id;
14710
14711 PRODUCE_GLYPHS (it);
14712
14713 while (it->current_x <= it->last_visible_x)
14714 PRODUCE_GLYPHS (it);
14715
14716 /* Don't count these blanks really. It would let us insert a left
14717 truncation glyph below and make us set the cursor on them, maybe. */
14718 it->current_x = saved_x;
14719 it->object = saved_object;
14720 it->position = saved_pos;
14721 it->what = saved_what;
14722 it->face_id = saved_face_id;
14723 }
14724 }
14725
14726
14727 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14728 trailing whitespace. */
14729
14730 static int
14731 trailing_whitespace_p (charpos)
14732 int charpos;
14733 {
14734 int bytepos = CHAR_TO_BYTE (charpos);
14735 int c = 0;
14736
14737 while (bytepos < ZV_BYTE
14738 && (c = FETCH_CHAR (bytepos),
14739 c == ' ' || c == '\t'))
14740 ++bytepos;
14741
14742 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14743 {
14744 if (bytepos != PT_BYTE)
14745 return 1;
14746 }
14747 return 0;
14748 }
14749
14750
14751 /* Highlight trailing whitespace, if any, in ROW. */
14752
14753 void
14754 highlight_trailing_whitespace (f, row)
14755 struct frame *f;
14756 struct glyph_row *row;
14757 {
14758 int used = row->used[TEXT_AREA];
14759
14760 if (used)
14761 {
14762 struct glyph *start = row->glyphs[TEXT_AREA];
14763 struct glyph *glyph = start + used - 1;
14764
14765 /* Skip over glyphs inserted to display the cursor at the
14766 end of a line, for extending the face of the last glyph
14767 to the end of the line on terminals, and for truncation
14768 and continuation glyphs. */
14769 while (glyph >= start
14770 && glyph->type == CHAR_GLYPH
14771 && INTEGERP (glyph->object))
14772 --glyph;
14773
14774 /* If last glyph is a space or stretch, and it's trailing
14775 whitespace, set the face of all trailing whitespace glyphs in
14776 IT->glyph_row to `trailing-whitespace'. */
14777 if (glyph >= start
14778 && BUFFERP (glyph->object)
14779 && (glyph->type == STRETCH_GLYPH
14780 || (glyph->type == CHAR_GLYPH
14781 && glyph->u.ch == ' '))
14782 && trailing_whitespace_p (glyph->charpos))
14783 {
14784 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
14785 if (face_id < 0)
14786 return;
14787
14788 while (glyph >= start
14789 && BUFFERP (glyph->object)
14790 && (glyph->type == STRETCH_GLYPH
14791 || (glyph->type == CHAR_GLYPH
14792 && glyph->u.ch == ' ')))
14793 (glyph--)->face_id = face_id;
14794 }
14795 }
14796 }
14797
14798
14799 /* Value is non-zero if glyph row ROW in window W should be
14800 used to hold the cursor. */
14801
14802 static int
14803 cursor_row_p (w, row)
14804 struct window *w;
14805 struct glyph_row *row;
14806 {
14807 int cursor_row_p = 1;
14808
14809 if (PT == MATRIX_ROW_END_CHARPOS (row))
14810 {
14811 /* If the row ends with a newline from a string, we don't want
14812 the cursor there (if the row is continued it doesn't end in a
14813 newline). */
14814 if (CHARPOS (row->end.string_pos) >= 0)
14815 cursor_row_p = row->continued_p;
14816 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14817 {
14818 /* If the row ends in middle of a real character,
14819 and the line is continued, we want the cursor here.
14820 That's because MATRIX_ROW_END_CHARPOS would equal
14821 PT if PT is before the character. */
14822 if (!row->ends_in_ellipsis_p)
14823 cursor_row_p = row->continued_p;
14824 else
14825 /* If the row ends in an ellipsis, then
14826 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
14827 We want that position to be displayed after the ellipsis. */
14828 cursor_row_p = 0;
14829 }
14830 /* If the row ends at ZV, display the cursor at the end of that
14831 row instead of at the start of the row below. */
14832 else if (row->ends_at_zv_p)
14833 cursor_row_p = 1;
14834 else
14835 cursor_row_p = 0;
14836 }
14837
14838 return cursor_row_p;
14839 }
14840
14841
14842 /* Construct the glyph row IT->glyph_row in the desired matrix of
14843 IT->w from text at the current position of IT. See dispextern.h
14844 for an overview of struct it. Value is non-zero if
14845 IT->glyph_row displays text, as opposed to a line displaying ZV
14846 only. */
14847
14848 static int
14849 display_line (it)
14850 struct it *it;
14851 {
14852 struct glyph_row *row = it->glyph_row;
14853 int overlay_arrow_bitmap;
14854 Lisp_Object overlay_arrow_string;
14855
14856 /* We always start displaying at hpos zero even if hscrolled. */
14857 xassert (it->hpos == 0 && it->current_x == 0);
14858
14859 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14860 >= it->w->desired_matrix->nrows)
14861 {
14862 it->w->nrows_scale_factor++;
14863 fonts_changed_p = 1;
14864 return 0;
14865 }
14866
14867 /* Is IT->w showing the region? */
14868 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14869
14870 /* Clear the result glyph row and enable it. */
14871 prepare_desired_row (row);
14872
14873 row->y = it->current_y;
14874 row->start = it->start;
14875 row->continuation_lines_width = it->continuation_lines_width;
14876 row->displays_text_p = 1;
14877 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14878 it->starts_in_middle_of_char_p = 0;
14879
14880 /* Arrange the overlays nicely for our purposes. Usually, we call
14881 display_line on only one line at a time, in which case this
14882 can't really hurt too much, or we call it on lines which appear
14883 one after another in the buffer, in which case all calls to
14884 recenter_overlay_lists but the first will be pretty cheap. */
14885 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14886
14887 /* Move over display elements that are not visible because we are
14888 hscrolled. This may stop at an x-position < IT->first_visible_x
14889 if the first glyph is partially visible or if we hit a line end. */
14890 if (it->current_x < it->first_visible_x)
14891 {
14892 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14893 MOVE_TO_POS | MOVE_TO_X);
14894 }
14895
14896 /* Get the initial row height. This is either the height of the
14897 text hscrolled, if there is any, or zero. */
14898 row->ascent = it->max_ascent;
14899 row->height = it->max_ascent + it->max_descent;
14900 row->phys_ascent = it->max_phys_ascent;
14901 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14902 row->extra_line_spacing = it->max_extra_line_spacing;
14903
14904 /* Loop generating characters. The loop is left with IT on the next
14905 character to display. */
14906 while (1)
14907 {
14908 int n_glyphs_before, hpos_before, x_before;
14909 int x, i, nglyphs;
14910 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14911
14912 /* Retrieve the next thing to display. Value is zero if end of
14913 buffer reached. */
14914 if (!get_next_display_element (it))
14915 {
14916 /* Maybe add a space at the end of this line that is used to
14917 display the cursor there under X. Set the charpos of the
14918 first glyph of blank lines not corresponding to any text
14919 to -1. */
14920 #ifdef HAVE_WINDOW_SYSTEM
14921 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14922 row->exact_window_width_line_p = 1;
14923 else
14924 #endif /* HAVE_WINDOW_SYSTEM */
14925 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14926 || row->used[TEXT_AREA] == 0)
14927 {
14928 row->glyphs[TEXT_AREA]->charpos = -1;
14929 row->displays_text_p = 0;
14930
14931 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14932 && (!MINI_WINDOW_P (it->w)
14933 || (minibuf_level && EQ (it->window, minibuf_window))))
14934 row->indicate_empty_line_p = 1;
14935 }
14936
14937 it->continuation_lines_width = 0;
14938 row->ends_at_zv_p = 1;
14939 break;
14940 }
14941
14942 /* Now, get the metrics of what we want to display. This also
14943 generates glyphs in `row' (which is IT->glyph_row). */
14944 n_glyphs_before = row->used[TEXT_AREA];
14945 x = it->current_x;
14946
14947 /* Remember the line height so far in case the next element doesn't
14948 fit on the line. */
14949 if (!it->truncate_lines_p)
14950 {
14951 ascent = it->max_ascent;
14952 descent = it->max_descent;
14953 phys_ascent = it->max_phys_ascent;
14954 phys_descent = it->max_phys_descent;
14955 }
14956
14957 PRODUCE_GLYPHS (it);
14958
14959 /* If this display element was in marginal areas, continue with
14960 the next one. */
14961 if (it->area != TEXT_AREA)
14962 {
14963 row->ascent = max (row->ascent, it->max_ascent);
14964 row->height = max (row->height, it->max_ascent + it->max_descent);
14965 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14966 row->phys_height = max (row->phys_height,
14967 it->max_phys_ascent + it->max_phys_descent);
14968 row->extra_line_spacing = max (row->extra_line_spacing,
14969 it->max_extra_line_spacing);
14970 set_iterator_to_next (it, 1);
14971 continue;
14972 }
14973
14974 /* Does the display element fit on the line? If we truncate
14975 lines, we should draw past the right edge of the window. If
14976 we don't truncate, we want to stop so that we can display the
14977 continuation glyph before the right margin. If lines are
14978 continued, there are two possible strategies for characters
14979 resulting in more than 1 glyph (e.g. tabs): Display as many
14980 glyphs as possible in this line and leave the rest for the
14981 continuation line, or display the whole element in the next
14982 line. Original redisplay did the former, so we do it also. */
14983 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14984 hpos_before = it->hpos;
14985 x_before = x;
14986
14987 if (/* Not a newline. */
14988 nglyphs > 0
14989 /* Glyphs produced fit entirely in the line. */
14990 && it->current_x < it->last_visible_x)
14991 {
14992 it->hpos += nglyphs;
14993 row->ascent = max (row->ascent, it->max_ascent);
14994 row->height = max (row->height, it->max_ascent + it->max_descent);
14995 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14996 row->phys_height = max (row->phys_height,
14997 it->max_phys_ascent + it->max_phys_descent);
14998 row->extra_line_spacing = max (row->extra_line_spacing,
14999 it->max_extra_line_spacing);
15000 if (it->current_x - it->pixel_width < it->first_visible_x)
15001 row->x = x - it->first_visible_x;
15002 }
15003 else
15004 {
15005 int new_x;
15006 struct glyph *glyph;
15007
15008 for (i = 0; i < nglyphs; ++i, x = new_x)
15009 {
15010 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
15011 new_x = x + glyph->pixel_width;
15012
15013 if (/* Lines are continued. */
15014 !it->truncate_lines_p
15015 && (/* Glyph doesn't fit on the line. */
15016 new_x > it->last_visible_x
15017 /* Or it fits exactly on a window system frame. */
15018 || (new_x == it->last_visible_x
15019 && FRAME_WINDOW_P (it->f))))
15020 {
15021 /* End of a continued line. */
15022
15023 if (it->hpos == 0
15024 || (new_x == it->last_visible_x
15025 && FRAME_WINDOW_P (it->f)))
15026 {
15027 /* Current glyph is the only one on the line or
15028 fits exactly on the line. We must continue
15029 the line because we can't draw the cursor
15030 after the glyph. */
15031 row->continued_p = 1;
15032 it->current_x = new_x;
15033 it->continuation_lines_width += new_x;
15034 ++it->hpos;
15035 if (i == nglyphs - 1)
15036 {
15037 set_iterator_to_next (it, 1);
15038 #ifdef HAVE_WINDOW_SYSTEM
15039 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15040 {
15041 if (!get_next_display_element (it))
15042 {
15043 row->exact_window_width_line_p = 1;
15044 it->continuation_lines_width = 0;
15045 row->continued_p = 0;
15046 row->ends_at_zv_p = 1;
15047 }
15048 else if (ITERATOR_AT_END_OF_LINE_P (it))
15049 {
15050 row->continued_p = 0;
15051 row->exact_window_width_line_p = 1;
15052 }
15053 }
15054 #endif /* HAVE_WINDOW_SYSTEM */
15055 }
15056 }
15057 else if (CHAR_GLYPH_PADDING_P (*glyph)
15058 && !FRAME_WINDOW_P (it->f))
15059 {
15060 /* A padding glyph that doesn't fit on this line.
15061 This means the whole character doesn't fit
15062 on the line. */
15063 row->used[TEXT_AREA] = n_glyphs_before;
15064
15065 /* Fill the rest of the row with continuation
15066 glyphs like in 20.x. */
15067 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
15068 < row->glyphs[1 + TEXT_AREA])
15069 produce_special_glyphs (it, IT_CONTINUATION);
15070
15071 row->continued_p = 1;
15072 it->current_x = x_before;
15073 it->continuation_lines_width += x_before;
15074
15075 /* Restore the height to what it was before the
15076 element not fitting on the line. */
15077 it->max_ascent = ascent;
15078 it->max_descent = descent;
15079 it->max_phys_ascent = phys_ascent;
15080 it->max_phys_descent = phys_descent;
15081 }
15082 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
15083 {
15084 /* A TAB that extends past the right edge of the
15085 window. This produces a single glyph on
15086 window system frames. We leave the glyph in
15087 this row and let it fill the row, but don't
15088 consume the TAB. */
15089 it->continuation_lines_width += it->last_visible_x;
15090 row->ends_in_middle_of_char_p = 1;
15091 row->continued_p = 1;
15092 glyph->pixel_width = it->last_visible_x - x;
15093 it->starts_in_middle_of_char_p = 1;
15094 }
15095 else
15096 {
15097 /* Something other than a TAB that draws past
15098 the right edge of the window. Restore
15099 positions to values before the element. */
15100 row->used[TEXT_AREA] = n_glyphs_before + i;
15101
15102 /* Display continuation glyphs. */
15103 if (!FRAME_WINDOW_P (it->f))
15104 produce_special_glyphs (it, IT_CONTINUATION);
15105 row->continued_p = 1;
15106
15107 it->continuation_lines_width += x;
15108
15109 if (nglyphs > 1 && i > 0)
15110 {
15111 row->ends_in_middle_of_char_p = 1;
15112 it->starts_in_middle_of_char_p = 1;
15113 }
15114
15115 /* Restore the height to what it was before the
15116 element not fitting on the line. */
15117 it->max_ascent = ascent;
15118 it->max_descent = descent;
15119 it->max_phys_ascent = phys_ascent;
15120 it->max_phys_descent = phys_descent;
15121 }
15122
15123 break;
15124 }
15125 else if (new_x > it->first_visible_x)
15126 {
15127 /* Increment number of glyphs actually displayed. */
15128 ++it->hpos;
15129
15130 if (x < it->first_visible_x)
15131 /* Glyph is partially visible, i.e. row starts at
15132 negative X position. */
15133 row->x = x - it->first_visible_x;
15134 }
15135 else
15136 {
15137 /* Glyph is completely off the left margin of the
15138 window. This should not happen because of the
15139 move_it_in_display_line at the start of this
15140 function, unless the text display area of the
15141 window is empty. */
15142 xassert (it->first_visible_x <= it->last_visible_x);
15143 }
15144 }
15145
15146 row->ascent = max (row->ascent, it->max_ascent);
15147 row->height = max (row->height, it->max_ascent + it->max_descent);
15148 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15149 row->phys_height = max (row->phys_height,
15150 it->max_phys_ascent + it->max_phys_descent);
15151 row->extra_line_spacing = max (row->extra_line_spacing,
15152 it->max_extra_line_spacing);
15153
15154 /* End of this display line if row is continued. */
15155 if (row->continued_p || row->ends_at_zv_p)
15156 break;
15157 }
15158
15159 at_end_of_line:
15160 /* Is this a line end? If yes, we're also done, after making
15161 sure that a non-default face is extended up to the right
15162 margin of the window. */
15163 if (ITERATOR_AT_END_OF_LINE_P (it))
15164 {
15165 int used_before = row->used[TEXT_AREA];
15166
15167 row->ends_in_newline_from_string_p = STRINGP (it->object);
15168
15169 #ifdef HAVE_WINDOW_SYSTEM
15170 /* Add a space at the end of the line that is used to
15171 display the cursor there. */
15172 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15173 append_space_for_newline (it, 0);
15174 #endif /* HAVE_WINDOW_SYSTEM */
15175
15176 /* Extend the face to the end of the line. */
15177 extend_face_to_end_of_line (it);
15178
15179 /* Make sure we have the position. */
15180 if (used_before == 0)
15181 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15182
15183 /* Consume the line end. This skips over invisible lines. */
15184 set_iterator_to_next (it, 1);
15185 it->continuation_lines_width = 0;
15186 break;
15187 }
15188
15189 /* Proceed with next display element. Note that this skips
15190 over lines invisible because of selective display. */
15191 set_iterator_to_next (it, 1);
15192
15193 /* If we truncate lines, we are done when the last displayed
15194 glyphs reach past the right margin of the window. */
15195 if (it->truncate_lines_p
15196 && (FRAME_WINDOW_P (it->f)
15197 ? (it->current_x >= it->last_visible_x)
15198 : (it->current_x > it->last_visible_x)))
15199 {
15200 /* Maybe add truncation glyphs. */
15201 if (!FRAME_WINDOW_P (it->f))
15202 {
15203 int i, n;
15204
15205 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15206 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15207 break;
15208
15209 for (n = row->used[TEXT_AREA]; i < n; ++i)
15210 {
15211 row->used[TEXT_AREA] = i;
15212 produce_special_glyphs (it, IT_TRUNCATION);
15213 }
15214 }
15215 #ifdef HAVE_WINDOW_SYSTEM
15216 else
15217 {
15218 /* Don't truncate if we can overflow newline into fringe. */
15219 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15220 {
15221 if (!get_next_display_element (it))
15222 {
15223 it->continuation_lines_width = 0;
15224 row->ends_at_zv_p = 1;
15225 row->exact_window_width_line_p = 1;
15226 break;
15227 }
15228 if (ITERATOR_AT_END_OF_LINE_P (it))
15229 {
15230 row->exact_window_width_line_p = 1;
15231 goto at_end_of_line;
15232 }
15233 }
15234 }
15235 #endif /* HAVE_WINDOW_SYSTEM */
15236
15237 row->truncated_on_right_p = 1;
15238 it->continuation_lines_width = 0;
15239 reseat_at_next_visible_line_start (it, 0);
15240 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15241 it->hpos = hpos_before;
15242 it->current_x = x_before;
15243 break;
15244 }
15245 }
15246
15247 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15248 at the left window margin. */
15249 if (it->first_visible_x
15250 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15251 {
15252 if (!FRAME_WINDOW_P (it->f))
15253 insert_left_trunc_glyphs (it);
15254 row->truncated_on_left_p = 1;
15255 }
15256
15257 /* If the start of this line is the overlay arrow-position, then
15258 mark this glyph row as the one containing the overlay arrow.
15259 This is clearly a mess with variable size fonts. It would be
15260 better to let it be displayed like cursors under X. */
15261 if (! overlay_arrow_seen
15262 && (overlay_arrow_string
15263 = overlay_arrow_at_row (it, row, &overlay_arrow_bitmap),
15264 !NILP (overlay_arrow_string)))
15265 {
15266 /* Overlay arrow in window redisplay is a fringe bitmap. */
15267 if (STRINGP (overlay_arrow_string))
15268 {
15269 struct glyph_row *arrow_row
15270 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15271 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15272 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15273 struct glyph *p = row->glyphs[TEXT_AREA];
15274 struct glyph *p2, *end;
15275
15276 /* Copy the arrow glyphs. */
15277 while (glyph < arrow_end)
15278 *p++ = *glyph++;
15279
15280 /* Throw away padding glyphs. */
15281 p2 = p;
15282 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15283 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15284 ++p2;
15285 if (p2 > p)
15286 {
15287 while (p2 < end)
15288 *p++ = *p2++;
15289 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15290 }
15291 }
15292 else
15293 {
15294 it->w->overlay_arrow_bitmap = overlay_arrow_bitmap;
15295 row->overlay_arrow_p = 1;
15296 }
15297 overlay_arrow_seen = 1;
15298 }
15299
15300 /* Compute pixel dimensions of this line. */
15301 compute_line_metrics (it);
15302
15303 /* Remember the position at which this line ends. */
15304 row->end = it->current;
15305
15306 /* Record whether this row ends inside an ellipsis. */
15307 row->ends_in_ellipsis_p
15308 = (it->method == GET_FROM_DISPLAY_VECTOR
15309 && it->ellipsis_p);
15310
15311 /* Save fringe bitmaps in this row. */
15312 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15313 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15314 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15315 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15316
15317 it->left_user_fringe_bitmap = 0;
15318 it->left_user_fringe_face_id = 0;
15319 it->right_user_fringe_bitmap = 0;
15320 it->right_user_fringe_face_id = 0;
15321
15322 /* Maybe set the cursor. */
15323 if (it->w->cursor.vpos < 0
15324 && PT >= MATRIX_ROW_START_CHARPOS (row)
15325 && PT <= MATRIX_ROW_END_CHARPOS (row)
15326 && cursor_row_p (it->w, row))
15327 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15328
15329 /* Highlight trailing whitespace. */
15330 if (!NILP (Vshow_trailing_whitespace))
15331 highlight_trailing_whitespace (it->f, it->glyph_row);
15332
15333 /* Prepare for the next line. This line starts horizontally at (X
15334 HPOS) = (0 0). Vertical positions are incremented. As a
15335 convenience for the caller, IT->glyph_row is set to the next
15336 row to be used. */
15337 it->current_x = it->hpos = 0;
15338 it->current_y += row->height;
15339 ++it->vpos;
15340 ++it->glyph_row;
15341 it->start = it->current;
15342 return row->displays_text_p;
15343 }
15344
15345
15346 \f
15347 /***********************************************************************
15348 Menu Bar
15349 ***********************************************************************/
15350
15351 /* Redisplay the menu bar in the frame for window W.
15352
15353 The menu bar of X frames that don't have X toolkit support is
15354 displayed in a special window W->frame->menu_bar_window.
15355
15356 The menu bar of terminal frames is treated specially as far as
15357 glyph matrices are concerned. Menu bar lines are not part of
15358 windows, so the update is done directly on the frame matrix rows
15359 for the menu bar. */
15360
15361 static void
15362 display_menu_bar (w)
15363 struct window *w;
15364 {
15365 struct frame *f = XFRAME (WINDOW_FRAME (w));
15366 struct it it;
15367 Lisp_Object items;
15368 int i;
15369
15370 /* Don't do all this for graphical frames. */
15371 #ifdef HAVE_NTGUI
15372 if (!NILP (Vwindow_system))
15373 return;
15374 #endif
15375 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15376 if (FRAME_X_P (f))
15377 return;
15378 #endif
15379 #ifdef MAC_OS
15380 if (FRAME_MAC_P (f))
15381 return;
15382 #endif
15383
15384 #ifdef USE_X_TOOLKIT
15385 xassert (!FRAME_WINDOW_P (f));
15386 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15387 it.first_visible_x = 0;
15388 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15389 #else /* not USE_X_TOOLKIT */
15390 if (FRAME_WINDOW_P (f))
15391 {
15392 /* Menu bar lines are displayed in the desired matrix of the
15393 dummy window menu_bar_window. */
15394 struct window *menu_w;
15395 xassert (WINDOWP (f->menu_bar_window));
15396 menu_w = XWINDOW (f->menu_bar_window);
15397 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15398 MENU_FACE_ID);
15399 it.first_visible_x = 0;
15400 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15401 }
15402 else
15403 {
15404 /* This is a TTY frame, i.e. character hpos/vpos are used as
15405 pixel x/y. */
15406 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15407 MENU_FACE_ID);
15408 it.first_visible_x = 0;
15409 it.last_visible_x = FRAME_COLS (f);
15410 }
15411 #endif /* not USE_X_TOOLKIT */
15412
15413 if (! mode_line_inverse_video)
15414 /* Force the menu-bar to be displayed in the default face. */
15415 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15416
15417 /* Clear all rows of the menu bar. */
15418 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15419 {
15420 struct glyph_row *row = it.glyph_row + i;
15421 clear_glyph_row (row);
15422 row->enabled_p = 1;
15423 row->full_width_p = 1;
15424 }
15425
15426 /* Display all items of the menu bar. */
15427 items = FRAME_MENU_BAR_ITEMS (it.f);
15428 for (i = 0; i < XVECTOR (items)->size; i += 4)
15429 {
15430 Lisp_Object string;
15431
15432 /* Stop at nil string. */
15433 string = AREF (items, i + 1);
15434 if (NILP (string))
15435 break;
15436
15437 /* Remember where item was displayed. */
15438 AREF (items, i + 3) = make_number (it.hpos);
15439
15440 /* Display the item, pad with one space. */
15441 if (it.current_x < it.last_visible_x)
15442 display_string (NULL, string, Qnil, 0, 0, &it,
15443 SCHARS (string) + 1, 0, 0, -1);
15444 }
15445
15446 /* Fill out the line with spaces. */
15447 if (it.current_x < it.last_visible_x)
15448 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15449
15450 /* Compute the total height of the lines. */
15451 compute_line_metrics (&it);
15452 }
15453
15454
15455 \f
15456 /***********************************************************************
15457 Mode Line
15458 ***********************************************************************/
15459
15460 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15461 FORCE is non-zero, redisplay mode lines unconditionally.
15462 Otherwise, redisplay only mode lines that are garbaged. Value is
15463 the number of windows whose mode lines were redisplayed. */
15464
15465 static int
15466 redisplay_mode_lines (window, force)
15467 Lisp_Object window;
15468 int force;
15469 {
15470 int nwindows = 0;
15471
15472 while (!NILP (window))
15473 {
15474 struct window *w = XWINDOW (window);
15475
15476 if (WINDOWP (w->hchild))
15477 nwindows += redisplay_mode_lines (w->hchild, force);
15478 else if (WINDOWP (w->vchild))
15479 nwindows += redisplay_mode_lines (w->vchild, force);
15480 else if (force
15481 || FRAME_GARBAGED_P (XFRAME (w->frame))
15482 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15483 {
15484 struct text_pos lpoint;
15485 struct buffer *old = current_buffer;
15486
15487 /* Set the window's buffer for the mode line display. */
15488 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15489 set_buffer_internal_1 (XBUFFER (w->buffer));
15490
15491 /* Point refers normally to the selected window. For any
15492 other window, set up appropriate value. */
15493 if (!EQ (window, selected_window))
15494 {
15495 struct text_pos pt;
15496
15497 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15498 if (CHARPOS (pt) < BEGV)
15499 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15500 else if (CHARPOS (pt) > (ZV - 1))
15501 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15502 else
15503 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15504 }
15505
15506 /* Display mode lines. */
15507 clear_glyph_matrix (w->desired_matrix);
15508 if (display_mode_lines (w))
15509 {
15510 ++nwindows;
15511 w->must_be_updated_p = 1;
15512 }
15513
15514 /* Restore old settings. */
15515 set_buffer_internal_1 (old);
15516 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15517 }
15518
15519 window = w->next;
15520 }
15521
15522 return nwindows;
15523 }
15524
15525
15526 /* Display the mode and/or top line of window W. Value is the number
15527 of mode lines displayed. */
15528
15529 static int
15530 display_mode_lines (w)
15531 struct window *w;
15532 {
15533 Lisp_Object old_selected_window, old_selected_frame;
15534 int n = 0;
15535
15536 old_selected_frame = selected_frame;
15537 selected_frame = w->frame;
15538 old_selected_window = selected_window;
15539 XSETWINDOW (selected_window, w);
15540
15541 /* These will be set while the mode line specs are processed. */
15542 line_number_displayed = 0;
15543 w->column_number_displayed = Qnil;
15544
15545 if (WINDOW_WANTS_MODELINE_P (w))
15546 {
15547 struct window *sel_w = XWINDOW (old_selected_window);
15548
15549 /* Select mode line face based on the real selected window. */
15550 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15551 current_buffer->mode_line_format);
15552 ++n;
15553 }
15554
15555 if (WINDOW_WANTS_HEADER_LINE_P (w))
15556 {
15557 display_mode_line (w, HEADER_LINE_FACE_ID,
15558 current_buffer->header_line_format);
15559 ++n;
15560 }
15561
15562 selected_frame = old_selected_frame;
15563 selected_window = old_selected_window;
15564 return n;
15565 }
15566
15567
15568 /* Display mode or top line of window W. FACE_ID specifies which line
15569 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15570 FORMAT is the mode line format to display. Value is the pixel
15571 height of the mode line displayed. */
15572
15573 static int
15574 display_mode_line (w, face_id, format)
15575 struct window *w;
15576 enum face_id face_id;
15577 Lisp_Object format;
15578 {
15579 struct it it;
15580 struct face *face;
15581
15582 init_iterator (&it, w, -1, -1, NULL, face_id);
15583 prepare_desired_row (it.glyph_row);
15584
15585 it.glyph_row->mode_line_p = 1;
15586
15587 if (! mode_line_inverse_video)
15588 /* Force the mode-line to be displayed in the default face. */
15589 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15590
15591 /* Temporarily make frame's keyboard the current kboard so that
15592 kboard-local variables in the mode_line_format will get the right
15593 values. */
15594 push_frame_kboard (it.f);
15595 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15596 pop_frame_kboard ();
15597
15598 /* Fill up with spaces. */
15599 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15600
15601 compute_line_metrics (&it);
15602 it.glyph_row->full_width_p = 1;
15603 it.glyph_row->continued_p = 0;
15604 it.glyph_row->truncated_on_left_p = 0;
15605 it.glyph_row->truncated_on_right_p = 0;
15606
15607 /* Make a 3D mode-line have a shadow at its right end. */
15608 face = FACE_FROM_ID (it.f, face_id);
15609 extend_face_to_end_of_line (&it);
15610 if (face->box != FACE_NO_BOX)
15611 {
15612 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15613 + it.glyph_row->used[TEXT_AREA] - 1);
15614 last->right_box_line_p = 1;
15615 }
15616
15617 return it.glyph_row->height;
15618 }
15619
15620 /* Alist that caches the results of :propertize.
15621 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15622 Lisp_Object mode_line_proptrans_alist;
15623
15624 /* List of strings making up the mode-line. */
15625 Lisp_Object mode_line_string_list;
15626
15627 /* Base face property when building propertized mode line string. */
15628 static Lisp_Object mode_line_string_face;
15629 static Lisp_Object mode_line_string_face_prop;
15630
15631
15632 /* Contribute ELT to the mode line for window IT->w. How it
15633 translates into text depends on its data type.
15634
15635 IT describes the display environment in which we display, as usual.
15636
15637 DEPTH is the depth in recursion. It is used to prevent
15638 infinite recursion here.
15639
15640 FIELD_WIDTH is the number of characters the display of ELT should
15641 occupy in the mode line, and PRECISION is the maximum number of
15642 characters to display from ELT's representation. See
15643 display_string for details.
15644
15645 Returns the hpos of the end of the text generated by ELT.
15646
15647 PROPS is a property list to add to any string we encounter.
15648
15649 If RISKY is nonzero, remove (disregard) any properties in any string
15650 we encounter, and ignore :eval and :propertize.
15651
15652 If the global variable `frame_title_ptr' is non-NULL, then the output
15653 is passed to `store_frame_title' instead of `display_string'. */
15654
15655 static int
15656 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15657 struct it *it;
15658 int depth;
15659 int field_width, precision;
15660 Lisp_Object elt, props;
15661 int risky;
15662 {
15663 int n = 0, field, prec;
15664 int literal = 0;
15665
15666 tail_recurse:
15667 if (depth > 100)
15668 elt = build_string ("*too-deep*");
15669
15670 depth++;
15671
15672 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15673 {
15674 case Lisp_String:
15675 {
15676 /* A string: output it and check for %-constructs within it. */
15677 unsigned char c;
15678 const unsigned char *this, *lisp_string;
15679
15680 if (!NILP (props) || risky)
15681 {
15682 Lisp_Object oprops, aelt;
15683 oprops = Ftext_properties_at (make_number (0), elt);
15684
15685 /* If the starting string's properties are not what
15686 we want, translate the string. Also, if the string
15687 is risky, do that anyway. */
15688
15689 if (NILP (Fequal (props, oprops)) || risky)
15690 {
15691 /* If the starting string has properties,
15692 merge the specified ones onto the existing ones. */
15693 if (! NILP (oprops) && !risky)
15694 {
15695 Lisp_Object tem;
15696
15697 oprops = Fcopy_sequence (oprops);
15698 tem = props;
15699 while (CONSP (tem))
15700 {
15701 oprops = Fplist_put (oprops, XCAR (tem),
15702 XCAR (XCDR (tem)));
15703 tem = XCDR (XCDR (tem));
15704 }
15705 props = oprops;
15706 }
15707
15708 aelt = Fassoc (elt, mode_line_proptrans_alist);
15709 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15710 {
15711 mode_line_proptrans_alist
15712 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15713 elt = XCAR (aelt);
15714 }
15715 else
15716 {
15717 Lisp_Object tem;
15718
15719 elt = Fcopy_sequence (elt);
15720 Fset_text_properties (make_number (0), Flength (elt),
15721 props, elt);
15722 /* Add this item to mode_line_proptrans_alist. */
15723 mode_line_proptrans_alist
15724 = Fcons (Fcons (elt, props),
15725 mode_line_proptrans_alist);
15726 /* Truncate mode_line_proptrans_alist
15727 to at most 50 elements. */
15728 tem = Fnthcdr (make_number (50),
15729 mode_line_proptrans_alist);
15730 if (! NILP (tem))
15731 XSETCDR (tem, Qnil);
15732 }
15733 }
15734 }
15735
15736 this = SDATA (elt);
15737 lisp_string = this;
15738
15739 if (literal)
15740 {
15741 prec = precision - n;
15742 if (frame_title_ptr)
15743 n += store_frame_title (SDATA (elt), -1, prec);
15744 else if (!NILP (mode_line_string_list))
15745 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15746 else
15747 n += display_string (NULL, elt, Qnil, 0, 0, it,
15748 0, prec, 0, STRING_MULTIBYTE (elt));
15749
15750 break;
15751 }
15752
15753 while ((precision <= 0 || n < precision)
15754 && *this
15755 && (frame_title_ptr
15756 || !NILP (mode_line_string_list)
15757 || it->current_x < it->last_visible_x))
15758 {
15759 const unsigned char *last = this;
15760
15761 /* Advance to end of string or next format specifier. */
15762 while ((c = *this++) != '\0' && c != '%')
15763 ;
15764
15765 if (this - 1 != last)
15766 {
15767 int nchars, nbytes;
15768
15769 /* Output to end of string or up to '%'. Field width
15770 is length of string. Don't output more than
15771 PRECISION allows us. */
15772 --this;
15773
15774 prec = c_string_width (last, this - last, precision - n,
15775 &nchars, &nbytes);
15776
15777 if (frame_title_ptr)
15778 n += store_frame_title (last, 0, prec);
15779 else if (!NILP (mode_line_string_list))
15780 {
15781 int bytepos = last - lisp_string;
15782 int charpos = string_byte_to_char (elt, bytepos);
15783 int endpos = (precision <= 0
15784 ? string_byte_to_char (elt,
15785 this - lisp_string)
15786 : charpos + nchars);
15787
15788 n += store_mode_line_string (NULL,
15789 Fsubstring (elt, make_number (charpos),
15790 make_number (endpos)),
15791 0, 0, 0, Qnil);
15792 }
15793 else
15794 {
15795 int bytepos = last - lisp_string;
15796 int charpos = string_byte_to_char (elt, bytepos);
15797 n += display_string (NULL, elt, Qnil, 0, charpos,
15798 it, 0, prec, 0,
15799 STRING_MULTIBYTE (elt));
15800 }
15801 }
15802 else /* c == '%' */
15803 {
15804 const unsigned char *percent_position = this;
15805
15806 /* Get the specified minimum width. Zero means
15807 don't pad. */
15808 field = 0;
15809 while ((c = *this++) >= '0' && c <= '9')
15810 field = field * 10 + c - '0';
15811
15812 /* Don't pad beyond the total padding allowed. */
15813 if (field_width - n > 0 && field > field_width - n)
15814 field = field_width - n;
15815
15816 /* Note that either PRECISION <= 0 or N < PRECISION. */
15817 prec = precision - n;
15818
15819 if (c == 'M')
15820 n += display_mode_element (it, depth, field, prec,
15821 Vglobal_mode_string, props,
15822 risky);
15823 else if (c != 0)
15824 {
15825 int multibyte;
15826 int bytepos, charpos;
15827 unsigned char *spec;
15828
15829 bytepos = percent_position - lisp_string;
15830 charpos = (STRING_MULTIBYTE (elt)
15831 ? string_byte_to_char (elt, bytepos)
15832 : bytepos);
15833
15834 spec
15835 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15836
15837 if (frame_title_ptr)
15838 n += store_frame_title (spec, field, prec);
15839 else if (!NILP (mode_line_string_list))
15840 {
15841 int len = strlen (spec);
15842 Lisp_Object tem = make_string (spec, len);
15843 props = Ftext_properties_at (make_number (charpos), elt);
15844 /* Should only keep face property in props */
15845 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15846 }
15847 else
15848 {
15849 int nglyphs_before, nwritten;
15850
15851 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15852 nwritten = display_string (spec, Qnil, elt,
15853 charpos, 0, it,
15854 field, prec, 0,
15855 multibyte);
15856
15857 /* Assign to the glyphs written above the
15858 string where the `%x' came from, position
15859 of the `%'. */
15860 if (nwritten > 0)
15861 {
15862 struct glyph *glyph
15863 = (it->glyph_row->glyphs[TEXT_AREA]
15864 + nglyphs_before);
15865 int i;
15866
15867 for (i = 0; i < nwritten; ++i)
15868 {
15869 glyph[i].object = elt;
15870 glyph[i].charpos = charpos;
15871 }
15872
15873 n += nwritten;
15874 }
15875 }
15876 }
15877 else /* c == 0 */
15878 break;
15879 }
15880 }
15881 }
15882 break;
15883
15884 case Lisp_Symbol:
15885 /* A symbol: process the value of the symbol recursively
15886 as if it appeared here directly. Avoid error if symbol void.
15887 Special case: if value of symbol is a string, output the string
15888 literally. */
15889 {
15890 register Lisp_Object tem;
15891
15892 /* If the variable is not marked as risky to set
15893 then its contents are risky to use. */
15894 if (NILP (Fget (elt, Qrisky_local_variable)))
15895 risky = 1;
15896
15897 tem = Fboundp (elt);
15898 if (!NILP (tem))
15899 {
15900 tem = Fsymbol_value (elt);
15901 /* If value is a string, output that string literally:
15902 don't check for % within it. */
15903 if (STRINGP (tem))
15904 literal = 1;
15905
15906 if (!EQ (tem, elt))
15907 {
15908 /* Give up right away for nil or t. */
15909 elt = tem;
15910 goto tail_recurse;
15911 }
15912 }
15913 }
15914 break;
15915
15916 case Lisp_Cons:
15917 {
15918 register Lisp_Object car, tem;
15919
15920 /* A cons cell: five distinct cases.
15921 If first element is :eval or :propertize, do something special.
15922 If first element is a string or a cons, process all the elements
15923 and effectively concatenate them.
15924 If first element is a negative number, truncate displaying cdr to
15925 at most that many characters. If positive, pad (with spaces)
15926 to at least that many characters.
15927 If first element is a symbol, process the cadr or caddr recursively
15928 according to whether the symbol's value is non-nil or nil. */
15929 car = XCAR (elt);
15930 if (EQ (car, QCeval))
15931 {
15932 /* An element of the form (:eval FORM) means evaluate FORM
15933 and use the result as mode line elements. */
15934
15935 if (risky)
15936 break;
15937
15938 if (CONSP (XCDR (elt)))
15939 {
15940 Lisp_Object spec;
15941 spec = safe_eval (XCAR (XCDR (elt)));
15942 n += display_mode_element (it, depth, field_width - n,
15943 precision - n, spec, props,
15944 risky);
15945 }
15946 }
15947 else if (EQ (car, QCpropertize))
15948 {
15949 /* An element of the form (:propertize ELT PROPS...)
15950 means display ELT but applying properties PROPS. */
15951
15952 if (risky)
15953 break;
15954
15955 if (CONSP (XCDR (elt)))
15956 n += display_mode_element (it, depth, field_width - n,
15957 precision - n, XCAR (XCDR (elt)),
15958 XCDR (XCDR (elt)), risky);
15959 }
15960 else if (SYMBOLP (car))
15961 {
15962 tem = Fboundp (car);
15963 elt = XCDR (elt);
15964 if (!CONSP (elt))
15965 goto invalid;
15966 /* elt is now the cdr, and we know it is a cons cell.
15967 Use its car if CAR has a non-nil value. */
15968 if (!NILP (tem))
15969 {
15970 tem = Fsymbol_value (car);
15971 if (!NILP (tem))
15972 {
15973 elt = XCAR (elt);
15974 goto tail_recurse;
15975 }
15976 }
15977 /* Symbol's value is nil (or symbol is unbound)
15978 Get the cddr of the original list
15979 and if possible find the caddr and use that. */
15980 elt = XCDR (elt);
15981 if (NILP (elt))
15982 break;
15983 else if (!CONSP (elt))
15984 goto invalid;
15985 elt = XCAR (elt);
15986 goto tail_recurse;
15987 }
15988 else if (INTEGERP (car))
15989 {
15990 register int lim = XINT (car);
15991 elt = XCDR (elt);
15992 if (lim < 0)
15993 {
15994 /* Negative int means reduce maximum width. */
15995 if (precision <= 0)
15996 precision = -lim;
15997 else
15998 precision = min (precision, -lim);
15999 }
16000 else if (lim > 0)
16001 {
16002 /* Padding specified. Don't let it be more than
16003 current maximum. */
16004 if (precision > 0)
16005 lim = min (precision, lim);
16006
16007 /* If that's more padding than already wanted, queue it.
16008 But don't reduce padding already specified even if
16009 that is beyond the current truncation point. */
16010 field_width = max (lim, field_width);
16011 }
16012 goto tail_recurse;
16013 }
16014 else if (STRINGP (car) || CONSP (car))
16015 {
16016 register int limit = 50;
16017 /* Limit is to protect against circular lists. */
16018 while (CONSP (elt)
16019 && --limit > 0
16020 && (precision <= 0 || n < precision))
16021 {
16022 n += display_mode_element (it, depth, field_width - n,
16023 precision - n, XCAR (elt),
16024 props, risky);
16025 elt = XCDR (elt);
16026 }
16027 }
16028 }
16029 break;
16030
16031 default:
16032 invalid:
16033 elt = build_string ("*invalid*");
16034 goto tail_recurse;
16035 }
16036
16037 /* Pad to FIELD_WIDTH. */
16038 if (field_width > 0 && n < field_width)
16039 {
16040 if (frame_title_ptr)
16041 n += store_frame_title ("", field_width - n, 0);
16042 else if (!NILP (mode_line_string_list))
16043 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
16044 else
16045 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
16046 0, 0, 0);
16047 }
16048
16049 return n;
16050 }
16051
16052 /* Store a mode-line string element in mode_line_string_list.
16053
16054 If STRING is non-null, display that C string. Otherwise, the Lisp
16055 string LISP_STRING is displayed.
16056
16057 FIELD_WIDTH is the minimum number of output glyphs to produce.
16058 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16059 with spaces. FIELD_WIDTH <= 0 means don't pad.
16060
16061 PRECISION is the maximum number of characters to output from
16062 STRING. PRECISION <= 0 means don't truncate the string.
16063
16064 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
16065 properties to the string.
16066
16067 PROPS are the properties to add to the string.
16068 The mode_line_string_face face property is always added to the string.
16069 */
16070
16071 static int
16072 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
16073 char *string;
16074 Lisp_Object lisp_string;
16075 int copy_string;
16076 int field_width;
16077 int precision;
16078 Lisp_Object props;
16079 {
16080 int len;
16081 int n = 0;
16082
16083 if (string != NULL)
16084 {
16085 len = strlen (string);
16086 if (precision > 0 && len > precision)
16087 len = precision;
16088 lisp_string = make_string (string, len);
16089 if (NILP (props))
16090 props = mode_line_string_face_prop;
16091 else if (!NILP (mode_line_string_face))
16092 {
16093 Lisp_Object face = Fsafe_plist_get (props, Qface);
16094 props = Fcopy_sequence (props);
16095 if (NILP (face))
16096 face = mode_line_string_face;
16097 else
16098 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16099 props = Fplist_put (props, Qface, face);
16100 }
16101 Fadd_text_properties (make_number (0), make_number (len),
16102 props, lisp_string);
16103 }
16104 else
16105 {
16106 len = XFASTINT (Flength (lisp_string));
16107 if (precision > 0 && len > precision)
16108 {
16109 len = precision;
16110 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
16111 precision = -1;
16112 }
16113 if (!NILP (mode_line_string_face))
16114 {
16115 Lisp_Object face;
16116 if (NILP (props))
16117 props = Ftext_properties_at (make_number (0), lisp_string);
16118 face = Fsafe_plist_get (props, Qface);
16119 if (NILP (face))
16120 face = mode_line_string_face;
16121 else
16122 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16123 props = Fcons (Qface, Fcons (face, Qnil));
16124 if (copy_string)
16125 lisp_string = Fcopy_sequence (lisp_string);
16126 }
16127 if (!NILP (props))
16128 Fadd_text_properties (make_number (0), make_number (len),
16129 props, lisp_string);
16130 }
16131
16132 if (len > 0)
16133 {
16134 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16135 n += len;
16136 }
16137
16138 if (field_width > len)
16139 {
16140 field_width -= len;
16141 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
16142 if (!NILP (props))
16143 Fadd_text_properties (make_number (0), make_number (field_width),
16144 props, lisp_string);
16145 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16146 n += field_width;
16147 }
16148
16149 return n;
16150 }
16151
16152
16153 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
16154 1, 4, 0,
16155 doc: /* Format a string out of a mode line format specification.
16156 First arg FORMAT specifies the mode line format (see `mode-line-format'
16157 for details) to use.
16158
16159 Optional second arg FACE specifies the face property to put
16160 on all characters for which no face is specified.
16161 t means whatever face the window's mode line currently uses
16162 \(either `mode-line' or `mode-line-inactive', depending).
16163 nil means the default is no face property.
16164 If FACE is an integer, the value string has no text properties.
16165
16166 Optional third and fourth args WINDOW and BUFFER specify the window
16167 and buffer to use as the context for the formatting (defaults
16168 are the selected window and the window's buffer). */)
16169 (format, face, window, buffer)
16170 Lisp_Object format, face, window, buffer;
16171 {
16172 struct it it;
16173 int len;
16174 struct window *w;
16175 struct buffer *old_buffer = NULL;
16176 int face_id = -1;
16177 int no_props = INTEGERP (face);
16178
16179 if (NILP (window))
16180 window = selected_window;
16181 CHECK_WINDOW (window);
16182 w = XWINDOW (window);
16183
16184 if (NILP (buffer))
16185 buffer = w->buffer;
16186 CHECK_BUFFER (buffer);
16187
16188 if (NILP (format))
16189 return build_string ("");
16190
16191 if (no_props)
16192 face = Qnil;
16193
16194 if (!NILP (face))
16195 {
16196 if (EQ (face, Qt))
16197 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
16198 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
16199 }
16200
16201 if (face_id < 0)
16202 face_id = DEFAULT_FACE_ID;
16203
16204 if (XBUFFER (buffer) != current_buffer)
16205 {
16206 old_buffer = current_buffer;
16207 set_buffer_internal_1 (XBUFFER (buffer));
16208 }
16209
16210 init_iterator (&it, w, -1, -1, NULL, face_id);
16211
16212 if (!no_props)
16213 {
16214 mode_line_string_face = face;
16215 mode_line_string_face_prop
16216 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
16217
16218 /* We need a dummy last element in mode_line_string_list to
16219 indicate we are building the propertized mode-line string.
16220 Using mode_line_string_face_prop here GC protects it. */
16221 mode_line_string_list
16222 = Fcons (mode_line_string_face_prop, Qnil);
16223 frame_title_ptr = NULL;
16224 }
16225 else
16226 {
16227 mode_line_string_face_prop = Qnil;
16228 mode_line_string_list = Qnil;
16229 frame_title_ptr = frame_title_buf;
16230 }
16231
16232 push_frame_kboard (it.f);
16233 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16234 pop_frame_kboard ();
16235
16236 if (old_buffer)
16237 set_buffer_internal_1 (old_buffer);
16238
16239 if (!no_props)
16240 {
16241 Lisp_Object str;
16242 mode_line_string_list = Fnreverse (mode_line_string_list);
16243 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
16244 make_string ("", 0));
16245 mode_line_string_face_prop = Qnil;
16246 mode_line_string_list = Qnil;
16247 return str;
16248 }
16249
16250 len = frame_title_ptr - frame_title_buf;
16251 if (len > 0 && frame_title_ptr[-1] == '-')
16252 {
16253 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
16254 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
16255 ;
16256 frame_title_ptr += 3; /* restore last non-dash + two dashes */
16257 if (len > frame_title_ptr - frame_title_buf)
16258 len = frame_title_ptr - frame_title_buf;
16259 }
16260
16261 frame_title_ptr = NULL;
16262 return make_string (frame_title_buf, len);
16263 }
16264
16265 /* Write a null-terminated, right justified decimal representation of
16266 the positive integer D to BUF using a minimal field width WIDTH. */
16267
16268 static void
16269 pint2str (buf, width, d)
16270 register char *buf;
16271 register int width;
16272 register int d;
16273 {
16274 register char *p = buf;
16275
16276 if (d <= 0)
16277 *p++ = '0';
16278 else
16279 {
16280 while (d > 0)
16281 {
16282 *p++ = d % 10 + '0';
16283 d /= 10;
16284 }
16285 }
16286
16287 for (width -= (int) (p - buf); width > 0; --width)
16288 *p++ = ' ';
16289 *p-- = '\0';
16290 while (p > buf)
16291 {
16292 d = *buf;
16293 *buf++ = *p;
16294 *p-- = d;
16295 }
16296 }
16297
16298 /* Write a null-terminated, right justified decimal and "human
16299 readable" representation of the nonnegative integer D to BUF using
16300 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16301
16302 static const char power_letter[] =
16303 {
16304 0, /* not used */
16305 'k', /* kilo */
16306 'M', /* mega */
16307 'G', /* giga */
16308 'T', /* tera */
16309 'P', /* peta */
16310 'E', /* exa */
16311 'Z', /* zetta */
16312 'Y' /* yotta */
16313 };
16314
16315 static void
16316 pint2hrstr (buf, width, d)
16317 char *buf;
16318 int width;
16319 int d;
16320 {
16321 /* We aim to represent the nonnegative integer D as
16322 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16323 int quotient = d;
16324 int remainder = 0;
16325 /* -1 means: do not use TENTHS. */
16326 int tenths = -1;
16327 int exponent = 0;
16328
16329 /* Length of QUOTIENT.TENTHS as a string. */
16330 int length;
16331
16332 char * psuffix;
16333 char * p;
16334
16335 if (1000 <= quotient)
16336 {
16337 /* Scale to the appropriate EXPONENT. */
16338 do
16339 {
16340 remainder = quotient % 1000;
16341 quotient /= 1000;
16342 exponent++;
16343 }
16344 while (1000 <= quotient);
16345
16346 /* Round to nearest and decide whether to use TENTHS or not. */
16347 if (quotient <= 9)
16348 {
16349 tenths = remainder / 100;
16350 if (50 <= remainder % 100)
16351 {
16352 if (tenths < 9)
16353 tenths++;
16354 else
16355 {
16356 quotient++;
16357 if (quotient == 10)
16358 tenths = -1;
16359 else
16360 tenths = 0;
16361 }
16362 }
16363 }
16364 else
16365 if (500 <= remainder)
16366 {
16367 if (quotient < 999)
16368 quotient++;
16369 else
16370 {
16371 quotient = 1;
16372 exponent++;
16373 tenths = 0;
16374 }
16375 }
16376 }
16377
16378 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16379 if (tenths == -1 && quotient <= 99)
16380 if (quotient <= 9)
16381 length = 1;
16382 else
16383 length = 2;
16384 else
16385 length = 3;
16386 p = psuffix = buf + max (width, length);
16387
16388 /* Print EXPONENT. */
16389 if (exponent)
16390 *psuffix++ = power_letter[exponent];
16391 *psuffix = '\0';
16392
16393 /* Print TENTHS. */
16394 if (tenths >= 0)
16395 {
16396 *--p = '0' + tenths;
16397 *--p = '.';
16398 }
16399
16400 /* Print QUOTIENT. */
16401 do
16402 {
16403 int digit = quotient % 10;
16404 *--p = '0' + digit;
16405 }
16406 while ((quotient /= 10) != 0);
16407
16408 /* Print leading spaces. */
16409 while (buf < p)
16410 *--p = ' ';
16411 }
16412
16413 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16414 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16415 type of CODING_SYSTEM. Return updated pointer into BUF. */
16416
16417 static unsigned char invalid_eol_type[] = "(*invalid*)";
16418
16419 static char *
16420 decode_mode_spec_coding (coding_system, buf, eol_flag)
16421 Lisp_Object coding_system;
16422 register char *buf;
16423 int eol_flag;
16424 {
16425 Lisp_Object val;
16426 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16427 const unsigned char *eol_str;
16428 int eol_str_len;
16429 /* The EOL conversion we are using. */
16430 Lisp_Object eoltype;
16431
16432 val = Fget (coding_system, Qcoding_system);
16433 eoltype = Qnil;
16434
16435 if (!VECTORP (val)) /* Not yet decided. */
16436 {
16437 if (multibyte)
16438 *buf++ = '-';
16439 if (eol_flag)
16440 eoltype = eol_mnemonic_undecided;
16441 /* Don't mention EOL conversion if it isn't decided. */
16442 }
16443 else
16444 {
16445 Lisp_Object eolvalue;
16446
16447 eolvalue = Fget (coding_system, Qeol_type);
16448
16449 if (multibyte)
16450 *buf++ = XFASTINT (AREF (val, 1));
16451
16452 if (eol_flag)
16453 {
16454 /* The EOL conversion that is normal on this system. */
16455
16456 if (NILP (eolvalue)) /* Not yet decided. */
16457 eoltype = eol_mnemonic_undecided;
16458 else if (VECTORP (eolvalue)) /* Not yet decided. */
16459 eoltype = eol_mnemonic_undecided;
16460 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16461 eoltype = (XFASTINT (eolvalue) == 0
16462 ? eol_mnemonic_unix
16463 : (XFASTINT (eolvalue) == 1
16464 ? eol_mnemonic_dos : eol_mnemonic_mac));
16465 }
16466 }
16467
16468 if (eol_flag)
16469 {
16470 /* Mention the EOL conversion if it is not the usual one. */
16471 if (STRINGP (eoltype))
16472 {
16473 eol_str = SDATA (eoltype);
16474 eol_str_len = SBYTES (eoltype);
16475 }
16476 else if (INTEGERP (eoltype)
16477 && CHAR_VALID_P (XINT (eoltype), 0))
16478 {
16479 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16480 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16481 eol_str = tmp;
16482 }
16483 else
16484 {
16485 eol_str = invalid_eol_type;
16486 eol_str_len = sizeof (invalid_eol_type) - 1;
16487 }
16488 bcopy (eol_str, buf, eol_str_len);
16489 buf += eol_str_len;
16490 }
16491
16492 return buf;
16493 }
16494
16495 /* Return a string for the output of a mode line %-spec for window W,
16496 generated by character C. PRECISION >= 0 means don't return a
16497 string longer than that value. FIELD_WIDTH > 0 means pad the
16498 string returned with spaces to that value. Return 1 in *MULTIBYTE
16499 if the result is multibyte text.
16500
16501 Note we operate on the current buffer for most purposes,
16502 the exception being w->base_line_pos. */
16503
16504 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16505
16506 static char *
16507 decode_mode_spec (w, c, field_width, precision, multibyte)
16508 struct window *w;
16509 register int c;
16510 int field_width, precision;
16511 int *multibyte;
16512 {
16513 Lisp_Object obj;
16514 struct frame *f = XFRAME (WINDOW_FRAME (w));
16515 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16516 struct buffer *b = current_buffer;
16517
16518 obj = Qnil;
16519 *multibyte = 0;
16520
16521 switch (c)
16522 {
16523 case '*':
16524 if (!NILP (b->read_only))
16525 return "%";
16526 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16527 return "*";
16528 return "-";
16529
16530 case '+':
16531 /* This differs from %* only for a modified read-only buffer. */
16532 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16533 return "*";
16534 if (!NILP (b->read_only))
16535 return "%";
16536 return "-";
16537
16538 case '&':
16539 /* This differs from %* in ignoring read-only-ness. */
16540 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16541 return "*";
16542 return "-";
16543
16544 case '%':
16545 return "%";
16546
16547 case '[':
16548 {
16549 int i;
16550 char *p;
16551
16552 if (command_loop_level > 5)
16553 return "[[[... ";
16554 p = decode_mode_spec_buf;
16555 for (i = 0; i < command_loop_level; i++)
16556 *p++ = '[';
16557 *p = 0;
16558 return decode_mode_spec_buf;
16559 }
16560
16561 case ']':
16562 {
16563 int i;
16564 char *p;
16565
16566 if (command_loop_level > 5)
16567 return " ...]]]";
16568 p = decode_mode_spec_buf;
16569 for (i = 0; i < command_loop_level; i++)
16570 *p++ = ']';
16571 *p = 0;
16572 return decode_mode_spec_buf;
16573 }
16574
16575 case '-':
16576 {
16577 register int i;
16578
16579 /* Let lots_of_dashes be a string of infinite length. */
16580 if (!NILP (mode_line_string_list))
16581 return "--";
16582 if (field_width <= 0
16583 || field_width > sizeof (lots_of_dashes))
16584 {
16585 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16586 decode_mode_spec_buf[i] = '-';
16587 decode_mode_spec_buf[i] = '\0';
16588 return decode_mode_spec_buf;
16589 }
16590 else
16591 return lots_of_dashes;
16592 }
16593
16594 case 'b':
16595 obj = b->name;
16596 break;
16597
16598 case 'c':
16599 {
16600 int col = (int) current_column (); /* iftc */
16601 w->column_number_displayed = make_number (col);
16602 pint2str (decode_mode_spec_buf, field_width, col);
16603 return decode_mode_spec_buf;
16604 }
16605
16606 case 'F':
16607 /* %F displays the frame name. */
16608 if (!NILP (f->title))
16609 return (char *) SDATA (f->title);
16610 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16611 return (char *) SDATA (f->name);
16612 return "Emacs";
16613
16614 case 'f':
16615 obj = b->filename;
16616 break;
16617
16618 case 'i':
16619 {
16620 int size = ZV - BEGV;
16621 pint2str (decode_mode_spec_buf, field_width, size);
16622 return decode_mode_spec_buf;
16623 }
16624
16625 case 'I':
16626 {
16627 int size = ZV - BEGV;
16628 pint2hrstr (decode_mode_spec_buf, field_width, size);
16629 return decode_mode_spec_buf;
16630 }
16631
16632 case 'l':
16633 {
16634 int startpos = XMARKER (w->start)->charpos;
16635 int startpos_byte = marker_byte_position (w->start);
16636 int line, linepos, linepos_byte, topline;
16637 int nlines, junk;
16638 int height = WINDOW_TOTAL_LINES (w);
16639
16640 /* If we decided that this buffer isn't suitable for line numbers,
16641 don't forget that too fast. */
16642 if (EQ (w->base_line_pos, w->buffer))
16643 goto no_value;
16644 /* But do forget it, if the window shows a different buffer now. */
16645 else if (BUFFERP (w->base_line_pos))
16646 w->base_line_pos = Qnil;
16647
16648 /* If the buffer is very big, don't waste time. */
16649 if (INTEGERP (Vline_number_display_limit)
16650 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16651 {
16652 w->base_line_pos = Qnil;
16653 w->base_line_number = Qnil;
16654 goto no_value;
16655 }
16656
16657 if (!NILP (w->base_line_number)
16658 && !NILP (w->base_line_pos)
16659 && XFASTINT (w->base_line_pos) <= startpos)
16660 {
16661 line = XFASTINT (w->base_line_number);
16662 linepos = XFASTINT (w->base_line_pos);
16663 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16664 }
16665 else
16666 {
16667 line = 1;
16668 linepos = BUF_BEGV (b);
16669 linepos_byte = BUF_BEGV_BYTE (b);
16670 }
16671
16672 /* Count lines from base line to window start position. */
16673 nlines = display_count_lines (linepos, linepos_byte,
16674 startpos_byte,
16675 startpos, &junk);
16676
16677 topline = nlines + line;
16678
16679 /* Determine a new base line, if the old one is too close
16680 or too far away, or if we did not have one.
16681 "Too close" means it's plausible a scroll-down would
16682 go back past it. */
16683 if (startpos == BUF_BEGV (b))
16684 {
16685 w->base_line_number = make_number (topline);
16686 w->base_line_pos = make_number (BUF_BEGV (b));
16687 }
16688 else if (nlines < height + 25 || nlines > height * 3 + 50
16689 || linepos == BUF_BEGV (b))
16690 {
16691 int limit = BUF_BEGV (b);
16692 int limit_byte = BUF_BEGV_BYTE (b);
16693 int position;
16694 int distance = (height * 2 + 30) * line_number_display_limit_width;
16695
16696 if (startpos - distance > limit)
16697 {
16698 limit = startpos - distance;
16699 limit_byte = CHAR_TO_BYTE (limit);
16700 }
16701
16702 nlines = display_count_lines (startpos, startpos_byte,
16703 limit_byte,
16704 - (height * 2 + 30),
16705 &position);
16706 /* If we couldn't find the lines we wanted within
16707 line_number_display_limit_width chars per line,
16708 give up on line numbers for this window. */
16709 if (position == limit_byte && limit == startpos - distance)
16710 {
16711 w->base_line_pos = w->buffer;
16712 w->base_line_number = Qnil;
16713 goto no_value;
16714 }
16715
16716 w->base_line_number = make_number (topline - nlines);
16717 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16718 }
16719
16720 /* Now count lines from the start pos to point. */
16721 nlines = display_count_lines (startpos, startpos_byte,
16722 PT_BYTE, PT, &junk);
16723
16724 /* Record that we did display the line number. */
16725 line_number_displayed = 1;
16726
16727 /* Make the string to show. */
16728 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16729 return decode_mode_spec_buf;
16730 no_value:
16731 {
16732 char* p = decode_mode_spec_buf;
16733 int pad = field_width - 2;
16734 while (pad-- > 0)
16735 *p++ = ' ';
16736 *p++ = '?';
16737 *p++ = '?';
16738 *p = '\0';
16739 return decode_mode_spec_buf;
16740 }
16741 }
16742 break;
16743
16744 case 'm':
16745 obj = b->mode_name;
16746 break;
16747
16748 case 'n':
16749 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16750 return " Narrow";
16751 break;
16752
16753 case 'p':
16754 {
16755 int pos = marker_position (w->start);
16756 int total = BUF_ZV (b) - BUF_BEGV (b);
16757
16758 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16759 {
16760 if (pos <= BUF_BEGV (b))
16761 return "All";
16762 else
16763 return "Bottom";
16764 }
16765 else if (pos <= BUF_BEGV (b))
16766 return "Top";
16767 else
16768 {
16769 if (total > 1000000)
16770 /* Do it differently for a large value, to avoid overflow. */
16771 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16772 else
16773 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16774 /* We can't normally display a 3-digit number,
16775 so get us a 2-digit number that is close. */
16776 if (total == 100)
16777 total = 99;
16778 sprintf (decode_mode_spec_buf, "%2d%%", total);
16779 return decode_mode_spec_buf;
16780 }
16781 }
16782
16783 /* Display percentage of size above the bottom of the screen. */
16784 case 'P':
16785 {
16786 int toppos = marker_position (w->start);
16787 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16788 int total = BUF_ZV (b) - BUF_BEGV (b);
16789
16790 if (botpos >= BUF_ZV (b))
16791 {
16792 if (toppos <= BUF_BEGV (b))
16793 return "All";
16794 else
16795 return "Bottom";
16796 }
16797 else
16798 {
16799 if (total > 1000000)
16800 /* Do it differently for a large value, to avoid overflow. */
16801 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16802 else
16803 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16804 /* We can't normally display a 3-digit number,
16805 so get us a 2-digit number that is close. */
16806 if (total == 100)
16807 total = 99;
16808 if (toppos <= BUF_BEGV (b))
16809 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16810 else
16811 sprintf (decode_mode_spec_buf, "%2d%%", total);
16812 return decode_mode_spec_buf;
16813 }
16814 }
16815
16816 case 's':
16817 /* status of process */
16818 obj = Fget_buffer_process (Fcurrent_buffer ());
16819 if (NILP (obj))
16820 return "no process";
16821 #ifdef subprocesses
16822 obj = Fsymbol_name (Fprocess_status (obj));
16823 #endif
16824 break;
16825
16826 case 't': /* indicate TEXT or BINARY */
16827 #ifdef MODE_LINE_BINARY_TEXT
16828 return MODE_LINE_BINARY_TEXT (b);
16829 #else
16830 return "T";
16831 #endif
16832
16833 case 'z':
16834 /* coding-system (not including end-of-line format) */
16835 case 'Z':
16836 /* coding-system (including end-of-line type) */
16837 {
16838 int eol_flag = (c == 'Z');
16839 char *p = decode_mode_spec_buf;
16840
16841 if (! FRAME_WINDOW_P (f))
16842 {
16843 /* No need to mention EOL here--the terminal never needs
16844 to do EOL conversion. */
16845 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16846 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16847 }
16848 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16849 p, eol_flag);
16850
16851 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16852 #ifdef subprocesses
16853 obj = Fget_buffer_process (Fcurrent_buffer ());
16854 if (PROCESSP (obj))
16855 {
16856 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16857 p, eol_flag);
16858 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16859 p, eol_flag);
16860 }
16861 #endif /* subprocesses */
16862 #endif /* 0 */
16863 *p = 0;
16864 return decode_mode_spec_buf;
16865 }
16866 }
16867
16868 if (STRINGP (obj))
16869 {
16870 *multibyte = STRING_MULTIBYTE (obj);
16871 return (char *) SDATA (obj);
16872 }
16873 else
16874 return "";
16875 }
16876
16877
16878 /* Count up to COUNT lines starting from START / START_BYTE.
16879 But don't go beyond LIMIT_BYTE.
16880 Return the number of lines thus found (always nonnegative).
16881
16882 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16883
16884 static int
16885 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16886 int start, start_byte, limit_byte, count;
16887 int *byte_pos_ptr;
16888 {
16889 register unsigned char *cursor;
16890 unsigned char *base;
16891
16892 register int ceiling;
16893 register unsigned char *ceiling_addr;
16894 int orig_count = count;
16895
16896 /* If we are not in selective display mode,
16897 check only for newlines. */
16898 int selective_display = (!NILP (current_buffer->selective_display)
16899 && !INTEGERP (current_buffer->selective_display));
16900
16901 if (count > 0)
16902 {
16903 while (start_byte < limit_byte)
16904 {
16905 ceiling = BUFFER_CEILING_OF (start_byte);
16906 ceiling = min (limit_byte - 1, ceiling);
16907 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16908 base = (cursor = BYTE_POS_ADDR (start_byte));
16909 while (1)
16910 {
16911 if (selective_display)
16912 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16913 ;
16914 else
16915 while (*cursor != '\n' && ++cursor != ceiling_addr)
16916 ;
16917
16918 if (cursor != ceiling_addr)
16919 {
16920 if (--count == 0)
16921 {
16922 start_byte += cursor - base + 1;
16923 *byte_pos_ptr = start_byte;
16924 return orig_count;
16925 }
16926 else
16927 if (++cursor == ceiling_addr)
16928 break;
16929 }
16930 else
16931 break;
16932 }
16933 start_byte += cursor - base;
16934 }
16935 }
16936 else
16937 {
16938 while (start_byte > limit_byte)
16939 {
16940 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16941 ceiling = max (limit_byte, ceiling);
16942 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16943 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16944 while (1)
16945 {
16946 if (selective_display)
16947 while (--cursor != ceiling_addr
16948 && *cursor != '\n' && *cursor != 015)
16949 ;
16950 else
16951 while (--cursor != ceiling_addr && *cursor != '\n')
16952 ;
16953
16954 if (cursor != ceiling_addr)
16955 {
16956 if (++count == 0)
16957 {
16958 start_byte += cursor - base + 1;
16959 *byte_pos_ptr = start_byte;
16960 /* When scanning backwards, we should
16961 not count the newline posterior to which we stop. */
16962 return - orig_count - 1;
16963 }
16964 }
16965 else
16966 break;
16967 }
16968 /* Here we add 1 to compensate for the last decrement
16969 of CURSOR, which took it past the valid range. */
16970 start_byte += cursor - base + 1;
16971 }
16972 }
16973
16974 *byte_pos_ptr = limit_byte;
16975
16976 if (count < 0)
16977 return - orig_count + count;
16978 return orig_count - count;
16979
16980 }
16981
16982
16983 \f
16984 /***********************************************************************
16985 Displaying strings
16986 ***********************************************************************/
16987
16988 /* Display a NUL-terminated string, starting with index START.
16989
16990 If STRING is non-null, display that C string. Otherwise, the Lisp
16991 string LISP_STRING is displayed.
16992
16993 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16994 FACE_STRING. Display STRING or LISP_STRING with the face at
16995 FACE_STRING_POS in FACE_STRING:
16996
16997 Display the string in the environment given by IT, but use the
16998 standard display table, temporarily.
16999
17000 FIELD_WIDTH is the minimum number of output glyphs to produce.
17001 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17002 with spaces. If STRING has more characters, more than FIELD_WIDTH
17003 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
17004
17005 PRECISION is the maximum number of characters to output from
17006 STRING. PRECISION < 0 means don't truncate the string.
17007
17008 This is roughly equivalent to printf format specifiers:
17009
17010 FIELD_WIDTH PRECISION PRINTF
17011 ----------------------------------------
17012 -1 -1 %s
17013 -1 10 %.10s
17014 10 -1 %10s
17015 20 10 %20.10s
17016
17017 MULTIBYTE zero means do not display multibyte chars, > 0 means do
17018 display them, and < 0 means obey the current buffer's value of
17019 enable_multibyte_characters.
17020
17021 Value is the number of glyphs produced. */
17022
17023 static int
17024 display_string (string, lisp_string, face_string, face_string_pos,
17025 start, it, field_width, precision, max_x, multibyte)
17026 unsigned char *string;
17027 Lisp_Object lisp_string;
17028 Lisp_Object face_string;
17029 int face_string_pos;
17030 int start;
17031 struct it *it;
17032 int field_width, precision, max_x;
17033 int multibyte;
17034 {
17035 int hpos_at_start = it->hpos;
17036 int saved_face_id = it->face_id;
17037 struct glyph_row *row = it->glyph_row;
17038
17039 /* Initialize the iterator IT for iteration over STRING beginning
17040 with index START. */
17041 reseat_to_string (it, string, lisp_string, start,
17042 precision, field_width, multibyte);
17043
17044 /* If displaying STRING, set up the face of the iterator
17045 from LISP_STRING, if that's given. */
17046 if (STRINGP (face_string))
17047 {
17048 int endptr;
17049 struct face *face;
17050
17051 it->face_id
17052 = face_at_string_position (it->w, face_string, face_string_pos,
17053 0, it->region_beg_charpos,
17054 it->region_end_charpos,
17055 &endptr, it->base_face_id, 0);
17056 face = FACE_FROM_ID (it->f, it->face_id);
17057 it->face_box_p = face->box != FACE_NO_BOX;
17058 }
17059
17060 /* Set max_x to the maximum allowed X position. Don't let it go
17061 beyond the right edge of the window. */
17062 if (max_x <= 0)
17063 max_x = it->last_visible_x;
17064 else
17065 max_x = min (max_x, it->last_visible_x);
17066
17067 /* Skip over display elements that are not visible. because IT->w is
17068 hscrolled. */
17069 if (it->current_x < it->first_visible_x)
17070 move_it_in_display_line_to (it, 100000, it->first_visible_x,
17071 MOVE_TO_POS | MOVE_TO_X);
17072
17073 row->ascent = it->max_ascent;
17074 row->height = it->max_ascent + it->max_descent;
17075 row->phys_ascent = it->max_phys_ascent;
17076 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17077 row->extra_line_spacing = it->max_extra_line_spacing;
17078
17079 /* This condition is for the case that we are called with current_x
17080 past last_visible_x. */
17081 while (it->current_x < max_x)
17082 {
17083 int x_before, x, n_glyphs_before, i, nglyphs;
17084
17085 /* Get the next display element. */
17086 if (!get_next_display_element (it))
17087 break;
17088
17089 /* Produce glyphs. */
17090 x_before = it->current_x;
17091 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
17092 PRODUCE_GLYPHS (it);
17093
17094 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
17095 i = 0;
17096 x = x_before;
17097 while (i < nglyphs)
17098 {
17099 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17100
17101 if (!it->truncate_lines_p
17102 && x + glyph->pixel_width > max_x)
17103 {
17104 /* End of continued line or max_x reached. */
17105 if (CHAR_GLYPH_PADDING_P (*glyph))
17106 {
17107 /* A wide character is unbreakable. */
17108 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
17109 it->current_x = x_before;
17110 }
17111 else
17112 {
17113 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
17114 it->current_x = x;
17115 }
17116 break;
17117 }
17118 else if (x + glyph->pixel_width > it->first_visible_x)
17119 {
17120 /* Glyph is at least partially visible. */
17121 ++it->hpos;
17122 if (x < it->first_visible_x)
17123 it->glyph_row->x = x - it->first_visible_x;
17124 }
17125 else
17126 {
17127 /* Glyph is off the left margin of the display area.
17128 Should not happen. */
17129 abort ();
17130 }
17131
17132 row->ascent = max (row->ascent, it->max_ascent);
17133 row->height = max (row->height, it->max_ascent + it->max_descent);
17134 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17135 row->phys_height = max (row->phys_height,
17136 it->max_phys_ascent + it->max_phys_descent);
17137 row->extra_line_spacing = max (row->extra_line_spacing,
17138 it->max_extra_line_spacing);
17139 x += glyph->pixel_width;
17140 ++i;
17141 }
17142
17143 /* Stop if max_x reached. */
17144 if (i < nglyphs)
17145 break;
17146
17147 /* Stop at line ends. */
17148 if (ITERATOR_AT_END_OF_LINE_P (it))
17149 {
17150 it->continuation_lines_width = 0;
17151 break;
17152 }
17153
17154 set_iterator_to_next (it, 1);
17155
17156 /* Stop if truncating at the right edge. */
17157 if (it->truncate_lines_p
17158 && it->current_x >= it->last_visible_x)
17159 {
17160 /* Add truncation mark, but don't do it if the line is
17161 truncated at a padding space. */
17162 if (IT_CHARPOS (*it) < it->string_nchars)
17163 {
17164 if (!FRAME_WINDOW_P (it->f))
17165 {
17166 int i, n;
17167
17168 if (it->current_x > it->last_visible_x)
17169 {
17170 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17171 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17172 break;
17173 for (n = row->used[TEXT_AREA]; i < n; ++i)
17174 {
17175 row->used[TEXT_AREA] = i;
17176 produce_special_glyphs (it, IT_TRUNCATION);
17177 }
17178 }
17179 produce_special_glyphs (it, IT_TRUNCATION);
17180 }
17181 it->glyph_row->truncated_on_right_p = 1;
17182 }
17183 break;
17184 }
17185 }
17186
17187 /* Maybe insert a truncation at the left. */
17188 if (it->first_visible_x
17189 && IT_CHARPOS (*it) > 0)
17190 {
17191 if (!FRAME_WINDOW_P (it->f))
17192 insert_left_trunc_glyphs (it);
17193 it->glyph_row->truncated_on_left_p = 1;
17194 }
17195
17196 it->face_id = saved_face_id;
17197
17198 /* Value is number of columns displayed. */
17199 return it->hpos - hpos_at_start;
17200 }
17201
17202
17203 \f
17204 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17205 appears as an element of LIST or as the car of an element of LIST.
17206 If PROPVAL is a list, compare each element against LIST in that
17207 way, and return 1/2 if any element of PROPVAL is found in LIST.
17208 Otherwise return 0. This function cannot quit.
17209 The return value is 2 if the text is invisible but with an ellipsis
17210 and 1 if it's invisible and without an ellipsis. */
17211
17212 int
17213 invisible_p (propval, list)
17214 register Lisp_Object propval;
17215 Lisp_Object list;
17216 {
17217 register Lisp_Object tail, proptail;
17218
17219 for (tail = list; CONSP (tail); tail = XCDR (tail))
17220 {
17221 register Lisp_Object tem;
17222 tem = XCAR (tail);
17223 if (EQ (propval, tem))
17224 return 1;
17225 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17226 return NILP (XCDR (tem)) ? 1 : 2;
17227 }
17228
17229 if (CONSP (propval))
17230 {
17231 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17232 {
17233 Lisp_Object propelt;
17234 propelt = XCAR (proptail);
17235 for (tail = list; CONSP (tail); tail = XCDR (tail))
17236 {
17237 register Lisp_Object tem;
17238 tem = XCAR (tail);
17239 if (EQ (propelt, tem))
17240 return 1;
17241 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17242 return NILP (XCDR (tem)) ? 1 : 2;
17243 }
17244 }
17245 }
17246
17247 return 0;
17248 }
17249
17250 /* Calculate a width or height in pixels from a specification using
17251 the following elements:
17252
17253 SPEC ::=
17254 NUM - a (fractional) multiple of the default font width/height
17255 (NUM) - specifies exactly NUM pixels
17256 UNIT - a fixed number of pixels, see below.
17257 ELEMENT - size of a display element in pixels, see below.
17258 (NUM . SPEC) - equals NUM * SPEC
17259 (+ SPEC SPEC ...) - add pixel values
17260 (- SPEC SPEC ...) - subtract pixel values
17261 (- SPEC) - negate pixel value
17262
17263 NUM ::=
17264 INT or FLOAT - a number constant
17265 SYMBOL - use symbol's (buffer local) variable binding.
17266
17267 UNIT ::=
17268 in - pixels per inch *)
17269 mm - pixels per 1/1000 meter *)
17270 cm - pixels per 1/100 meter *)
17271 width - width of current font in pixels.
17272 height - height of current font in pixels.
17273
17274 *) using the ratio(s) defined in display-pixels-per-inch.
17275
17276 ELEMENT ::=
17277
17278 left-fringe - left fringe width in pixels
17279 right-fringe - right fringe width in pixels
17280
17281 left-margin - left margin width in pixels
17282 right-margin - right margin width in pixels
17283
17284 scroll-bar - scroll-bar area width in pixels
17285
17286 Examples:
17287
17288 Pixels corresponding to 5 inches:
17289 (5 . in)
17290
17291 Total width of non-text areas on left side of window (if scroll-bar is on left):
17292 '(space :width (+ left-fringe left-margin scroll-bar))
17293
17294 Align to first text column (in header line):
17295 '(space :align-to 0)
17296
17297 Align to middle of text area minus half the width of variable `my-image'
17298 containing a loaded image:
17299 '(space :align-to (0.5 . (- text my-image)))
17300
17301 Width of left margin minus width of 1 character in the default font:
17302 '(space :width (- left-margin 1))
17303
17304 Width of left margin minus width of 2 characters in the current font:
17305 '(space :width (- left-margin (2 . width)))
17306
17307 Center 1 character over left-margin (in header line):
17308 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17309
17310 Different ways to express width of left fringe plus left margin minus one pixel:
17311 '(space :width (- (+ left-fringe left-margin) (1)))
17312 '(space :width (+ left-fringe left-margin (- (1))))
17313 '(space :width (+ left-fringe left-margin (-1)))
17314
17315 */
17316
17317 #define NUMVAL(X) \
17318 ((INTEGERP (X) || FLOATP (X)) \
17319 ? XFLOATINT (X) \
17320 : - 1)
17321
17322 int
17323 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17324 double *res;
17325 struct it *it;
17326 Lisp_Object prop;
17327 void *font;
17328 int width_p, *align_to;
17329 {
17330 double pixels;
17331
17332 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17333 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17334
17335 if (NILP (prop))
17336 return OK_PIXELS (0);
17337
17338 if (SYMBOLP (prop))
17339 {
17340 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17341 {
17342 char *unit = SDATA (SYMBOL_NAME (prop));
17343
17344 if (unit[0] == 'i' && unit[1] == 'n')
17345 pixels = 1.0;
17346 else if (unit[0] == 'm' && unit[1] == 'm')
17347 pixels = 25.4;
17348 else if (unit[0] == 'c' && unit[1] == 'm')
17349 pixels = 2.54;
17350 else
17351 pixels = 0;
17352 if (pixels > 0)
17353 {
17354 double ppi;
17355 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17356 || (CONSP (Vdisplay_pixels_per_inch)
17357 && (ppi = (width_p
17358 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17359 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17360 ppi > 0)))
17361 return OK_PIXELS (ppi / pixels);
17362
17363 return 0;
17364 }
17365 }
17366
17367 #ifdef HAVE_WINDOW_SYSTEM
17368 if (EQ (prop, Qheight))
17369 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17370 if (EQ (prop, Qwidth))
17371 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17372 #else
17373 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17374 return OK_PIXELS (1);
17375 #endif
17376
17377 if (EQ (prop, Qtext))
17378 return OK_PIXELS (width_p
17379 ? window_box_width (it->w, TEXT_AREA)
17380 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17381
17382 if (align_to && *align_to < 0)
17383 {
17384 *res = 0;
17385 if (EQ (prop, Qleft))
17386 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17387 if (EQ (prop, Qright))
17388 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17389 if (EQ (prop, Qcenter))
17390 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17391 + window_box_width (it->w, TEXT_AREA) / 2);
17392 if (EQ (prop, Qleft_fringe))
17393 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17394 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17395 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17396 if (EQ (prop, Qright_fringe))
17397 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17398 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17399 : window_box_right_offset (it->w, TEXT_AREA));
17400 if (EQ (prop, Qleft_margin))
17401 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17402 if (EQ (prop, Qright_margin))
17403 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17404 if (EQ (prop, Qscroll_bar))
17405 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17406 ? 0
17407 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17408 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17409 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17410 : 0)));
17411 }
17412 else
17413 {
17414 if (EQ (prop, Qleft_fringe))
17415 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17416 if (EQ (prop, Qright_fringe))
17417 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17418 if (EQ (prop, Qleft_margin))
17419 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17420 if (EQ (prop, Qright_margin))
17421 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17422 if (EQ (prop, Qscroll_bar))
17423 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17424 }
17425
17426 prop = Fbuffer_local_value (prop, it->w->buffer);
17427 }
17428
17429 if (INTEGERP (prop) || FLOATP (prop))
17430 {
17431 int base_unit = (width_p
17432 ? FRAME_COLUMN_WIDTH (it->f)
17433 : FRAME_LINE_HEIGHT (it->f));
17434 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17435 }
17436
17437 if (CONSP (prop))
17438 {
17439 Lisp_Object car = XCAR (prop);
17440 Lisp_Object cdr = XCDR (prop);
17441
17442 if (SYMBOLP (car))
17443 {
17444 #ifdef HAVE_WINDOW_SYSTEM
17445 if (valid_image_p (prop))
17446 {
17447 int id = lookup_image (it->f, prop);
17448 struct image *img = IMAGE_FROM_ID (it->f, id);
17449
17450 return OK_PIXELS (width_p ? img->width : img->height);
17451 }
17452 #endif
17453 if (EQ (car, Qplus) || EQ (car, Qminus))
17454 {
17455 int first = 1;
17456 double px;
17457
17458 pixels = 0;
17459 while (CONSP (cdr))
17460 {
17461 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17462 font, width_p, align_to))
17463 return 0;
17464 if (first)
17465 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17466 else
17467 pixels += px;
17468 cdr = XCDR (cdr);
17469 }
17470 if (EQ (car, Qminus))
17471 pixels = -pixels;
17472 return OK_PIXELS (pixels);
17473 }
17474
17475 car = Fbuffer_local_value (car, it->w->buffer);
17476 }
17477
17478 if (INTEGERP (car) || FLOATP (car))
17479 {
17480 double fact;
17481 pixels = XFLOATINT (car);
17482 if (NILP (cdr))
17483 return OK_PIXELS (pixels);
17484 if (calc_pixel_width_or_height (&fact, it, cdr,
17485 font, width_p, align_to))
17486 return OK_PIXELS (pixels * fact);
17487 return 0;
17488 }
17489
17490 return 0;
17491 }
17492
17493 return 0;
17494 }
17495
17496 \f
17497 /***********************************************************************
17498 Glyph Display
17499 ***********************************************************************/
17500
17501 #ifdef HAVE_WINDOW_SYSTEM
17502
17503 #if GLYPH_DEBUG
17504
17505 void
17506 dump_glyph_string (s)
17507 struct glyph_string *s;
17508 {
17509 fprintf (stderr, "glyph string\n");
17510 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17511 s->x, s->y, s->width, s->height);
17512 fprintf (stderr, " ybase = %d\n", s->ybase);
17513 fprintf (stderr, " hl = %d\n", s->hl);
17514 fprintf (stderr, " left overhang = %d, right = %d\n",
17515 s->left_overhang, s->right_overhang);
17516 fprintf (stderr, " nchars = %d\n", s->nchars);
17517 fprintf (stderr, " extends to end of line = %d\n",
17518 s->extends_to_end_of_line_p);
17519 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17520 fprintf (stderr, " bg width = %d\n", s->background_width);
17521 }
17522
17523 #endif /* GLYPH_DEBUG */
17524
17525 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17526 of XChar2b structures for S; it can't be allocated in
17527 init_glyph_string because it must be allocated via `alloca'. W
17528 is the window on which S is drawn. ROW and AREA are the glyph row
17529 and area within the row from which S is constructed. START is the
17530 index of the first glyph structure covered by S. HL is a
17531 face-override for drawing S. */
17532
17533 #ifdef HAVE_NTGUI
17534 #define OPTIONAL_HDC(hdc) hdc,
17535 #define DECLARE_HDC(hdc) HDC hdc;
17536 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17537 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17538 #endif
17539
17540 #ifndef OPTIONAL_HDC
17541 #define OPTIONAL_HDC(hdc)
17542 #define DECLARE_HDC(hdc)
17543 #define ALLOCATE_HDC(hdc, f)
17544 #define RELEASE_HDC(hdc, f)
17545 #endif
17546
17547 static void
17548 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17549 struct glyph_string *s;
17550 DECLARE_HDC (hdc)
17551 XChar2b *char2b;
17552 struct window *w;
17553 struct glyph_row *row;
17554 enum glyph_row_area area;
17555 int start;
17556 enum draw_glyphs_face hl;
17557 {
17558 bzero (s, sizeof *s);
17559 s->w = w;
17560 s->f = XFRAME (w->frame);
17561 #ifdef HAVE_NTGUI
17562 s->hdc = hdc;
17563 #endif
17564 s->display = FRAME_X_DISPLAY (s->f);
17565 s->window = FRAME_X_WINDOW (s->f);
17566 s->char2b = char2b;
17567 s->hl = hl;
17568 s->row = row;
17569 s->area = area;
17570 s->first_glyph = row->glyphs[area] + start;
17571 s->height = row->height;
17572 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17573
17574 /* Display the internal border below the tool-bar window. */
17575 if (WINDOWP (s->f->tool_bar_window)
17576 && s->w == XWINDOW (s->f->tool_bar_window))
17577 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17578
17579 s->ybase = s->y + row->ascent;
17580 }
17581
17582
17583 /* Append the list of glyph strings with head H and tail T to the list
17584 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17585
17586 static INLINE void
17587 append_glyph_string_lists (head, tail, h, t)
17588 struct glyph_string **head, **tail;
17589 struct glyph_string *h, *t;
17590 {
17591 if (h)
17592 {
17593 if (*head)
17594 (*tail)->next = h;
17595 else
17596 *head = h;
17597 h->prev = *tail;
17598 *tail = t;
17599 }
17600 }
17601
17602
17603 /* Prepend the list of glyph strings with head H and tail T to the
17604 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17605 result. */
17606
17607 static INLINE void
17608 prepend_glyph_string_lists (head, tail, h, t)
17609 struct glyph_string **head, **tail;
17610 struct glyph_string *h, *t;
17611 {
17612 if (h)
17613 {
17614 if (*head)
17615 (*head)->prev = t;
17616 else
17617 *tail = t;
17618 t->next = *head;
17619 *head = h;
17620 }
17621 }
17622
17623
17624 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17625 Set *HEAD and *TAIL to the resulting list. */
17626
17627 static INLINE void
17628 append_glyph_string (head, tail, s)
17629 struct glyph_string **head, **tail;
17630 struct glyph_string *s;
17631 {
17632 s->next = s->prev = NULL;
17633 append_glyph_string_lists (head, tail, s, s);
17634 }
17635
17636
17637 /* Get face and two-byte form of character glyph GLYPH on frame F.
17638 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17639 a pointer to a realized face that is ready for display. */
17640
17641 static INLINE struct face *
17642 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17643 struct frame *f;
17644 struct glyph *glyph;
17645 XChar2b *char2b;
17646 int *two_byte_p;
17647 {
17648 struct face *face;
17649
17650 xassert (glyph->type == CHAR_GLYPH);
17651 face = FACE_FROM_ID (f, glyph->face_id);
17652
17653 if (two_byte_p)
17654 *two_byte_p = 0;
17655
17656 if (!glyph->multibyte_p)
17657 {
17658 /* Unibyte case. We don't have to encode, but we have to make
17659 sure to use a face suitable for unibyte. */
17660 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17661 }
17662 else if (glyph->u.ch < 128
17663 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17664 {
17665 /* Case of ASCII in a face known to fit ASCII. */
17666 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17667 }
17668 else
17669 {
17670 int c1, c2, charset;
17671
17672 /* Split characters into bytes. If c2 is -1 afterwards, C is
17673 really a one-byte character so that byte1 is zero. */
17674 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17675 if (c2 > 0)
17676 STORE_XCHAR2B (char2b, c1, c2);
17677 else
17678 STORE_XCHAR2B (char2b, 0, c1);
17679
17680 /* Maybe encode the character in *CHAR2B. */
17681 if (charset != CHARSET_ASCII)
17682 {
17683 struct font_info *font_info
17684 = FONT_INFO_FROM_ID (f, face->font_info_id);
17685 if (font_info)
17686 glyph->font_type
17687 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17688 }
17689 }
17690
17691 /* Make sure X resources of the face are allocated. */
17692 xassert (face != NULL);
17693 PREPARE_FACE_FOR_DISPLAY (f, face);
17694 return face;
17695 }
17696
17697
17698 /* Fill glyph string S with composition components specified by S->cmp.
17699
17700 FACES is an array of faces for all components of this composition.
17701 S->gidx is the index of the first component for S.
17702 OVERLAPS_P non-zero means S should draw the foreground only, and
17703 use its physical height for clipping.
17704
17705 Value is the index of a component not in S. */
17706
17707 static int
17708 fill_composite_glyph_string (s, faces, overlaps_p)
17709 struct glyph_string *s;
17710 struct face **faces;
17711 int overlaps_p;
17712 {
17713 int i;
17714
17715 xassert (s);
17716
17717 s->for_overlaps_p = overlaps_p;
17718
17719 s->face = faces[s->gidx];
17720 s->font = s->face->font;
17721 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17722
17723 /* For all glyphs of this composition, starting at the offset
17724 S->gidx, until we reach the end of the definition or encounter a
17725 glyph that requires the different face, add it to S. */
17726 ++s->nchars;
17727 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17728 ++s->nchars;
17729
17730 /* All glyph strings for the same composition has the same width,
17731 i.e. the width set for the first component of the composition. */
17732
17733 s->width = s->first_glyph->pixel_width;
17734
17735 /* If the specified font could not be loaded, use the frame's
17736 default font, but record the fact that we couldn't load it in
17737 the glyph string so that we can draw rectangles for the
17738 characters of the glyph string. */
17739 if (s->font == NULL)
17740 {
17741 s->font_not_found_p = 1;
17742 s->font = FRAME_FONT (s->f);
17743 }
17744
17745 /* Adjust base line for subscript/superscript text. */
17746 s->ybase += s->first_glyph->voffset;
17747
17748 xassert (s->face && s->face->gc);
17749
17750 /* This glyph string must always be drawn with 16-bit functions. */
17751 s->two_byte_p = 1;
17752
17753 return s->gidx + s->nchars;
17754 }
17755
17756
17757 /* Fill glyph string S from a sequence of character glyphs.
17758
17759 FACE_ID is the face id of the string. START is the index of the
17760 first glyph to consider, END is the index of the last + 1.
17761 OVERLAPS_P non-zero means S should draw the foreground only, and
17762 use its physical height for clipping.
17763
17764 Value is the index of the first glyph not in S. */
17765
17766 static int
17767 fill_glyph_string (s, face_id, start, end, overlaps_p)
17768 struct glyph_string *s;
17769 int face_id;
17770 int start, end, overlaps_p;
17771 {
17772 struct glyph *glyph, *last;
17773 int voffset;
17774 int glyph_not_available_p;
17775
17776 xassert (s->f == XFRAME (s->w->frame));
17777 xassert (s->nchars == 0);
17778 xassert (start >= 0 && end > start);
17779
17780 s->for_overlaps_p = overlaps_p,
17781 glyph = s->row->glyphs[s->area] + start;
17782 last = s->row->glyphs[s->area] + end;
17783 voffset = glyph->voffset;
17784
17785 glyph_not_available_p = glyph->glyph_not_available_p;
17786
17787 while (glyph < last
17788 && glyph->type == CHAR_GLYPH
17789 && glyph->voffset == voffset
17790 /* Same face id implies same font, nowadays. */
17791 && glyph->face_id == face_id
17792 && glyph->glyph_not_available_p == glyph_not_available_p)
17793 {
17794 int two_byte_p;
17795
17796 s->face = get_glyph_face_and_encoding (s->f, glyph,
17797 s->char2b + s->nchars,
17798 &two_byte_p);
17799 s->two_byte_p = two_byte_p;
17800 ++s->nchars;
17801 xassert (s->nchars <= end - start);
17802 s->width += glyph->pixel_width;
17803 ++glyph;
17804 }
17805
17806 s->font = s->face->font;
17807 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17808
17809 /* If the specified font could not be loaded, use the frame's font,
17810 but record the fact that we couldn't load it in
17811 S->font_not_found_p so that we can draw rectangles for the
17812 characters of the glyph string. */
17813 if (s->font == NULL || glyph_not_available_p)
17814 {
17815 s->font_not_found_p = 1;
17816 s->font = FRAME_FONT (s->f);
17817 }
17818
17819 /* Adjust base line for subscript/superscript text. */
17820 s->ybase += voffset;
17821
17822 xassert (s->face && s->face->gc);
17823 return glyph - s->row->glyphs[s->area];
17824 }
17825
17826
17827 /* Fill glyph string S from image glyph S->first_glyph. */
17828
17829 static void
17830 fill_image_glyph_string (s)
17831 struct glyph_string *s;
17832 {
17833 xassert (s->first_glyph->type == IMAGE_GLYPH);
17834 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17835 xassert (s->img);
17836 s->slice = s->first_glyph->slice;
17837 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17838 s->font = s->face->font;
17839 s->width = s->first_glyph->pixel_width;
17840
17841 /* Adjust base line for subscript/superscript text. */
17842 s->ybase += s->first_glyph->voffset;
17843 }
17844
17845
17846 /* Fill glyph string S from a sequence of stretch glyphs.
17847
17848 ROW is the glyph row in which the glyphs are found, AREA is the
17849 area within the row. START is the index of the first glyph to
17850 consider, END is the index of the last + 1.
17851
17852 Value is the index of the first glyph not in S. */
17853
17854 static int
17855 fill_stretch_glyph_string (s, row, area, start, end)
17856 struct glyph_string *s;
17857 struct glyph_row *row;
17858 enum glyph_row_area area;
17859 int start, end;
17860 {
17861 struct glyph *glyph, *last;
17862 int voffset, face_id;
17863
17864 xassert (s->first_glyph->type == STRETCH_GLYPH);
17865
17866 glyph = s->row->glyphs[s->area] + start;
17867 last = s->row->glyphs[s->area] + end;
17868 face_id = glyph->face_id;
17869 s->face = FACE_FROM_ID (s->f, face_id);
17870 s->font = s->face->font;
17871 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17872 s->width = glyph->pixel_width;
17873 voffset = glyph->voffset;
17874
17875 for (++glyph;
17876 (glyph < last
17877 && glyph->type == STRETCH_GLYPH
17878 && glyph->voffset == voffset
17879 && glyph->face_id == face_id);
17880 ++glyph)
17881 s->width += glyph->pixel_width;
17882
17883 /* Adjust base line for subscript/superscript text. */
17884 s->ybase += voffset;
17885
17886 /* The case that face->gc == 0 is handled when drawing the glyph
17887 string by calling PREPARE_FACE_FOR_DISPLAY. */
17888 xassert (s->face);
17889 return glyph - s->row->glyphs[s->area];
17890 }
17891
17892
17893 /* EXPORT for RIF:
17894 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17895 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17896 assumed to be zero. */
17897
17898 void
17899 x_get_glyph_overhangs (glyph, f, left, right)
17900 struct glyph *glyph;
17901 struct frame *f;
17902 int *left, *right;
17903 {
17904 *left = *right = 0;
17905
17906 if (glyph->type == CHAR_GLYPH)
17907 {
17908 XFontStruct *font;
17909 struct face *face;
17910 struct font_info *font_info;
17911 XChar2b char2b;
17912 XCharStruct *pcm;
17913
17914 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17915 font = face->font;
17916 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17917 if (font /* ++KFS: Should this be font_info ? */
17918 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17919 {
17920 if (pcm->rbearing > pcm->width)
17921 *right = pcm->rbearing - pcm->width;
17922 if (pcm->lbearing < 0)
17923 *left = -pcm->lbearing;
17924 }
17925 }
17926 }
17927
17928
17929 /* Return the index of the first glyph preceding glyph string S that
17930 is overwritten by S because of S's left overhang. Value is -1
17931 if no glyphs are overwritten. */
17932
17933 static int
17934 left_overwritten (s)
17935 struct glyph_string *s;
17936 {
17937 int k;
17938
17939 if (s->left_overhang)
17940 {
17941 int x = 0, i;
17942 struct glyph *glyphs = s->row->glyphs[s->area];
17943 int first = s->first_glyph - glyphs;
17944
17945 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17946 x -= glyphs[i].pixel_width;
17947
17948 k = i + 1;
17949 }
17950 else
17951 k = -1;
17952
17953 return k;
17954 }
17955
17956
17957 /* Return the index of the first glyph preceding glyph string S that
17958 is overwriting S because of its right overhang. Value is -1 if no
17959 glyph in front of S overwrites S. */
17960
17961 static int
17962 left_overwriting (s)
17963 struct glyph_string *s;
17964 {
17965 int i, k, x;
17966 struct glyph *glyphs = s->row->glyphs[s->area];
17967 int first = s->first_glyph - glyphs;
17968
17969 k = -1;
17970 x = 0;
17971 for (i = first - 1; i >= 0; --i)
17972 {
17973 int left, right;
17974 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17975 if (x + right > 0)
17976 k = i;
17977 x -= glyphs[i].pixel_width;
17978 }
17979
17980 return k;
17981 }
17982
17983
17984 /* Return the index of the last glyph following glyph string S that is
17985 not overwritten by S because of S's right overhang. Value is -1 if
17986 no such glyph is found. */
17987
17988 static int
17989 right_overwritten (s)
17990 struct glyph_string *s;
17991 {
17992 int k = -1;
17993
17994 if (s->right_overhang)
17995 {
17996 int x = 0, i;
17997 struct glyph *glyphs = s->row->glyphs[s->area];
17998 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17999 int end = s->row->used[s->area];
18000
18001 for (i = first; i < end && s->right_overhang > x; ++i)
18002 x += glyphs[i].pixel_width;
18003
18004 k = i;
18005 }
18006
18007 return k;
18008 }
18009
18010
18011 /* Return the index of the last glyph following glyph string S that
18012 overwrites S because of its left overhang. Value is negative
18013 if no such glyph is found. */
18014
18015 static int
18016 right_overwriting (s)
18017 struct glyph_string *s;
18018 {
18019 int i, k, x;
18020 int end = s->row->used[s->area];
18021 struct glyph *glyphs = s->row->glyphs[s->area];
18022 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18023
18024 k = -1;
18025 x = 0;
18026 for (i = first; i < end; ++i)
18027 {
18028 int left, right;
18029 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18030 if (x - left < 0)
18031 k = i;
18032 x += glyphs[i].pixel_width;
18033 }
18034
18035 return k;
18036 }
18037
18038
18039 /* Get face and two-byte form of character C in face FACE_ID on frame
18040 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18041 means we want to display multibyte text. DISPLAY_P non-zero means
18042 make sure that X resources for the face returned are allocated.
18043 Value is a pointer to a realized face that is ready for display if
18044 DISPLAY_P is non-zero. */
18045
18046 static INLINE struct face *
18047 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
18048 struct frame *f;
18049 int c, face_id;
18050 XChar2b *char2b;
18051 int multibyte_p, display_p;
18052 {
18053 struct face *face = FACE_FROM_ID (f, face_id);
18054
18055 if (!multibyte_p)
18056 {
18057 /* Unibyte case. We don't have to encode, but we have to make
18058 sure to use a face suitable for unibyte. */
18059 STORE_XCHAR2B (char2b, 0, c);
18060 face_id = FACE_FOR_CHAR (f, face, c);
18061 face = FACE_FROM_ID (f, face_id);
18062 }
18063 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
18064 {
18065 /* Case of ASCII in a face known to fit ASCII. */
18066 STORE_XCHAR2B (char2b, 0, c);
18067 }
18068 else
18069 {
18070 int c1, c2, charset;
18071
18072 /* Split characters into bytes. If c2 is -1 afterwards, C is
18073 really a one-byte character so that byte1 is zero. */
18074 SPLIT_CHAR (c, charset, c1, c2);
18075 if (c2 > 0)
18076 STORE_XCHAR2B (char2b, c1, c2);
18077 else
18078 STORE_XCHAR2B (char2b, 0, c1);
18079
18080 /* Maybe encode the character in *CHAR2B. */
18081 if (face->font != NULL)
18082 {
18083 struct font_info *font_info
18084 = FONT_INFO_FROM_ID (f, face->font_info_id);
18085 if (font_info)
18086 rif->encode_char (c, char2b, font_info, 0);
18087 }
18088 }
18089
18090 /* Make sure X resources of the face are allocated. */
18091 #ifdef HAVE_X_WINDOWS
18092 if (display_p)
18093 #endif
18094 {
18095 xassert (face != NULL);
18096 PREPARE_FACE_FOR_DISPLAY (f, face);
18097 }
18098
18099 return face;
18100 }
18101
18102
18103 /* Set background width of glyph string S. START is the index of the
18104 first glyph following S. LAST_X is the right-most x-position + 1
18105 in the drawing area. */
18106
18107 static INLINE void
18108 set_glyph_string_background_width (s, start, last_x)
18109 struct glyph_string *s;
18110 int start;
18111 int last_x;
18112 {
18113 /* If the face of this glyph string has to be drawn to the end of
18114 the drawing area, set S->extends_to_end_of_line_p. */
18115 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
18116
18117 if (start == s->row->used[s->area]
18118 && s->area == TEXT_AREA
18119 && ((s->hl == DRAW_NORMAL_TEXT
18120 && (s->row->fill_line_p
18121 || s->face->background != default_face->background
18122 || s->face->stipple != default_face->stipple
18123 || s->row->mouse_face_p))
18124 || s->hl == DRAW_MOUSE_FACE
18125 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
18126 && s->row->fill_line_p)))
18127 s->extends_to_end_of_line_p = 1;
18128
18129 /* If S extends its face to the end of the line, set its
18130 background_width to the distance to the right edge of the drawing
18131 area. */
18132 if (s->extends_to_end_of_line_p)
18133 s->background_width = last_x - s->x + 1;
18134 else
18135 s->background_width = s->width;
18136 }
18137
18138
18139 /* Compute overhangs and x-positions for glyph string S and its
18140 predecessors, or successors. X is the starting x-position for S.
18141 BACKWARD_P non-zero means process predecessors. */
18142
18143 static void
18144 compute_overhangs_and_x (s, x, backward_p)
18145 struct glyph_string *s;
18146 int x;
18147 int backward_p;
18148 {
18149 if (backward_p)
18150 {
18151 while (s)
18152 {
18153 if (rif->compute_glyph_string_overhangs)
18154 rif->compute_glyph_string_overhangs (s);
18155 x -= s->width;
18156 s->x = x;
18157 s = s->prev;
18158 }
18159 }
18160 else
18161 {
18162 while (s)
18163 {
18164 if (rif->compute_glyph_string_overhangs)
18165 rif->compute_glyph_string_overhangs (s);
18166 s->x = x;
18167 x += s->width;
18168 s = s->next;
18169 }
18170 }
18171 }
18172
18173
18174
18175 /* The following macros are only called from draw_glyphs below.
18176 They reference the following parameters of that function directly:
18177 `w', `row', `area', and `overlap_p'
18178 as well as the following local variables:
18179 `s', `f', and `hdc' (in W32) */
18180
18181 #ifdef HAVE_NTGUI
18182 /* On W32, silently add local `hdc' variable to argument list of
18183 init_glyph_string. */
18184 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18185 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
18186 #else
18187 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18188 init_glyph_string (s, char2b, w, row, area, start, hl)
18189 #endif
18190
18191 /* Add a glyph string for a stretch glyph to the list of strings
18192 between HEAD and TAIL. START is the index of the stretch glyph in
18193 row area AREA of glyph row ROW. END is the index of the last glyph
18194 in that glyph row area. X is the current output position assigned
18195 to the new glyph string constructed. HL overrides that face of the
18196 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18197 is the right-most x-position of the drawing area. */
18198
18199 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
18200 and below -- keep them on one line. */
18201 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18202 do \
18203 { \
18204 s = (struct glyph_string *) alloca (sizeof *s); \
18205 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18206 START = fill_stretch_glyph_string (s, row, area, START, END); \
18207 append_glyph_string (&HEAD, &TAIL, s); \
18208 s->x = (X); \
18209 } \
18210 while (0)
18211
18212
18213 /* Add a glyph string for an image glyph to the list of strings
18214 between HEAD and TAIL. START is the index of the image glyph in
18215 row area AREA of glyph row ROW. END is the index of the last glyph
18216 in that glyph row area. X is the current output position assigned
18217 to the new glyph string constructed. HL overrides that face of the
18218 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18219 is the right-most x-position of the drawing area. */
18220
18221 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18222 do \
18223 { \
18224 s = (struct glyph_string *) alloca (sizeof *s); \
18225 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18226 fill_image_glyph_string (s); \
18227 append_glyph_string (&HEAD, &TAIL, s); \
18228 ++START; \
18229 s->x = (X); \
18230 } \
18231 while (0)
18232
18233
18234 /* Add a glyph string for a sequence of character glyphs to the list
18235 of strings between HEAD and TAIL. START is the index of the first
18236 glyph in row area AREA of glyph row ROW that is part of the new
18237 glyph string. END is the index of the last glyph in that glyph row
18238 area. X is the current output position assigned to the new glyph
18239 string constructed. HL overrides that face of the glyph; e.g. it
18240 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18241 right-most x-position of the drawing area. */
18242
18243 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18244 do \
18245 { \
18246 int c, face_id; \
18247 XChar2b *char2b; \
18248 \
18249 c = (row)->glyphs[area][START].u.ch; \
18250 face_id = (row)->glyphs[area][START].face_id; \
18251 \
18252 s = (struct glyph_string *) alloca (sizeof *s); \
18253 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18254 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18255 append_glyph_string (&HEAD, &TAIL, s); \
18256 s->x = (X); \
18257 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18258 } \
18259 while (0)
18260
18261
18262 /* Add a glyph string for a composite sequence to the list of strings
18263 between HEAD and TAIL. START is the index of the first glyph in
18264 row area AREA of glyph row ROW that is part of the new glyph
18265 string. END is the index of the last glyph in that glyph row area.
18266 X is the current output position assigned to the new glyph string
18267 constructed. HL overrides that face of the glyph; e.g. it is
18268 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18269 x-position of the drawing area. */
18270
18271 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18272 do { \
18273 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18274 int face_id = (row)->glyphs[area][START].face_id; \
18275 struct face *base_face = FACE_FROM_ID (f, face_id); \
18276 struct composition *cmp = composition_table[cmp_id]; \
18277 int glyph_len = cmp->glyph_len; \
18278 XChar2b *char2b; \
18279 struct face **faces; \
18280 struct glyph_string *first_s = NULL; \
18281 int n; \
18282 \
18283 base_face = base_face->ascii_face; \
18284 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18285 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18286 /* At first, fill in `char2b' and `faces'. */ \
18287 for (n = 0; n < glyph_len; n++) \
18288 { \
18289 int c = COMPOSITION_GLYPH (cmp, n); \
18290 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18291 faces[n] = FACE_FROM_ID (f, this_face_id); \
18292 get_char_face_and_encoding (f, c, this_face_id, \
18293 char2b + n, 1, 1); \
18294 } \
18295 \
18296 /* Make glyph_strings for each glyph sequence that is drawable by \
18297 the same face, and append them to HEAD/TAIL. */ \
18298 for (n = 0; n < cmp->glyph_len;) \
18299 { \
18300 s = (struct glyph_string *) alloca (sizeof *s); \
18301 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18302 append_glyph_string (&(HEAD), &(TAIL), s); \
18303 s->cmp = cmp; \
18304 s->gidx = n; \
18305 s->x = (X); \
18306 \
18307 if (n == 0) \
18308 first_s = s; \
18309 \
18310 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18311 } \
18312 \
18313 ++START; \
18314 s = first_s; \
18315 } while (0)
18316
18317
18318 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18319 of AREA of glyph row ROW on window W between indices START and END.
18320 HL overrides the face for drawing glyph strings, e.g. it is
18321 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18322 x-positions of the drawing area.
18323
18324 This is an ugly monster macro construct because we must use alloca
18325 to allocate glyph strings (because draw_glyphs can be called
18326 asynchronously). */
18327
18328 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18329 do \
18330 { \
18331 HEAD = TAIL = NULL; \
18332 while (START < END) \
18333 { \
18334 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18335 switch (first_glyph->type) \
18336 { \
18337 case CHAR_GLYPH: \
18338 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18339 HL, X, LAST_X); \
18340 break; \
18341 \
18342 case COMPOSITE_GLYPH: \
18343 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18344 HL, X, LAST_X); \
18345 break; \
18346 \
18347 case STRETCH_GLYPH: \
18348 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18349 HL, X, LAST_X); \
18350 break; \
18351 \
18352 case IMAGE_GLYPH: \
18353 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18354 HL, X, LAST_X); \
18355 break; \
18356 \
18357 default: \
18358 abort (); \
18359 } \
18360 \
18361 set_glyph_string_background_width (s, START, LAST_X); \
18362 (X) += s->width; \
18363 } \
18364 } \
18365 while (0)
18366
18367
18368 /* Draw glyphs between START and END in AREA of ROW on window W,
18369 starting at x-position X. X is relative to AREA in W. HL is a
18370 face-override with the following meaning:
18371
18372 DRAW_NORMAL_TEXT draw normally
18373 DRAW_CURSOR draw in cursor face
18374 DRAW_MOUSE_FACE draw in mouse face.
18375 DRAW_INVERSE_VIDEO draw in mode line face
18376 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18377 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18378
18379 If OVERLAPS_P is non-zero, draw only the foreground of characters
18380 and clip to the physical height of ROW.
18381
18382 Value is the x-position reached, relative to AREA of W. */
18383
18384 static int
18385 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18386 struct window *w;
18387 int x;
18388 struct glyph_row *row;
18389 enum glyph_row_area area;
18390 int start, end;
18391 enum draw_glyphs_face hl;
18392 int overlaps_p;
18393 {
18394 struct glyph_string *head, *tail;
18395 struct glyph_string *s;
18396 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
18397 int last_x, area_width;
18398 int x_reached;
18399 int i, j;
18400 struct frame *f = XFRAME (WINDOW_FRAME (w));
18401 DECLARE_HDC (hdc);
18402
18403 ALLOCATE_HDC (hdc, f);
18404
18405 /* Let's rather be paranoid than getting a SEGV. */
18406 end = min (end, row->used[area]);
18407 start = max (0, start);
18408 start = min (end, start);
18409
18410 /* Translate X to frame coordinates. Set last_x to the right
18411 end of the drawing area. */
18412 if (row->full_width_p)
18413 {
18414 /* X is relative to the left edge of W, without scroll bars
18415 or fringes. */
18416 x += WINDOW_LEFT_EDGE_X (w);
18417 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18418 }
18419 else
18420 {
18421 int area_left = window_box_left (w, area);
18422 x += area_left;
18423 area_width = window_box_width (w, area);
18424 last_x = area_left + area_width;
18425 }
18426
18427 /* Build a doubly-linked list of glyph_string structures between
18428 head and tail from what we have to draw. Note that the macro
18429 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18430 the reason we use a separate variable `i'. */
18431 i = start;
18432 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18433 if (tail)
18434 x_reached = tail->x + tail->background_width;
18435 else
18436 x_reached = x;
18437
18438 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18439 the row, redraw some glyphs in front or following the glyph
18440 strings built above. */
18441 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18442 {
18443 int dummy_x = 0;
18444 struct glyph_string *h, *t;
18445
18446 /* Compute overhangs for all glyph strings. */
18447 if (rif->compute_glyph_string_overhangs)
18448 for (s = head; s; s = s->next)
18449 rif->compute_glyph_string_overhangs (s);
18450
18451 /* Prepend glyph strings for glyphs in front of the first glyph
18452 string that are overwritten because of the first glyph
18453 string's left overhang. The background of all strings
18454 prepended must be drawn because the first glyph string
18455 draws over it. */
18456 i = left_overwritten (head);
18457 if (i >= 0)
18458 {
18459 j = i;
18460 BUILD_GLYPH_STRINGS (j, start, h, t,
18461 DRAW_NORMAL_TEXT, dummy_x, last_x);
18462 start = i;
18463 compute_overhangs_and_x (t, head->x, 1);
18464 prepend_glyph_string_lists (&head, &tail, h, t);
18465 clip_head = head;
18466 }
18467
18468 /* Prepend glyph strings for glyphs in front of the first glyph
18469 string that overwrite that glyph string because of their
18470 right overhang. For these strings, only the foreground must
18471 be drawn, because it draws over the glyph string at `head'.
18472 The background must not be drawn because this would overwrite
18473 right overhangs of preceding glyphs for which no glyph
18474 strings exist. */
18475 i = left_overwriting (head);
18476 if (i >= 0)
18477 {
18478 clip_head = head;
18479 BUILD_GLYPH_STRINGS (i, start, h, t,
18480 DRAW_NORMAL_TEXT, dummy_x, last_x);
18481 for (s = h; s; s = s->next)
18482 s->background_filled_p = 1;
18483 compute_overhangs_and_x (t, head->x, 1);
18484 prepend_glyph_string_lists (&head, &tail, h, t);
18485 }
18486
18487 /* Append glyphs strings for glyphs following the last glyph
18488 string tail that are overwritten by tail. The background of
18489 these strings has to be drawn because tail's foreground draws
18490 over it. */
18491 i = right_overwritten (tail);
18492 if (i >= 0)
18493 {
18494 BUILD_GLYPH_STRINGS (end, i, h, t,
18495 DRAW_NORMAL_TEXT, x, last_x);
18496 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18497 append_glyph_string_lists (&head, &tail, h, t);
18498 clip_tail = tail;
18499 }
18500
18501 /* Append glyph strings for glyphs following the last glyph
18502 string tail that overwrite tail. The foreground of such
18503 glyphs has to be drawn because it writes into the background
18504 of tail. The background must not be drawn because it could
18505 paint over the foreground of following glyphs. */
18506 i = right_overwriting (tail);
18507 if (i >= 0)
18508 {
18509 clip_tail = tail;
18510 BUILD_GLYPH_STRINGS (end, i, h, t,
18511 DRAW_NORMAL_TEXT, x, last_x);
18512 for (s = h; s; s = s->next)
18513 s->background_filled_p = 1;
18514 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18515 append_glyph_string_lists (&head, &tail, h, t);
18516 }
18517 if (clip_head || clip_tail)
18518 for (s = head; s; s = s->next)
18519 {
18520 s->clip_head = clip_head;
18521 s->clip_tail = clip_tail;
18522 }
18523 }
18524
18525 /* Draw all strings. */
18526 for (s = head; s; s = s->next)
18527 rif->draw_glyph_string (s);
18528
18529 if (area == TEXT_AREA
18530 && !row->full_width_p
18531 /* When drawing overlapping rows, only the glyph strings'
18532 foreground is drawn, which doesn't erase a cursor
18533 completely. */
18534 && !overlaps_p)
18535 {
18536 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
18537 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
18538 : (tail ? tail->x + tail->background_width : x));
18539
18540 int text_left = window_box_left (w, TEXT_AREA);
18541 x0 -= text_left;
18542 x1 -= text_left;
18543
18544 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18545 row->y, MATRIX_ROW_BOTTOM_Y (row));
18546 }
18547
18548 /* Value is the x-position up to which drawn, relative to AREA of W.
18549 This doesn't include parts drawn because of overhangs. */
18550 if (row->full_width_p)
18551 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18552 else
18553 x_reached -= window_box_left (w, area);
18554
18555 RELEASE_HDC (hdc, f);
18556
18557 return x_reached;
18558 }
18559
18560 /* Expand row matrix if too narrow. Don't expand if area
18561 is not present. */
18562
18563 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18564 { \
18565 if (!fonts_changed_p \
18566 && (it->glyph_row->glyphs[area] \
18567 < it->glyph_row->glyphs[area + 1])) \
18568 { \
18569 it->w->ncols_scale_factor++; \
18570 fonts_changed_p = 1; \
18571 } \
18572 }
18573
18574 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18575 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18576
18577 static INLINE void
18578 append_glyph (it)
18579 struct it *it;
18580 {
18581 struct glyph *glyph;
18582 enum glyph_row_area area = it->area;
18583
18584 xassert (it->glyph_row);
18585 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18586
18587 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18588 if (glyph < it->glyph_row->glyphs[area + 1])
18589 {
18590 glyph->charpos = CHARPOS (it->position);
18591 glyph->object = it->object;
18592 glyph->pixel_width = it->pixel_width;
18593 glyph->ascent = it->ascent;
18594 glyph->descent = it->descent;
18595 glyph->voffset = it->voffset;
18596 glyph->type = CHAR_GLYPH;
18597 glyph->multibyte_p = it->multibyte_p;
18598 glyph->left_box_line_p = it->start_of_box_run_p;
18599 glyph->right_box_line_p = it->end_of_box_run_p;
18600 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18601 || it->phys_descent > it->descent);
18602 glyph->padding_p = 0;
18603 glyph->glyph_not_available_p = it->glyph_not_available_p;
18604 glyph->face_id = it->face_id;
18605 glyph->u.ch = it->char_to_display;
18606 glyph->slice = null_glyph_slice;
18607 glyph->font_type = FONT_TYPE_UNKNOWN;
18608 ++it->glyph_row->used[area];
18609 }
18610 else
18611 IT_EXPAND_MATRIX_WIDTH (it, area);
18612 }
18613
18614 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18615 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18616
18617 static INLINE void
18618 append_composite_glyph (it)
18619 struct it *it;
18620 {
18621 struct glyph *glyph;
18622 enum glyph_row_area area = it->area;
18623
18624 xassert (it->glyph_row);
18625
18626 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18627 if (glyph < it->glyph_row->glyphs[area + 1])
18628 {
18629 glyph->charpos = CHARPOS (it->position);
18630 glyph->object = it->object;
18631 glyph->pixel_width = it->pixel_width;
18632 glyph->ascent = it->ascent;
18633 glyph->descent = it->descent;
18634 glyph->voffset = it->voffset;
18635 glyph->type = COMPOSITE_GLYPH;
18636 glyph->multibyte_p = it->multibyte_p;
18637 glyph->left_box_line_p = it->start_of_box_run_p;
18638 glyph->right_box_line_p = it->end_of_box_run_p;
18639 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18640 || it->phys_descent > it->descent);
18641 glyph->padding_p = 0;
18642 glyph->glyph_not_available_p = 0;
18643 glyph->face_id = it->face_id;
18644 glyph->u.cmp_id = it->cmp_id;
18645 glyph->slice = null_glyph_slice;
18646 glyph->font_type = FONT_TYPE_UNKNOWN;
18647 ++it->glyph_row->used[area];
18648 }
18649 else
18650 IT_EXPAND_MATRIX_WIDTH (it, area);
18651 }
18652
18653
18654 /* Change IT->ascent and IT->height according to the setting of
18655 IT->voffset. */
18656
18657 static INLINE void
18658 take_vertical_position_into_account (it)
18659 struct it *it;
18660 {
18661 if (it->voffset)
18662 {
18663 if (it->voffset < 0)
18664 /* Increase the ascent so that we can display the text higher
18665 in the line. */
18666 it->ascent -= it->voffset;
18667 else
18668 /* Increase the descent so that we can display the text lower
18669 in the line. */
18670 it->descent += it->voffset;
18671 }
18672 }
18673
18674
18675 /* Produce glyphs/get display metrics for the image IT is loaded with.
18676 See the description of struct display_iterator in dispextern.h for
18677 an overview of struct display_iterator. */
18678
18679 static void
18680 produce_image_glyph (it)
18681 struct it *it;
18682 {
18683 struct image *img;
18684 struct face *face;
18685 int glyph_ascent;
18686 struct glyph_slice slice;
18687
18688 xassert (it->what == IT_IMAGE);
18689
18690 face = FACE_FROM_ID (it->f, it->face_id);
18691 xassert (face);
18692 /* Make sure X resources of the face is loaded. */
18693 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18694
18695 if (it->image_id < 0)
18696 {
18697 /* Fringe bitmap. */
18698 it->ascent = it->phys_ascent = 0;
18699 it->descent = it->phys_descent = 0;
18700 it->pixel_width = 0;
18701 it->nglyphs = 0;
18702 return;
18703 }
18704
18705 img = IMAGE_FROM_ID (it->f, it->image_id);
18706 xassert (img);
18707 /* Make sure X resources of the image is loaded. */
18708 prepare_image_for_display (it->f, img);
18709
18710 slice.x = slice.y = 0;
18711 slice.width = img->width;
18712 slice.height = img->height;
18713
18714 if (INTEGERP (it->slice.x))
18715 slice.x = XINT (it->slice.x);
18716 else if (FLOATP (it->slice.x))
18717 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18718
18719 if (INTEGERP (it->slice.y))
18720 slice.y = XINT (it->slice.y);
18721 else if (FLOATP (it->slice.y))
18722 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18723
18724 if (INTEGERP (it->slice.width))
18725 slice.width = XINT (it->slice.width);
18726 else if (FLOATP (it->slice.width))
18727 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18728
18729 if (INTEGERP (it->slice.height))
18730 slice.height = XINT (it->slice.height);
18731 else if (FLOATP (it->slice.height))
18732 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18733
18734 if (slice.x >= img->width)
18735 slice.x = img->width;
18736 if (slice.y >= img->height)
18737 slice.y = img->height;
18738 if (slice.x + slice.width >= img->width)
18739 slice.width = img->width - slice.x;
18740 if (slice.y + slice.height > img->height)
18741 slice.height = img->height - slice.y;
18742
18743 if (slice.width == 0 || slice.height == 0)
18744 return;
18745
18746 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18747
18748 it->descent = slice.height - glyph_ascent;
18749 if (slice.y == 0)
18750 it->descent += img->vmargin;
18751 if (slice.y + slice.height == img->height)
18752 it->descent += img->vmargin;
18753 it->phys_descent = it->descent;
18754
18755 it->pixel_width = slice.width;
18756 if (slice.x == 0)
18757 it->pixel_width += img->hmargin;
18758 if (slice.x + slice.width == img->width)
18759 it->pixel_width += img->hmargin;
18760
18761 /* It's quite possible for images to have an ascent greater than
18762 their height, so don't get confused in that case. */
18763 if (it->descent < 0)
18764 it->descent = 0;
18765
18766 #if 0 /* this breaks image tiling */
18767 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18768 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18769 if (face_ascent > it->ascent)
18770 it->ascent = it->phys_ascent = face_ascent;
18771 #endif
18772
18773 it->nglyphs = 1;
18774
18775 if (face->box != FACE_NO_BOX)
18776 {
18777 if (face->box_line_width > 0)
18778 {
18779 if (slice.y == 0)
18780 it->ascent += face->box_line_width;
18781 if (slice.y + slice.height == img->height)
18782 it->descent += face->box_line_width;
18783 }
18784
18785 if (it->start_of_box_run_p && slice.x == 0)
18786 it->pixel_width += abs (face->box_line_width);
18787 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18788 it->pixel_width += abs (face->box_line_width);
18789 }
18790
18791 take_vertical_position_into_account (it);
18792
18793 if (it->glyph_row)
18794 {
18795 struct glyph *glyph;
18796 enum glyph_row_area area = it->area;
18797
18798 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18799 if (glyph < it->glyph_row->glyphs[area + 1])
18800 {
18801 glyph->charpos = CHARPOS (it->position);
18802 glyph->object = it->object;
18803 glyph->pixel_width = it->pixel_width;
18804 glyph->ascent = glyph_ascent;
18805 glyph->descent = it->descent;
18806 glyph->voffset = it->voffset;
18807 glyph->type = IMAGE_GLYPH;
18808 glyph->multibyte_p = it->multibyte_p;
18809 glyph->left_box_line_p = it->start_of_box_run_p;
18810 glyph->right_box_line_p = it->end_of_box_run_p;
18811 glyph->overlaps_vertically_p = 0;
18812 glyph->padding_p = 0;
18813 glyph->glyph_not_available_p = 0;
18814 glyph->face_id = it->face_id;
18815 glyph->u.img_id = img->id;
18816 glyph->slice = slice;
18817 glyph->font_type = FONT_TYPE_UNKNOWN;
18818 ++it->glyph_row->used[area];
18819 }
18820 else
18821 IT_EXPAND_MATRIX_WIDTH (it, area);
18822 }
18823 }
18824
18825
18826 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18827 of the glyph, WIDTH and HEIGHT are the width and height of the
18828 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18829
18830 static void
18831 append_stretch_glyph (it, object, width, height, ascent)
18832 struct it *it;
18833 Lisp_Object object;
18834 int width, height;
18835 int ascent;
18836 {
18837 struct glyph *glyph;
18838 enum glyph_row_area area = it->area;
18839
18840 xassert (ascent >= 0 && ascent <= height);
18841
18842 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18843 if (glyph < it->glyph_row->glyphs[area + 1])
18844 {
18845 glyph->charpos = CHARPOS (it->position);
18846 glyph->object = object;
18847 glyph->pixel_width = width;
18848 glyph->ascent = ascent;
18849 glyph->descent = height - ascent;
18850 glyph->voffset = it->voffset;
18851 glyph->type = STRETCH_GLYPH;
18852 glyph->multibyte_p = it->multibyte_p;
18853 glyph->left_box_line_p = it->start_of_box_run_p;
18854 glyph->right_box_line_p = it->end_of_box_run_p;
18855 glyph->overlaps_vertically_p = 0;
18856 glyph->padding_p = 0;
18857 glyph->glyph_not_available_p = 0;
18858 glyph->face_id = it->face_id;
18859 glyph->u.stretch.ascent = ascent;
18860 glyph->u.stretch.height = height;
18861 glyph->slice = null_glyph_slice;
18862 glyph->font_type = FONT_TYPE_UNKNOWN;
18863 ++it->glyph_row->used[area];
18864 }
18865 else
18866 IT_EXPAND_MATRIX_WIDTH (it, area);
18867 }
18868
18869
18870 /* Produce a stretch glyph for iterator IT. IT->object is the value
18871 of the glyph property displayed. The value must be a list
18872 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18873 being recognized:
18874
18875 1. `:width WIDTH' specifies that the space should be WIDTH *
18876 canonical char width wide. WIDTH may be an integer or floating
18877 point number.
18878
18879 2. `:relative-width FACTOR' specifies that the width of the stretch
18880 should be computed from the width of the first character having the
18881 `glyph' property, and should be FACTOR times that width.
18882
18883 3. `:align-to HPOS' specifies that the space should be wide enough
18884 to reach HPOS, a value in canonical character units.
18885
18886 Exactly one of the above pairs must be present.
18887
18888 4. `:height HEIGHT' specifies that the height of the stretch produced
18889 should be HEIGHT, measured in canonical character units.
18890
18891 5. `:relative-height FACTOR' specifies that the height of the
18892 stretch should be FACTOR times the height of the characters having
18893 the glyph property.
18894
18895 Either none or exactly one of 4 or 5 must be present.
18896
18897 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18898 of the stretch should be used for the ascent of the stretch.
18899 ASCENT must be in the range 0 <= ASCENT <= 100. */
18900
18901 static void
18902 produce_stretch_glyph (it)
18903 struct it *it;
18904 {
18905 /* (space :width WIDTH :height HEIGHT ...) */
18906 Lisp_Object prop, plist;
18907 int width = 0, height = 0, align_to = -1;
18908 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18909 int ascent = 0;
18910 double tem;
18911 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18912 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18913
18914 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18915
18916 /* List should start with `space'. */
18917 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18918 plist = XCDR (it->object);
18919
18920 /* Compute the width of the stretch. */
18921 if ((prop = Fsafe_plist_get (plist, QCwidth), !NILP (prop))
18922 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18923 {
18924 /* Absolute width `:width WIDTH' specified and valid. */
18925 zero_width_ok_p = 1;
18926 width = (int)tem;
18927 }
18928 else if (prop = Fsafe_plist_get (plist, QCrelative_width),
18929 NUMVAL (prop) > 0)
18930 {
18931 /* Relative width `:relative-width FACTOR' specified and valid.
18932 Compute the width of the characters having the `glyph'
18933 property. */
18934 struct it it2;
18935 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18936
18937 it2 = *it;
18938 if (it->multibyte_p)
18939 {
18940 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18941 - IT_BYTEPOS (*it));
18942 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18943 }
18944 else
18945 it2.c = *p, it2.len = 1;
18946
18947 it2.glyph_row = NULL;
18948 it2.what = IT_CHARACTER;
18949 x_produce_glyphs (&it2);
18950 width = NUMVAL (prop) * it2.pixel_width;
18951 }
18952 else if ((prop = Fsafe_plist_get (plist, QCalign_to), !NILP (prop))
18953 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18954 {
18955 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18956 align_to = (align_to < 0
18957 ? 0
18958 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18959 else if (align_to < 0)
18960 align_to = window_box_left_offset (it->w, TEXT_AREA);
18961 width = max (0, (int)tem + align_to - it->current_x);
18962 zero_width_ok_p = 1;
18963 }
18964 else
18965 /* Nothing specified -> width defaults to canonical char width. */
18966 width = FRAME_COLUMN_WIDTH (it->f);
18967
18968 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18969 width = 1;
18970
18971 /* Compute height. */
18972 if ((prop = Fsafe_plist_get (plist, QCheight), !NILP (prop))
18973 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18974 {
18975 height = (int)tem;
18976 zero_height_ok_p = 1;
18977 }
18978 else if (prop = Fsafe_plist_get (plist, QCrelative_height),
18979 NUMVAL (prop) > 0)
18980 height = FONT_HEIGHT (font) * NUMVAL (prop);
18981 else
18982 height = FONT_HEIGHT (font);
18983
18984 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18985 height = 1;
18986
18987 /* Compute percentage of height used for ascent. If
18988 `:ascent ASCENT' is present and valid, use that. Otherwise,
18989 derive the ascent from the font in use. */
18990 if (prop = Fsafe_plist_get (plist, QCascent),
18991 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18992 ascent = height * NUMVAL (prop) / 100.0;
18993 else if (!NILP (prop)
18994 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18995 ascent = min (max (0, (int)tem), height);
18996 else
18997 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18998
18999 if (width > 0 && height > 0 && it->glyph_row)
19000 {
19001 Lisp_Object object = it->stack[it->sp - 1].string;
19002 if (!STRINGP (object))
19003 object = it->w->buffer;
19004 append_stretch_glyph (it, object, width, height, ascent);
19005 }
19006
19007 it->pixel_width = width;
19008 it->ascent = it->phys_ascent = ascent;
19009 it->descent = it->phys_descent = height - it->ascent;
19010 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
19011
19012 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
19013 {
19014 if (face->box_line_width > 0)
19015 {
19016 it->ascent += face->box_line_width;
19017 it->descent += face->box_line_width;
19018 }
19019
19020 if (it->start_of_box_run_p)
19021 it->pixel_width += abs (face->box_line_width);
19022 if (it->end_of_box_run_p)
19023 it->pixel_width += abs (face->box_line_width);
19024 }
19025
19026 take_vertical_position_into_account (it);
19027 }
19028
19029 /* Get line-height and line-spacing property at point.
19030 If line-height has format (HEIGHT TOTAL), return TOTAL
19031 in TOTAL_HEIGHT. */
19032
19033 static Lisp_Object
19034 get_line_height_property (it, prop)
19035 struct it *it;
19036 Lisp_Object prop;
19037 {
19038 Lisp_Object position, val;
19039
19040 if (STRINGP (it->object))
19041 position = make_number (IT_STRING_CHARPOS (*it));
19042 else if (BUFFERP (it->object))
19043 position = make_number (IT_CHARPOS (*it));
19044 else
19045 return Qnil;
19046
19047 return Fget_char_property (position, prop, it->object);
19048 }
19049
19050 /* Calculate line-height and line-spacing properties.
19051 An integer value specifies explicit pixel value.
19052 A float value specifies relative value to current face height.
19053 A cons (float . face-name) specifies relative value to
19054 height of specified face font.
19055
19056 Returns height in pixels, or nil. */
19057
19058
19059 static Lisp_Object
19060 calc_line_height_property (it, val, font, boff, override)
19061 struct it *it;
19062 Lisp_Object val;
19063 XFontStruct *font;
19064 int boff, override;
19065 {
19066 Lisp_Object face_name = Qnil;
19067 int ascent, descent, height;
19068
19069 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
19070 return val;
19071
19072 if (CONSP (val))
19073 {
19074 face_name = XCAR (val);
19075 val = XCDR (val);
19076 if (!NUMBERP (val))
19077 val = make_number (1);
19078 if (NILP (face_name))
19079 {
19080 height = it->ascent + it->descent;
19081 goto scale;
19082 }
19083 }
19084
19085 if (NILP (face_name))
19086 {
19087 font = FRAME_FONT (it->f);
19088 boff = FRAME_BASELINE_OFFSET (it->f);
19089 }
19090 else if (EQ (face_name, Qt))
19091 {
19092 override = 0;
19093 }
19094 else
19095 {
19096 int face_id;
19097 struct face *face;
19098 struct font_info *font_info;
19099
19100 face_id = lookup_named_face (it->f, face_name, ' ', 0);
19101 if (face_id < 0)
19102 return make_number (-1);
19103
19104 face = FACE_FROM_ID (it->f, face_id);
19105 font = face->font;
19106 if (font == NULL)
19107 return make_number (-1);
19108
19109 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19110 boff = font_info->baseline_offset;
19111 if (font_info->vertical_centering)
19112 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19113 }
19114
19115 ascent = FONT_BASE (font) + boff;
19116 descent = FONT_DESCENT (font) - boff;
19117
19118 if (override)
19119 {
19120 it->override_ascent = ascent;
19121 it->override_descent = descent;
19122 it->override_boff = boff;
19123 }
19124
19125 height = ascent + descent;
19126
19127 scale:
19128 if (FLOATP (val))
19129 height = (int)(XFLOAT_DATA (val) * height);
19130 else if (INTEGERP (val))
19131 height *= XINT (val);
19132
19133 return make_number (height);
19134 }
19135
19136
19137 /* RIF:
19138 Produce glyphs/get display metrics for the display element IT is
19139 loaded with. See the description of struct display_iterator in
19140 dispextern.h for an overview of struct display_iterator. */
19141
19142 void
19143 x_produce_glyphs (it)
19144 struct it *it;
19145 {
19146 int extra_line_spacing = it->extra_line_spacing;
19147
19148 it->glyph_not_available_p = 0;
19149
19150 if (it->what == IT_CHARACTER)
19151 {
19152 XChar2b char2b;
19153 XFontStruct *font;
19154 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19155 XCharStruct *pcm;
19156 int font_not_found_p;
19157 struct font_info *font_info;
19158 int boff; /* baseline offset */
19159 /* We may change it->multibyte_p upon unibyte<->multibyte
19160 conversion. So, save the current value now and restore it
19161 later.
19162
19163 Note: It seems that we don't have to record multibyte_p in
19164 struct glyph because the character code itself tells if or
19165 not the character is multibyte. Thus, in the future, we must
19166 consider eliminating the field `multibyte_p' in the struct
19167 glyph. */
19168 int saved_multibyte_p = it->multibyte_p;
19169
19170 /* Maybe translate single-byte characters to multibyte, or the
19171 other way. */
19172 it->char_to_display = it->c;
19173 if (!ASCII_BYTE_P (it->c))
19174 {
19175 if (unibyte_display_via_language_environment
19176 && SINGLE_BYTE_CHAR_P (it->c)
19177 && (it->c >= 0240
19178 || !NILP (Vnonascii_translation_table)))
19179 {
19180 it->char_to_display = unibyte_char_to_multibyte (it->c);
19181 it->multibyte_p = 1;
19182 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19183 face = FACE_FROM_ID (it->f, it->face_id);
19184 }
19185 else if (!SINGLE_BYTE_CHAR_P (it->c)
19186 && !it->multibyte_p)
19187 {
19188 it->multibyte_p = 1;
19189 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19190 face = FACE_FROM_ID (it->f, it->face_id);
19191 }
19192 }
19193
19194 /* Get font to use. Encode IT->char_to_display. */
19195 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19196 &char2b, it->multibyte_p, 0);
19197 font = face->font;
19198
19199 /* When no suitable font found, use the default font. */
19200 font_not_found_p = font == NULL;
19201 if (font_not_found_p)
19202 {
19203 font = FRAME_FONT (it->f);
19204 boff = FRAME_BASELINE_OFFSET (it->f);
19205 font_info = NULL;
19206 }
19207 else
19208 {
19209 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19210 boff = font_info->baseline_offset;
19211 if (font_info->vertical_centering)
19212 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19213 }
19214
19215 if (it->char_to_display >= ' '
19216 && (!it->multibyte_p || it->char_to_display < 128))
19217 {
19218 /* Either unibyte or ASCII. */
19219 int stretched_p;
19220
19221 it->nglyphs = 1;
19222
19223 pcm = rif->per_char_metric (font, &char2b,
19224 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
19225
19226 if (it->override_ascent >= 0)
19227 {
19228 it->ascent = it->override_ascent;
19229 it->descent = it->override_descent;
19230 boff = it->override_boff;
19231 }
19232 else
19233 {
19234 it->ascent = FONT_BASE (font) + boff;
19235 it->descent = FONT_DESCENT (font) - boff;
19236 }
19237
19238 if (pcm)
19239 {
19240 it->phys_ascent = pcm->ascent + boff;
19241 it->phys_descent = pcm->descent - boff;
19242 it->pixel_width = pcm->width;
19243 }
19244 else
19245 {
19246 it->glyph_not_available_p = 1;
19247 it->phys_ascent = it->ascent;
19248 it->phys_descent = it->descent;
19249 it->pixel_width = FONT_WIDTH (font);
19250 }
19251
19252 if (it->constrain_row_ascent_descent_p)
19253 {
19254 if (it->descent > it->max_descent)
19255 {
19256 it->ascent += it->descent - it->max_descent;
19257 it->descent = it->max_descent;
19258 }
19259 if (it->ascent > it->max_ascent)
19260 {
19261 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19262 it->ascent = it->max_ascent;
19263 }
19264 it->phys_ascent = min (it->phys_ascent, it->ascent);
19265 it->phys_descent = min (it->phys_descent, it->descent);
19266 extra_line_spacing = 0;
19267 }
19268
19269 /* If this is a space inside a region of text with
19270 `space-width' property, change its width. */
19271 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19272 if (stretched_p)
19273 it->pixel_width *= XFLOATINT (it->space_width);
19274
19275 /* If face has a box, add the box thickness to the character
19276 height. If character has a box line to the left and/or
19277 right, add the box line width to the character's width. */
19278 if (face->box != FACE_NO_BOX)
19279 {
19280 int thick = face->box_line_width;
19281
19282 if (thick > 0)
19283 {
19284 it->ascent += thick;
19285 it->descent += thick;
19286 }
19287 else
19288 thick = -thick;
19289
19290 if (it->start_of_box_run_p)
19291 it->pixel_width += thick;
19292 if (it->end_of_box_run_p)
19293 it->pixel_width += thick;
19294 }
19295
19296 /* If face has an overline, add the height of the overline
19297 (1 pixel) and a 1 pixel margin to the character height. */
19298 if (face->overline_p)
19299 it->ascent += 2;
19300
19301 if (it->constrain_row_ascent_descent_p)
19302 {
19303 if (it->ascent > it->max_ascent)
19304 it->ascent = it->max_ascent;
19305 if (it->descent > it->max_descent)
19306 it->descent = it->max_descent;
19307 }
19308
19309 take_vertical_position_into_account (it);
19310
19311 /* If we have to actually produce glyphs, do it. */
19312 if (it->glyph_row)
19313 {
19314 if (stretched_p)
19315 {
19316 /* Translate a space with a `space-width' property
19317 into a stretch glyph. */
19318 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19319 / FONT_HEIGHT (font));
19320 append_stretch_glyph (it, it->object, it->pixel_width,
19321 it->ascent + it->descent, ascent);
19322 }
19323 else
19324 append_glyph (it);
19325
19326 /* If characters with lbearing or rbearing are displayed
19327 in this line, record that fact in a flag of the
19328 glyph row. This is used to optimize X output code. */
19329 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19330 it->glyph_row->contains_overlapping_glyphs_p = 1;
19331 }
19332 }
19333 else if (it->char_to_display == '\n')
19334 {
19335 /* A newline has no width but we need the height of the line.
19336 But if previous part of the line set a height, don't
19337 increase that height */
19338
19339 Lisp_Object height;
19340 Lisp_Object total_height = Qnil;
19341
19342 it->override_ascent = -1;
19343 it->pixel_width = 0;
19344 it->nglyphs = 0;
19345
19346 height = get_line_height_property(it, Qline_height);
19347 /* Split (line-height total-height) list */
19348 if (CONSP (height)
19349 && CONSP (XCDR (height))
19350 && NILP (XCDR (XCDR (height))))
19351 {
19352 total_height = XCAR (XCDR (height));
19353 height = XCAR (height);
19354 }
19355 height = calc_line_height_property(it, height, font, boff, 1);
19356
19357 if (it->override_ascent >= 0)
19358 {
19359 it->ascent = it->override_ascent;
19360 it->descent = it->override_descent;
19361 boff = it->override_boff;
19362 }
19363 else
19364 {
19365 it->ascent = FONT_BASE (font) + boff;
19366 it->descent = FONT_DESCENT (font) - boff;
19367 }
19368
19369 if (EQ (height, Qt))
19370 {
19371 if (it->descent > it->max_descent)
19372 {
19373 it->ascent += it->descent - it->max_descent;
19374 it->descent = it->max_descent;
19375 }
19376 if (it->ascent > it->max_ascent)
19377 {
19378 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19379 it->ascent = it->max_ascent;
19380 }
19381 it->phys_ascent = min (it->phys_ascent, it->ascent);
19382 it->phys_descent = min (it->phys_descent, it->descent);
19383 it->constrain_row_ascent_descent_p = 1;
19384 extra_line_spacing = 0;
19385 }
19386 else
19387 {
19388 Lisp_Object spacing;
19389 int total = 0;
19390
19391 it->phys_ascent = it->ascent;
19392 it->phys_descent = it->descent;
19393
19394 if ((it->max_ascent > 0 || it->max_descent > 0)
19395 && face->box != FACE_NO_BOX
19396 && face->box_line_width > 0)
19397 {
19398 it->ascent += face->box_line_width;
19399 it->descent += face->box_line_width;
19400 }
19401 if (!NILP (height)
19402 && XINT (height) > it->ascent + it->descent)
19403 it->ascent = XINT (height) - it->descent;
19404
19405 if (!NILP (total_height))
19406 spacing = calc_line_height_property(it, total_height, font, boff, 0);
19407 else
19408 {
19409 spacing = get_line_height_property(it, Qline_spacing);
19410 spacing = calc_line_height_property(it, spacing, font, boff, 0);
19411 }
19412 if (INTEGERP (spacing))
19413 {
19414 extra_line_spacing = XINT (spacing);
19415 if (!NILP (total_height))
19416 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19417 }
19418 }
19419 }
19420 else if (it->char_to_display == '\t')
19421 {
19422 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
19423 int x = it->current_x + it->continuation_lines_width;
19424 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19425
19426 /* If the distance from the current position to the next tab
19427 stop is less than a space character width, use the
19428 tab stop after that. */
19429 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
19430 next_tab_x += tab_width;
19431
19432 it->pixel_width = next_tab_x - x;
19433 it->nglyphs = 1;
19434 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19435 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19436
19437 if (it->glyph_row)
19438 {
19439 append_stretch_glyph (it, it->object, it->pixel_width,
19440 it->ascent + it->descent, it->ascent);
19441 }
19442 }
19443 else
19444 {
19445 /* A multi-byte character. Assume that the display width of the
19446 character is the width of the character multiplied by the
19447 width of the font. */
19448
19449 /* If we found a font, this font should give us the right
19450 metrics. If we didn't find a font, use the frame's
19451 default font and calculate the width of the character
19452 from the charset width; this is what old redisplay code
19453 did. */
19454
19455 pcm = rif->per_char_metric (font, &char2b,
19456 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19457
19458 if (font_not_found_p || !pcm)
19459 {
19460 int charset = CHAR_CHARSET (it->char_to_display);
19461
19462 it->glyph_not_available_p = 1;
19463 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19464 * CHARSET_WIDTH (charset));
19465 it->phys_ascent = FONT_BASE (font) + boff;
19466 it->phys_descent = FONT_DESCENT (font) - boff;
19467 }
19468 else
19469 {
19470 it->pixel_width = pcm->width;
19471 it->phys_ascent = pcm->ascent + boff;
19472 it->phys_descent = pcm->descent - boff;
19473 if (it->glyph_row
19474 && (pcm->lbearing < 0
19475 || pcm->rbearing > pcm->width))
19476 it->glyph_row->contains_overlapping_glyphs_p = 1;
19477 }
19478 it->nglyphs = 1;
19479 it->ascent = FONT_BASE (font) + boff;
19480 it->descent = FONT_DESCENT (font) - boff;
19481 if (face->box != FACE_NO_BOX)
19482 {
19483 int thick = face->box_line_width;
19484
19485 if (thick > 0)
19486 {
19487 it->ascent += thick;
19488 it->descent += thick;
19489 }
19490 else
19491 thick = - thick;
19492
19493 if (it->start_of_box_run_p)
19494 it->pixel_width += thick;
19495 if (it->end_of_box_run_p)
19496 it->pixel_width += thick;
19497 }
19498
19499 /* If face has an overline, add the height of the overline
19500 (1 pixel) and a 1 pixel margin to the character height. */
19501 if (face->overline_p)
19502 it->ascent += 2;
19503
19504 take_vertical_position_into_account (it);
19505
19506 if (it->glyph_row)
19507 append_glyph (it);
19508 }
19509 it->multibyte_p = saved_multibyte_p;
19510 }
19511 else if (it->what == IT_COMPOSITION)
19512 {
19513 /* Note: A composition is represented as one glyph in the
19514 glyph matrix. There are no padding glyphs. */
19515 XChar2b char2b;
19516 XFontStruct *font;
19517 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19518 XCharStruct *pcm;
19519 int font_not_found_p;
19520 struct font_info *font_info;
19521 int boff; /* baseline offset */
19522 struct composition *cmp = composition_table[it->cmp_id];
19523
19524 /* Maybe translate single-byte characters to multibyte. */
19525 it->char_to_display = it->c;
19526 if (unibyte_display_via_language_environment
19527 && SINGLE_BYTE_CHAR_P (it->c)
19528 && (it->c >= 0240
19529 || (it->c >= 0200
19530 && !NILP (Vnonascii_translation_table))))
19531 {
19532 it->char_to_display = unibyte_char_to_multibyte (it->c);
19533 }
19534
19535 /* Get face and font to use. Encode IT->char_to_display. */
19536 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19537 face = FACE_FROM_ID (it->f, it->face_id);
19538 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19539 &char2b, it->multibyte_p, 0);
19540 font = face->font;
19541
19542 /* When no suitable font found, use the default font. */
19543 font_not_found_p = font == NULL;
19544 if (font_not_found_p)
19545 {
19546 font = FRAME_FONT (it->f);
19547 boff = FRAME_BASELINE_OFFSET (it->f);
19548 font_info = NULL;
19549 }
19550 else
19551 {
19552 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19553 boff = font_info->baseline_offset;
19554 if (font_info->vertical_centering)
19555 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19556 }
19557
19558 /* There are no padding glyphs, so there is only one glyph to
19559 produce for the composition. Important is that pixel_width,
19560 ascent and descent are the values of what is drawn by
19561 draw_glyphs (i.e. the values of the overall glyphs composed). */
19562 it->nglyphs = 1;
19563
19564 /* If we have not yet calculated pixel size data of glyphs of
19565 the composition for the current face font, calculate them
19566 now. Theoretically, we have to check all fonts for the
19567 glyphs, but that requires much time and memory space. So,
19568 here we check only the font of the first glyph. This leads
19569 to incorrect display very rarely, and C-l (recenter) can
19570 correct the display anyway. */
19571 if (cmp->font != (void *) font)
19572 {
19573 /* Ascent and descent of the font of the first character of
19574 this composition (adjusted by baseline offset). Ascent
19575 and descent of overall glyphs should not be less than
19576 them respectively. */
19577 int font_ascent = FONT_BASE (font) + boff;
19578 int font_descent = FONT_DESCENT (font) - boff;
19579 /* Bounding box of the overall glyphs. */
19580 int leftmost, rightmost, lowest, highest;
19581 int i, width, ascent, descent;
19582
19583 cmp->font = (void *) font;
19584
19585 /* Initialize the bounding box. */
19586 if (font_info
19587 && (pcm = rif->per_char_metric (font, &char2b,
19588 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19589 {
19590 width = pcm->width;
19591 ascent = pcm->ascent;
19592 descent = pcm->descent;
19593 }
19594 else
19595 {
19596 width = FONT_WIDTH (font);
19597 ascent = FONT_BASE (font);
19598 descent = FONT_DESCENT (font);
19599 }
19600
19601 rightmost = width;
19602 lowest = - descent + boff;
19603 highest = ascent + boff;
19604 leftmost = 0;
19605
19606 if (font_info
19607 && font_info->default_ascent
19608 && CHAR_TABLE_P (Vuse_default_ascent)
19609 && !NILP (Faref (Vuse_default_ascent,
19610 make_number (it->char_to_display))))
19611 highest = font_info->default_ascent + boff;
19612
19613 /* Draw the first glyph at the normal position. It may be
19614 shifted to right later if some other glyphs are drawn at
19615 the left. */
19616 cmp->offsets[0] = 0;
19617 cmp->offsets[1] = boff;
19618
19619 /* Set cmp->offsets for the remaining glyphs. */
19620 for (i = 1; i < cmp->glyph_len; i++)
19621 {
19622 int left, right, btm, top;
19623 int ch = COMPOSITION_GLYPH (cmp, i);
19624 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19625
19626 face = FACE_FROM_ID (it->f, face_id);
19627 get_char_face_and_encoding (it->f, ch, face->id,
19628 &char2b, it->multibyte_p, 0);
19629 font = face->font;
19630 if (font == NULL)
19631 {
19632 font = FRAME_FONT (it->f);
19633 boff = FRAME_BASELINE_OFFSET (it->f);
19634 font_info = NULL;
19635 }
19636 else
19637 {
19638 font_info
19639 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19640 boff = font_info->baseline_offset;
19641 if (font_info->vertical_centering)
19642 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19643 }
19644
19645 if (font_info
19646 && (pcm = rif->per_char_metric (font, &char2b,
19647 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19648 {
19649 width = pcm->width;
19650 ascent = pcm->ascent;
19651 descent = pcm->descent;
19652 }
19653 else
19654 {
19655 width = FONT_WIDTH (font);
19656 ascent = 1;
19657 descent = 0;
19658 }
19659
19660 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19661 {
19662 /* Relative composition with or without
19663 alternate chars. */
19664 left = (leftmost + rightmost - width) / 2;
19665 btm = - descent + boff;
19666 if (font_info && font_info->relative_compose
19667 && (! CHAR_TABLE_P (Vignore_relative_composition)
19668 || NILP (Faref (Vignore_relative_composition,
19669 make_number (ch)))))
19670 {
19671
19672 if (- descent >= font_info->relative_compose)
19673 /* One extra pixel between two glyphs. */
19674 btm = highest + 1;
19675 else if (ascent <= 0)
19676 /* One extra pixel between two glyphs. */
19677 btm = lowest - 1 - ascent - descent;
19678 }
19679 }
19680 else
19681 {
19682 /* A composition rule is specified by an integer
19683 value that encodes global and new reference
19684 points (GREF and NREF). GREF and NREF are
19685 specified by numbers as below:
19686
19687 0---1---2 -- ascent
19688 | |
19689 | |
19690 | |
19691 9--10--11 -- center
19692 | |
19693 ---3---4---5--- baseline
19694 | |
19695 6---7---8 -- descent
19696 */
19697 int rule = COMPOSITION_RULE (cmp, i);
19698 int gref, nref, grefx, grefy, nrefx, nrefy;
19699
19700 COMPOSITION_DECODE_RULE (rule, gref, nref);
19701 grefx = gref % 3, nrefx = nref % 3;
19702 grefy = gref / 3, nrefy = nref / 3;
19703
19704 left = (leftmost
19705 + grefx * (rightmost - leftmost) / 2
19706 - nrefx * width / 2);
19707 btm = ((grefy == 0 ? highest
19708 : grefy == 1 ? 0
19709 : grefy == 2 ? lowest
19710 : (highest + lowest) / 2)
19711 - (nrefy == 0 ? ascent + descent
19712 : nrefy == 1 ? descent - boff
19713 : nrefy == 2 ? 0
19714 : (ascent + descent) / 2));
19715 }
19716
19717 cmp->offsets[i * 2] = left;
19718 cmp->offsets[i * 2 + 1] = btm + descent;
19719
19720 /* Update the bounding box of the overall glyphs. */
19721 right = left + width;
19722 top = btm + descent + ascent;
19723 if (left < leftmost)
19724 leftmost = left;
19725 if (right > rightmost)
19726 rightmost = right;
19727 if (top > highest)
19728 highest = top;
19729 if (btm < lowest)
19730 lowest = btm;
19731 }
19732
19733 /* If there are glyphs whose x-offsets are negative,
19734 shift all glyphs to the right and make all x-offsets
19735 non-negative. */
19736 if (leftmost < 0)
19737 {
19738 for (i = 0; i < cmp->glyph_len; i++)
19739 cmp->offsets[i * 2] -= leftmost;
19740 rightmost -= leftmost;
19741 }
19742
19743 cmp->pixel_width = rightmost;
19744 cmp->ascent = highest;
19745 cmp->descent = - lowest;
19746 if (cmp->ascent < font_ascent)
19747 cmp->ascent = font_ascent;
19748 if (cmp->descent < font_descent)
19749 cmp->descent = font_descent;
19750 }
19751
19752 it->pixel_width = cmp->pixel_width;
19753 it->ascent = it->phys_ascent = cmp->ascent;
19754 it->descent = it->phys_descent = cmp->descent;
19755
19756 if (face->box != FACE_NO_BOX)
19757 {
19758 int thick = face->box_line_width;
19759
19760 if (thick > 0)
19761 {
19762 it->ascent += thick;
19763 it->descent += thick;
19764 }
19765 else
19766 thick = - thick;
19767
19768 if (it->start_of_box_run_p)
19769 it->pixel_width += thick;
19770 if (it->end_of_box_run_p)
19771 it->pixel_width += thick;
19772 }
19773
19774 /* If face has an overline, add the height of the overline
19775 (1 pixel) and a 1 pixel margin to the character height. */
19776 if (face->overline_p)
19777 it->ascent += 2;
19778
19779 take_vertical_position_into_account (it);
19780
19781 if (it->glyph_row)
19782 append_composite_glyph (it);
19783 }
19784 else if (it->what == IT_IMAGE)
19785 produce_image_glyph (it);
19786 else if (it->what == IT_STRETCH)
19787 produce_stretch_glyph (it);
19788
19789 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19790 because this isn't true for images with `:ascent 100'. */
19791 xassert (it->ascent >= 0 && it->descent >= 0);
19792 if (it->area == TEXT_AREA)
19793 it->current_x += it->pixel_width;
19794
19795 if (extra_line_spacing > 0)
19796 {
19797 it->descent += extra_line_spacing;
19798 if (extra_line_spacing > it->max_extra_line_spacing)
19799 it->max_extra_line_spacing = extra_line_spacing;
19800 }
19801
19802 it->max_ascent = max (it->max_ascent, it->ascent);
19803 it->max_descent = max (it->max_descent, it->descent);
19804 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19805 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19806 }
19807
19808 /* EXPORT for RIF:
19809 Output LEN glyphs starting at START at the nominal cursor position.
19810 Advance the nominal cursor over the text. The global variable
19811 updated_window contains the window being updated, updated_row is
19812 the glyph row being updated, and updated_area is the area of that
19813 row being updated. */
19814
19815 void
19816 x_write_glyphs (start, len)
19817 struct glyph *start;
19818 int len;
19819 {
19820 int x, hpos;
19821
19822 xassert (updated_window && updated_row);
19823 BLOCK_INPUT;
19824
19825 /* Write glyphs. */
19826
19827 hpos = start - updated_row->glyphs[updated_area];
19828 x = draw_glyphs (updated_window, output_cursor.x,
19829 updated_row, updated_area,
19830 hpos, hpos + len,
19831 DRAW_NORMAL_TEXT, 0);
19832
19833 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19834 if (updated_area == TEXT_AREA
19835 && updated_window->phys_cursor_on_p
19836 && updated_window->phys_cursor.vpos == output_cursor.vpos
19837 && updated_window->phys_cursor.hpos >= hpos
19838 && updated_window->phys_cursor.hpos < hpos + len)
19839 updated_window->phys_cursor_on_p = 0;
19840
19841 UNBLOCK_INPUT;
19842
19843 /* Advance the output cursor. */
19844 output_cursor.hpos += len;
19845 output_cursor.x = x;
19846 }
19847
19848
19849 /* EXPORT for RIF:
19850 Insert LEN glyphs from START at the nominal cursor position. */
19851
19852 void
19853 x_insert_glyphs (start, len)
19854 struct glyph *start;
19855 int len;
19856 {
19857 struct frame *f;
19858 struct window *w;
19859 int line_height, shift_by_width, shifted_region_width;
19860 struct glyph_row *row;
19861 struct glyph *glyph;
19862 int frame_x, frame_y, hpos;
19863
19864 xassert (updated_window && updated_row);
19865 BLOCK_INPUT;
19866 w = updated_window;
19867 f = XFRAME (WINDOW_FRAME (w));
19868
19869 /* Get the height of the line we are in. */
19870 row = updated_row;
19871 line_height = row->height;
19872
19873 /* Get the width of the glyphs to insert. */
19874 shift_by_width = 0;
19875 for (glyph = start; glyph < start + len; ++glyph)
19876 shift_by_width += glyph->pixel_width;
19877
19878 /* Get the width of the region to shift right. */
19879 shifted_region_width = (window_box_width (w, updated_area)
19880 - output_cursor.x
19881 - shift_by_width);
19882
19883 /* Shift right. */
19884 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19885 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19886
19887 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19888 line_height, shift_by_width);
19889
19890 /* Write the glyphs. */
19891 hpos = start - row->glyphs[updated_area];
19892 draw_glyphs (w, output_cursor.x, row, updated_area,
19893 hpos, hpos + len,
19894 DRAW_NORMAL_TEXT, 0);
19895
19896 /* Advance the output cursor. */
19897 output_cursor.hpos += len;
19898 output_cursor.x += shift_by_width;
19899 UNBLOCK_INPUT;
19900 }
19901
19902
19903 /* EXPORT for RIF:
19904 Erase the current text line from the nominal cursor position
19905 (inclusive) to pixel column TO_X (exclusive). The idea is that
19906 everything from TO_X onward is already erased.
19907
19908 TO_X is a pixel position relative to updated_area of
19909 updated_window. TO_X == -1 means clear to the end of this area. */
19910
19911 void
19912 x_clear_end_of_line (to_x)
19913 int to_x;
19914 {
19915 struct frame *f;
19916 struct window *w = updated_window;
19917 int max_x, min_y, max_y;
19918 int from_x, from_y, to_y;
19919
19920 xassert (updated_window && updated_row);
19921 f = XFRAME (w->frame);
19922
19923 if (updated_row->full_width_p)
19924 max_x = WINDOW_TOTAL_WIDTH (w);
19925 else
19926 max_x = window_box_width (w, updated_area);
19927 max_y = window_text_bottom_y (w);
19928
19929 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19930 of window. For TO_X > 0, truncate to end of drawing area. */
19931 if (to_x == 0)
19932 return;
19933 else if (to_x < 0)
19934 to_x = max_x;
19935 else
19936 to_x = min (to_x, max_x);
19937
19938 to_y = min (max_y, output_cursor.y + updated_row->height);
19939
19940 /* Notice if the cursor will be cleared by this operation. */
19941 if (!updated_row->full_width_p)
19942 notice_overwritten_cursor (w, updated_area,
19943 output_cursor.x, -1,
19944 updated_row->y,
19945 MATRIX_ROW_BOTTOM_Y (updated_row));
19946
19947 from_x = output_cursor.x;
19948
19949 /* Translate to frame coordinates. */
19950 if (updated_row->full_width_p)
19951 {
19952 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19953 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19954 }
19955 else
19956 {
19957 int area_left = window_box_left (w, updated_area);
19958 from_x += area_left;
19959 to_x += area_left;
19960 }
19961
19962 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19963 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19964 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19965
19966 /* Prevent inadvertently clearing to end of the X window. */
19967 if (to_x > from_x && to_y > from_y)
19968 {
19969 BLOCK_INPUT;
19970 rif->clear_frame_area (f, from_x, from_y,
19971 to_x - from_x, to_y - from_y);
19972 UNBLOCK_INPUT;
19973 }
19974 }
19975
19976 #endif /* HAVE_WINDOW_SYSTEM */
19977
19978
19979 \f
19980 /***********************************************************************
19981 Cursor types
19982 ***********************************************************************/
19983
19984 /* Value is the internal representation of the specified cursor type
19985 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19986 of the bar cursor. */
19987
19988 static enum text_cursor_kinds
19989 get_specified_cursor_type (arg, width)
19990 Lisp_Object arg;
19991 int *width;
19992 {
19993 enum text_cursor_kinds type;
19994
19995 if (NILP (arg))
19996 return NO_CURSOR;
19997
19998 if (EQ (arg, Qbox))
19999 return FILLED_BOX_CURSOR;
20000
20001 if (EQ (arg, Qhollow))
20002 return HOLLOW_BOX_CURSOR;
20003
20004 if (EQ (arg, Qbar))
20005 {
20006 *width = 2;
20007 return BAR_CURSOR;
20008 }
20009
20010 if (CONSP (arg)
20011 && EQ (XCAR (arg), Qbar)
20012 && INTEGERP (XCDR (arg))
20013 && XINT (XCDR (arg)) >= 0)
20014 {
20015 *width = XINT (XCDR (arg));
20016 return BAR_CURSOR;
20017 }
20018
20019 if (EQ (arg, Qhbar))
20020 {
20021 *width = 2;
20022 return HBAR_CURSOR;
20023 }
20024
20025 if (CONSP (arg)
20026 && EQ (XCAR (arg), Qhbar)
20027 && INTEGERP (XCDR (arg))
20028 && XINT (XCDR (arg)) >= 0)
20029 {
20030 *width = XINT (XCDR (arg));
20031 return HBAR_CURSOR;
20032 }
20033
20034 /* Treat anything unknown as "hollow box cursor".
20035 It was bad to signal an error; people have trouble fixing
20036 .Xdefaults with Emacs, when it has something bad in it. */
20037 type = HOLLOW_BOX_CURSOR;
20038
20039 return type;
20040 }
20041
20042 /* Set the default cursor types for specified frame. */
20043 void
20044 set_frame_cursor_types (f, arg)
20045 struct frame *f;
20046 Lisp_Object arg;
20047 {
20048 int width;
20049 Lisp_Object tem;
20050
20051 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
20052 FRAME_CURSOR_WIDTH (f) = width;
20053
20054 /* By default, set up the blink-off state depending on the on-state. */
20055
20056 tem = Fassoc (arg, Vblink_cursor_alist);
20057 if (!NILP (tem))
20058 {
20059 FRAME_BLINK_OFF_CURSOR (f)
20060 = get_specified_cursor_type (XCDR (tem), &width);
20061 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
20062 }
20063 else
20064 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
20065 }
20066
20067
20068 /* Return the cursor we want to be displayed in window W. Return
20069 width of bar/hbar cursor through WIDTH arg. Return with
20070 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
20071 (i.e. if the `system caret' should track this cursor).
20072
20073 In a mini-buffer window, we want the cursor only to appear if we
20074 are reading input from this window. For the selected window, we
20075 want the cursor type given by the frame parameter or buffer local
20076 setting of cursor-type. If explicitly marked off, draw no cursor.
20077 In all other cases, we want a hollow box cursor. */
20078
20079 static enum text_cursor_kinds
20080 get_window_cursor_type (w, glyph, width, active_cursor)
20081 struct window *w;
20082 struct glyph *glyph;
20083 int *width;
20084 int *active_cursor;
20085 {
20086 struct frame *f = XFRAME (w->frame);
20087 struct buffer *b = XBUFFER (w->buffer);
20088 int cursor_type = DEFAULT_CURSOR;
20089 Lisp_Object alt_cursor;
20090 int non_selected = 0;
20091
20092 *active_cursor = 1;
20093
20094 /* Echo area */
20095 if (cursor_in_echo_area
20096 && FRAME_HAS_MINIBUF_P (f)
20097 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
20098 {
20099 if (w == XWINDOW (echo_area_window))
20100 {
20101 *width = FRAME_CURSOR_WIDTH (f);
20102 return FRAME_DESIRED_CURSOR (f);
20103 }
20104
20105 *active_cursor = 0;
20106 non_selected = 1;
20107 }
20108
20109 /* Nonselected window or nonselected frame. */
20110 else if (w != XWINDOW (f->selected_window)
20111 #ifdef HAVE_WINDOW_SYSTEM
20112 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
20113 #endif
20114 )
20115 {
20116 *active_cursor = 0;
20117
20118 if (MINI_WINDOW_P (w) && minibuf_level == 0)
20119 return NO_CURSOR;
20120
20121 non_selected = 1;
20122 }
20123
20124 /* Never display a cursor in a window in which cursor-type is nil. */
20125 if (NILP (b->cursor_type))
20126 return NO_CURSOR;
20127
20128 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
20129 if (non_selected)
20130 {
20131 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
20132 return get_specified_cursor_type (alt_cursor, width);
20133 }
20134
20135 /* Get the normal cursor type for this window. */
20136 if (EQ (b->cursor_type, Qt))
20137 {
20138 cursor_type = FRAME_DESIRED_CURSOR (f);
20139 *width = FRAME_CURSOR_WIDTH (f);
20140 }
20141 else
20142 cursor_type = get_specified_cursor_type (b->cursor_type, width);
20143
20144 /* Use normal cursor if not blinked off. */
20145 if (!w->cursor_off_p)
20146 {
20147 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
20148 if (cursor_type == FILLED_BOX_CURSOR)
20149 cursor_type = HOLLOW_BOX_CURSOR;
20150 }
20151 return cursor_type;
20152 }
20153
20154 /* Cursor is blinked off, so determine how to "toggle" it. */
20155
20156 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
20157 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
20158 return get_specified_cursor_type (XCDR (alt_cursor), width);
20159
20160 /* Then see if frame has specified a specific blink off cursor type. */
20161 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
20162 {
20163 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
20164 return FRAME_BLINK_OFF_CURSOR (f);
20165 }
20166
20167 #if 0
20168 /* Some people liked having a permanently visible blinking cursor,
20169 while others had very strong opinions against it. So it was
20170 decided to remove it. KFS 2003-09-03 */
20171
20172 /* Finally perform built-in cursor blinking:
20173 filled box <-> hollow box
20174 wide [h]bar <-> narrow [h]bar
20175 narrow [h]bar <-> no cursor
20176 other type <-> no cursor */
20177
20178 if (cursor_type == FILLED_BOX_CURSOR)
20179 return HOLLOW_BOX_CURSOR;
20180
20181 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
20182 {
20183 *width = 1;
20184 return cursor_type;
20185 }
20186 #endif
20187
20188 return NO_CURSOR;
20189 }
20190
20191
20192 #ifdef HAVE_WINDOW_SYSTEM
20193
20194 /* Notice when the text cursor of window W has been completely
20195 overwritten by a drawing operation that outputs glyphs in AREA
20196 starting at X0 and ending at X1 in the line starting at Y0 and
20197 ending at Y1. X coordinates are area-relative. X1 < 0 means all
20198 the rest of the line after X0 has been written. Y coordinates
20199 are window-relative. */
20200
20201 static void
20202 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
20203 struct window *w;
20204 enum glyph_row_area area;
20205 int x0, y0, x1, y1;
20206 {
20207 int cx0, cx1, cy0, cy1;
20208 struct glyph_row *row;
20209
20210 if (!w->phys_cursor_on_p)
20211 return;
20212 if (area != TEXT_AREA)
20213 return;
20214
20215 if (w->phys_cursor.vpos < 0
20216 || w->phys_cursor.vpos >= w->current_matrix->nrows
20217 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
20218 !(row->enabled_p && row->displays_text_p)))
20219 return;
20220
20221 if (row->cursor_in_fringe_p)
20222 {
20223 row->cursor_in_fringe_p = 0;
20224 draw_fringe_bitmap (w, row, 0);
20225 w->phys_cursor_on_p = 0;
20226 return;
20227 }
20228
20229 cx0 = w->phys_cursor.x;
20230 cx1 = cx0 + w->phys_cursor_width;
20231 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20232 return;
20233
20234 /* The cursor image will be completely removed from the
20235 screen if the output area intersects the cursor area in
20236 y-direction. When we draw in [y0 y1[, and some part of
20237 the cursor is at y < y0, that part must have been drawn
20238 before. When scrolling, the cursor is erased before
20239 actually scrolling, so we don't come here. When not
20240 scrolling, the rows above the old cursor row must have
20241 changed, and in this case these rows must have written
20242 over the cursor image.
20243
20244 Likewise if part of the cursor is below y1, with the
20245 exception of the cursor being in the first blank row at
20246 the buffer and window end because update_text_area
20247 doesn't draw that row. (Except when it does, but
20248 that's handled in update_text_area.) */
20249
20250 cy0 = w->phys_cursor.y;
20251 cy1 = cy0 + w->phys_cursor_height;
20252 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20253 return;
20254
20255 w->phys_cursor_on_p = 0;
20256 }
20257
20258 #endif /* HAVE_WINDOW_SYSTEM */
20259
20260 \f
20261 /************************************************************************
20262 Mouse Face
20263 ************************************************************************/
20264
20265 #ifdef HAVE_WINDOW_SYSTEM
20266
20267 /* EXPORT for RIF:
20268 Fix the display of area AREA of overlapping row ROW in window W. */
20269
20270 void
20271 x_fix_overlapping_area (w, row, area)
20272 struct window *w;
20273 struct glyph_row *row;
20274 enum glyph_row_area area;
20275 {
20276 int i, x;
20277
20278 BLOCK_INPUT;
20279
20280 x = 0;
20281 for (i = 0; i < row->used[area];)
20282 {
20283 if (row->glyphs[area][i].overlaps_vertically_p)
20284 {
20285 int start = i, start_x = x;
20286
20287 do
20288 {
20289 x += row->glyphs[area][i].pixel_width;
20290 ++i;
20291 }
20292 while (i < row->used[area]
20293 && row->glyphs[area][i].overlaps_vertically_p);
20294
20295 draw_glyphs (w, start_x, row, area,
20296 start, i,
20297 DRAW_NORMAL_TEXT, 1);
20298 }
20299 else
20300 {
20301 x += row->glyphs[area][i].pixel_width;
20302 ++i;
20303 }
20304 }
20305
20306 UNBLOCK_INPUT;
20307 }
20308
20309
20310 /* EXPORT:
20311 Draw the cursor glyph of window W in glyph row ROW. See the
20312 comment of draw_glyphs for the meaning of HL. */
20313
20314 void
20315 draw_phys_cursor_glyph (w, row, hl)
20316 struct window *w;
20317 struct glyph_row *row;
20318 enum draw_glyphs_face hl;
20319 {
20320 /* If cursor hpos is out of bounds, don't draw garbage. This can
20321 happen in mini-buffer windows when switching between echo area
20322 glyphs and mini-buffer. */
20323 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20324 {
20325 int on_p = w->phys_cursor_on_p;
20326 int x1;
20327 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20328 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20329 hl, 0);
20330 w->phys_cursor_on_p = on_p;
20331
20332 if (hl == DRAW_CURSOR)
20333 w->phys_cursor_width = x1 - w->phys_cursor.x;
20334 /* When we erase the cursor, and ROW is overlapped by other
20335 rows, make sure that these overlapping parts of other rows
20336 are redrawn. */
20337 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20338 {
20339 if (row > w->current_matrix->rows
20340 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20341 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20342
20343 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20344 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20345 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20346 }
20347 }
20348 }
20349
20350
20351 /* EXPORT:
20352 Erase the image of a cursor of window W from the screen. */
20353
20354 void
20355 erase_phys_cursor (w)
20356 struct window *w;
20357 {
20358 struct frame *f = XFRAME (w->frame);
20359 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20360 int hpos = w->phys_cursor.hpos;
20361 int vpos = w->phys_cursor.vpos;
20362 int mouse_face_here_p = 0;
20363 struct glyph_matrix *active_glyphs = w->current_matrix;
20364 struct glyph_row *cursor_row;
20365 struct glyph *cursor_glyph;
20366 enum draw_glyphs_face hl;
20367
20368 /* No cursor displayed or row invalidated => nothing to do on the
20369 screen. */
20370 if (w->phys_cursor_type == NO_CURSOR)
20371 goto mark_cursor_off;
20372
20373 /* VPOS >= active_glyphs->nrows means that window has been resized.
20374 Don't bother to erase the cursor. */
20375 if (vpos >= active_glyphs->nrows)
20376 goto mark_cursor_off;
20377
20378 /* If row containing cursor is marked invalid, there is nothing we
20379 can do. */
20380 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20381 if (!cursor_row->enabled_p)
20382 goto mark_cursor_off;
20383
20384 /* If line spacing is > 0, old cursor may only be partially visible in
20385 window after split-window. So adjust visible height. */
20386 cursor_row->visible_height = min (cursor_row->visible_height,
20387 window_text_bottom_y (w) - cursor_row->y);
20388
20389 /* If row is completely invisible, don't attempt to delete a cursor which
20390 isn't there. This can happen if cursor is at top of a window, and
20391 we switch to a buffer with a header line in that window. */
20392 if (cursor_row->visible_height <= 0)
20393 goto mark_cursor_off;
20394
20395 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20396 if (cursor_row->cursor_in_fringe_p)
20397 {
20398 cursor_row->cursor_in_fringe_p = 0;
20399 draw_fringe_bitmap (w, cursor_row, 0);
20400 goto mark_cursor_off;
20401 }
20402
20403 /* This can happen when the new row is shorter than the old one.
20404 In this case, either draw_glyphs or clear_end_of_line
20405 should have cleared the cursor. Note that we wouldn't be
20406 able to erase the cursor in this case because we don't have a
20407 cursor glyph at hand. */
20408 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20409 goto mark_cursor_off;
20410
20411 /* If the cursor is in the mouse face area, redisplay that when
20412 we clear the cursor. */
20413 if (! NILP (dpyinfo->mouse_face_window)
20414 && w == XWINDOW (dpyinfo->mouse_face_window)
20415 && (vpos > dpyinfo->mouse_face_beg_row
20416 || (vpos == dpyinfo->mouse_face_beg_row
20417 && hpos >= dpyinfo->mouse_face_beg_col))
20418 && (vpos < dpyinfo->mouse_face_end_row
20419 || (vpos == dpyinfo->mouse_face_end_row
20420 && hpos < dpyinfo->mouse_face_end_col))
20421 /* Don't redraw the cursor's spot in mouse face if it is at the
20422 end of a line (on a newline). The cursor appears there, but
20423 mouse highlighting does not. */
20424 && cursor_row->used[TEXT_AREA] > hpos)
20425 mouse_face_here_p = 1;
20426
20427 /* Maybe clear the display under the cursor. */
20428 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20429 {
20430 int x, y;
20431 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20432 int width;
20433
20434 cursor_glyph = get_phys_cursor_glyph (w);
20435 if (cursor_glyph == NULL)
20436 goto mark_cursor_off;
20437
20438 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20439 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20440 width = min (cursor_glyph->pixel_width,
20441 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
20442
20443 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
20444 }
20445
20446 /* Erase the cursor by redrawing the character underneath it. */
20447 if (mouse_face_here_p)
20448 hl = DRAW_MOUSE_FACE;
20449 else
20450 hl = DRAW_NORMAL_TEXT;
20451 draw_phys_cursor_glyph (w, cursor_row, hl);
20452
20453 mark_cursor_off:
20454 w->phys_cursor_on_p = 0;
20455 w->phys_cursor_type = NO_CURSOR;
20456 }
20457
20458
20459 /* EXPORT:
20460 Display or clear cursor of window W. If ON is zero, clear the
20461 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20462 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20463
20464 void
20465 display_and_set_cursor (w, on, hpos, vpos, x, y)
20466 struct window *w;
20467 int on, hpos, vpos, x, y;
20468 {
20469 struct frame *f = XFRAME (w->frame);
20470 int new_cursor_type;
20471 int new_cursor_width;
20472 int active_cursor;
20473 struct glyph_row *glyph_row;
20474 struct glyph *glyph;
20475
20476 /* This is pointless on invisible frames, and dangerous on garbaged
20477 windows and frames; in the latter case, the frame or window may
20478 be in the midst of changing its size, and x and y may be off the
20479 window. */
20480 if (! FRAME_VISIBLE_P (f)
20481 || FRAME_GARBAGED_P (f)
20482 || vpos >= w->current_matrix->nrows
20483 || hpos >= w->current_matrix->matrix_w)
20484 return;
20485
20486 /* If cursor is off and we want it off, return quickly. */
20487 if (!on && !w->phys_cursor_on_p)
20488 return;
20489
20490 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20491 /* If cursor row is not enabled, we don't really know where to
20492 display the cursor. */
20493 if (!glyph_row->enabled_p)
20494 {
20495 w->phys_cursor_on_p = 0;
20496 return;
20497 }
20498
20499 glyph = NULL;
20500 if (!glyph_row->exact_window_width_line_p
20501 || hpos < glyph_row->used[TEXT_AREA])
20502 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20503
20504 xassert (interrupt_input_blocked);
20505
20506 /* Set new_cursor_type to the cursor we want to be displayed. */
20507 new_cursor_type = get_window_cursor_type (w, glyph,
20508 &new_cursor_width, &active_cursor);
20509
20510 /* If cursor is currently being shown and we don't want it to be or
20511 it is in the wrong place, or the cursor type is not what we want,
20512 erase it. */
20513 if (w->phys_cursor_on_p
20514 && (!on
20515 || w->phys_cursor.x != x
20516 || w->phys_cursor.y != y
20517 || new_cursor_type != w->phys_cursor_type
20518 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20519 && new_cursor_width != w->phys_cursor_width)))
20520 erase_phys_cursor (w);
20521
20522 /* Don't check phys_cursor_on_p here because that flag is only set
20523 to zero in some cases where we know that the cursor has been
20524 completely erased, to avoid the extra work of erasing the cursor
20525 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20526 still not be visible, or it has only been partly erased. */
20527 if (on)
20528 {
20529 w->phys_cursor_ascent = glyph_row->ascent;
20530 w->phys_cursor_height = glyph_row->height;
20531
20532 /* Set phys_cursor_.* before x_draw_.* is called because some
20533 of them may need the information. */
20534 w->phys_cursor.x = x;
20535 w->phys_cursor.y = glyph_row->y;
20536 w->phys_cursor.hpos = hpos;
20537 w->phys_cursor.vpos = vpos;
20538 }
20539
20540 rif->draw_window_cursor (w, glyph_row, x, y,
20541 new_cursor_type, new_cursor_width,
20542 on, active_cursor);
20543 }
20544
20545
20546 /* Switch the display of W's cursor on or off, according to the value
20547 of ON. */
20548
20549 static void
20550 update_window_cursor (w, on)
20551 struct window *w;
20552 int on;
20553 {
20554 /* Don't update cursor in windows whose frame is in the process
20555 of being deleted. */
20556 if (w->current_matrix)
20557 {
20558 BLOCK_INPUT;
20559 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20560 w->phys_cursor.x, w->phys_cursor.y);
20561 UNBLOCK_INPUT;
20562 }
20563 }
20564
20565
20566 /* Call update_window_cursor with parameter ON_P on all leaf windows
20567 in the window tree rooted at W. */
20568
20569 static void
20570 update_cursor_in_window_tree (w, on_p)
20571 struct window *w;
20572 int on_p;
20573 {
20574 while (w)
20575 {
20576 if (!NILP (w->hchild))
20577 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20578 else if (!NILP (w->vchild))
20579 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20580 else
20581 update_window_cursor (w, on_p);
20582
20583 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20584 }
20585 }
20586
20587
20588 /* EXPORT:
20589 Display the cursor on window W, or clear it, according to ON_P.
20590 Don't change the cursor's position. */
20591
20592 void
20593 x_update_cursor (f, on_p)
20594 struct frame *f;
20595 int on_p;
20596 {
20597 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20598 }
20599
20600
20601 /* EXPORT:
20602 Clear the cursor of window W to background color, and mark the
20603 cursor as not shown. This is used when the text where the cursor
20604 is is about to be rewritten. */
20605
20606 void
20607 x_clear_cursor (w)
20608 struct window *w;
20609 {
20610 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20611 update_window_cursor (w, 0);
20612 }
20613
20614
20615 /* EXPORT:
20616 Display the active region described by mouse_face_* according to DRAW. */
20617
20618 void
20619 show_mouse_face (dpyinfo, draw)
20620 Display_Info *dpyinfo;
20621 enum draw_glyphs_face draw;
20622 {
20623 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20624 struct frame *f = XFRAME (WINDOW_FRAME (w));
20625
20626 if (/* If window is in the process of being destroyed, don't bother
20627 to do anything. */
20628 w->current_matrix != NULL
20629 /* Don't update mouse highlight if hidden */
20630 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20631 /* Recognize when we are called to operate on rows that don't exist
20632 anymore. This can happen when a window is split. */
20633 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20634 {
20635 int phys_cursor_on_p = w->phys_cursor_on_p;
20636 struct glyph_row *row, *first, *last;
20637
20638 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20639 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20640
20641 for (row = first; row <= last && row->enabled_p; ++row)
20642 {
20643 int start_hpos, end_hpos, start_x;
20644
20645 /* For all but the first row, the highlight starts at column 0. */
20646 if (row == first)
20647 {
20648 start_hpos = dpyinfo->mouse_face_beg_col;
20649 start_x = dpyinfo->mouse_face_beg_x;
20650 }
20651 else
20652 {
20653 start_hpos = 0;
20654 start_x = 0;
20655 }
20656
20657 if (row == last)
20658 end_hpos = dpyinfo->mouse_face_end_col;
20659 else
20660 end_hpos = row->used[TEXT_AREA];
20661
20662 if (end_hpos > start_hpos)
20663 {
20664 draw_glyphs (w, start_x, row, TEXT_AREA,
20665 start_hpos, end_hpos,
20666 draw, 0);
20667
20668 row->mouse_face_p
20669 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20670 }
20671 }
20672
20673 /* When we've written over the cursor, arrange for it to
20674 be displayed again. */
20675 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20676 {
20677 BLOCK_INPUT;
20678 display_and_set_cursor (w, 1,
20679 w->phys_cursor.hpos, w->phys_cursor.vpos,
20680 w->phys_cursor.x, w->phys_cursor.y);
20681 UNBLOCK_INPUT;
20682 }
20683 }
20684
20685 /* Change the mouse cursor. */
20686 if (draw == DRAW_NORMAL_TEXT)
20687 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20688 else if (draw == DRAW_MOUSE_FACE)
20689 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20690 else
20691 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20692 }
20693
20694 /* EXPORT:
20695 Clear out the mouse-highlighted active region.
20696 Redraw it un-highlighted first. Value is non-zero if mouse
20697 face was actually drawn unhighlighted. */
20698
20699 int
20700 clear_mouse_face (dpyinfo)
20701 Display_Info *dpyinfo;
20702 {
20703 int cleared = 0;
20704
20705 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20706 {
20707 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20708 cleared = 1;
20709 }
20710
20711 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20712 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20713 dpyinfo->mouse_face_window = Qnil;
20714 dpyinfo->mouse_face_overlay = Qnil;
20715 return cleared;
20716 }
20717
20718
20719 /* EXPORT:
20720 Non-zero if physical cursor of window W is within mouse face. */
20721
20722 int
20723 cursor_in_mouse_face_p (w)
20724 struct window *w;
20725 {
20726 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20727 int in_mouse_face = 0;
20728
20729 if (WINDOWP (dpyinfo->mouse_face_window)
20730 && XWINDOW (dpyinfo->mouse_face_window) == w)
20731 {
20732 int hpos = w->phys_cursor.hpos;
20733 int vpos = w->phys_cursor.vpos;
20734
20735 if (vpos >= dpyinfo->mouse_face_beg_row
20736 && vpos <= dpyinfo->mouse_face_end_row
20737 && (vpos > dpyinfo->mouse_face_beg_row
20738 || hpos >= dpyinfo->mouse_face_beg_col)
20739 && (vpos < dpyinfo->mouse_face_end_row
20740 || hpos < dpyinfo->mouse_face_end_col
20741 || dpyinfo->mouse_face_past_end))
20742 in_mouse_face = 1;
20743 }
20744
20745 return in_mouse_face;
20746 }
20747
20748
20749
20750 \f
20751 /* Find the glyph matrix position of buffer position CHARPOS in window
20752 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20753 current glyphs must be up to date. If CHARPOS is above window
20754 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20755 of last line in W. In the row containing CHARPOS, stop before glyphs
20756 having STOP as object. */
20757
20758 #if 1 /* This is a version of fast_find_position that's more correct
20759 in the presence of hscrolling, for example. I didn't install
20760 it right away because the problem fixed is minor, it failed
20761 in 20.x as well, and I think it's too risky to install
20762 so near the release of 21.1. 2001-09-25 gerd. */
20763
20764 static int
20765 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20766 struct window *w;
20767 int charpos;
20768 int *hpos, *vpos, *x, *y;
20769 Lisp_Object stop;
20770 {
20771 struct glyph_row *row, *first;
20772 struct glyph *glyph, *end;
20773 int past_end = 0;
20774
20775 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20776 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20777 {
20778 *x = first->x;
20779 *y = first->y;
20780 *hpos = 0;
20781 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
20782 return 1;
20783 }
20784
20785 row = row_containing_pos (w, charpos, first, NULL, 0);
20786 if (row == NULL)
20787 {
20788 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20789 past_end = 1;
20790 }
20791
20792 /* If whole rows or last part of a row came from a display overlay,
20793 row_containing_pos will skip over such rows because their end pos
20794 equals the start pos of the overlay or interval.
20795
20796 Move back if we have a STOP object and previous row's
20797 end glyph came from STOP. */
20798 if (!NILP (stop))
20799 {
20800 struct glyph_row *prev;
20801 while ((prev = row - 1, prev >= first)
20802 && MATRIX_ROW_END_CHARPOS (prev) == charpos
20803 && prev->used[TEXT_AREA] > 0)
20804 {
20805 struct glyph *beg = prev->glyphs[TEXT_AREA];
20806 glyph = beg + prev->used[TEXT_AREA];
20807 while (--glyph >= beg
20808 && INTEGERP (glyph->object));
20809 if (glyph < beg
20810 || !EQ (stop, glyph->object))
20811 break;
20812 row = prev;
20813 }
20814 }
20815
20816 *x = row->x;
20817 *y = row->y;
20818 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20819
20820 glyph = row->glyphs[TEXT_AREA];
20821 end = glyph + row->used[TEXT_AREA];
20822
20823 /* Skip over glyphs not having an object at the start of the row.
20824 These are special glyphs like truncation marks on terminal
20825 frames. */
20826 if (row->displays_text_p)
20827 while (glyph < end
20828 && INTEGERP (glyph->object)
20829 && !EQ (stop, glyph->object)
20830 && glyph->charpos < 0)
20831 {
20832 *x += glyph->pixel_width;
20833 ++glyph;
20834 }
20835
20836 while (glyph < end
20837 && !INTEGERP (glyph->object)
20838 && !EQ (stop, glyph->object)
20839 && (!BUFFERP (glyph->object)
20840 || glyph->charpos < charpos))
20841 {
20842 *x += glyph->pixel_width;
20843 ++glyph;
20844 }
20845
20846 *hpos = glyph - row->glyphs[TEXT_AREA];
20847 return !past_end;
20848 }
20849
20850 #else /* not 1 */
20851
20852 static int
20853 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20854 struct window *w;
20855 int pos;
20856 int *hpos, *vpos, *x, *y;
20857 Lisp_Object stop;
20858 {
20859 int i;
20860 int lastcol;
20861 int maybe_next_line_p = 0;
20862 int line_start_position;
20863 int yb = window_text_bottom_y (w);
20864 struct glyph_row *row, *best_row;
20865 int row_vpos, best_row_vpos;
20866 int current_x;
20867
20868 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20869 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20870
20871 while (row->y < yb)
20872 {
20873 if (row->used[TEXT_AREA])
20874 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20875 else
20876 line_start_position = 0;
20877
20878 if (line_start_position > pos)
20879 break;
20880 /* If the position sought is the end of the buffer,
20881 don't include the blank lines at the bottom of the window. */
20882 else if (line_start_position == pos
20883 && pos == BUF_ZV (XBUFFER (w->buffer)))
20884 {
20885 maybe_next_line_p = 1;
20886 break;
20887 }
20888 else if (line_start_position > 0)
20889 {
20890 best_row = row;
20891 best_row_vpos = row_vpos;
20892 }
20893
20894 if (row->y + row->height >= yb)
20895 break;
20896
20897 ++row;
20898 ++row_vpos;
20899 }
20900
20901 /* Find the right column within BEST_ROW. */
20902 lastcol = 0;
20903 current_x = best_row->x;
20904 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20905 {
20906 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20907 int charpos = glyph->charpos;
20908
20909 if (BUFFERP (glyph->object))
20910 {
20911 if (charpos == pos)
20912 {
20913 *hpos = i;
20914 *vpos = best_row_vpos;
20915 *x = current_x;
20916 *y = best_row->y;
20917 return 1;
20918 }
20919 else if (charpos > pos)
20920 break;
20921 }
20922 else if (EQ (glyph->object, stop))
20923 break;
20924
20925 if (charpos > 0)
20926 lastcol = i;
20927 current_x += glyph->pixel_width;
20928 }
20929
20930 /* If we're looking for the end of the buffer,
20931 and we didn't find it in the line we scanned,
20932 use the start of the following line. */
20933 if (maybe_next_line_p)
20934 {
20935 ++best_row;
20936 ++best_row_vpos;
20937 lastcol = 0;
20938 current_x = best_row->x;
20939 }
20940
20941 *vpos = best_row_vpos;
20942 *hpos = lastcol + 1;
20943 *x = current_x;
20944 *y = best_row->y;
20945 return 0;
20946 }
20947
20948 #endif /* not 1 */
20949
20950
20951 /* Find the position of the glyph for position POS in OBJECT in
20952 window W's current matrix, and return in *X, *Y the pixel
20953 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20954
20955 RIGHT_P non-zero means return the position of the right edge of the
20956 glyph, RIGHT_P zero means return the left edge position.
20957
20958 If no glyph for POS exists in the matrix, return the position of
20959 the glyph with the next smaller position that is in the matrix, if
20960 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20961 exists in the matrix, return the position of the glyph with the
20962 next larger position in OBJECT.
20963
20964 Value is non-zero if a glyph was found. */
20965
20966 static int
20967 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20968 struct window *w;
20969 int pos;
20970 Lisp_Object object;
20971 int *hpos, *vpos, *x, *y;
20972 int right_p;
20973 {
20974 int yb = window_text_bottom_y (w);
20975 struct glyph_row *r;
20976 struct glyph *best_glyph = NULL;
20977 struct glyph_row *best_row = NULL;
20978 int best_x = 0;
20979
20980 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20981 r->enabled_p && r->y < yb;
20982 ++r)
20983 {
20984 struct glyph *g = r->glyphs[TEXT_AREA];
20985 struct glyph *e = g + r->used[TEXT_AREA];
20986 int gx;
20987
20988 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20989 if (EQ (g->object, object))
20990 {
20991 if (g->charpos == pos)
20992 {
20993 best_glyph = g;
20994 best_x = gx;
20995 best_row = r;
20996 goto found;
20997 }
20998 else if (best_glyph == NULL
20999 || ((abs (g->charpos - pos)
21000 < abs (best_glyph->charpos - pos))
21001 && (right_p
21002 ? g->charpos < pos
21003 : g->charpos > pos)))
21004 {
21005 best_glyph = g;
21006 best_x = gx;
21007 best_row = r;
21008 }
21009 }
21010 }
21011
21012 found:
21013
21014 if (best_glyph)
21015 {
21016 *x = best_x;
21017 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
21018
21019 if (right_p)
21020 {
21021 *x += best_glyph->pixel_width;
21022 ++*hpos;
21023 }
21024
21025 *y = best_row->y;
21026 *vpos = best_row - w->current_matrix->rows;
21027 }
21028
21029 return best_glyph != NULL;
21030 }
21031
21032
21033 /* See if position X, Y is within a hot-spot of an image. */
21034
21035 static int
21036 on_hot_spot_p (hot_spot, x, y)
21037 Lisp_Object hot_spot;
21038 int x, y;
21039 {
21040 if (!CONSP (hot_spot))
21041 return 0;
21042
21043 if (EQ (XCAR (hot_spot), Qrect))
21044 {
21045 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
21046 Lisp_Object rect = XCDR (hot_spot);
21047 Lisp_Object tem;
21048 if (!CONSP (rect))
21049 return 0;
21050 if (!CONSP (XCAR (rect)))
21051 return 0;
21052 if (!CONSP (XCDR (rect)))
21053 return 0;
21054 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
21055 return 0;
21056 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
21057 return 0;
21058 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
21059 return 0;
21060 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
21061 return 0;
21062 return 1;
21063 }
21064 else if (EQ (XCAR (hot_spot), Qcircle))
21065 {
21066 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
21067 Lisp_Object circ = XCDR (hot_spot);
21068 Lisp_Object lr, lx0, ly0;
21069 if (CONSP (circ)
21070 && CONSP (XCAR (circ))
21071 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
21072 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
21073 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
21074 {
21075 double r = XFLOATINT (lr);
21076 double dx = XINT (lx0) - x;
21077 double dy = XINT (ly0) - y;
21078 return (dx * dx + dy * dy <= r * r);
21079 }
21080 }
21081 else if (EQ (XCAR (hot_spot), Qpoly))
21082 {
21083 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
21084 if (VECTORP (XCDR (hot_spot)))
21085 {
21086 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
21087 Lisp_Object *poly = v->contents;
21088 int n = v->size;
21089 int i;
21090 int inside = 0;
21091 Lisp_Object lx, ly;
21092 int x0, y0;
21093
21094 /* Need an even number of coordinates, and at least 3 edges. */
21095 if (n < 6 || n & 1)
21096 return 0;
21097
21098 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
21099 If count is odd, we are inside polygon. Pixels on edges
21100 may or may not be included depending on actual geometry of the
21101 polygon. */
21102 if ((lx = poly[n-2], !INTEGERP (lx))
21103 || (ly = poly[n-1], !INTEGERP (lx)))
21104 return 0;
21105 x0 = XINT (lx), y0 = XINT (ly);
21106 for (i = 0; i < n; i += 2)
21107 {
21108 int x1 = x0, y1 = y0;
21109 if ((lx = poly[i], !INTEGERP (lx))
21110 || (ly = poly[i+1], !INTEGERP (ly)))
21111 return 0;
21112 x0 = XINT (lx), y0 = XINT (ly);
21113
21114 /* Does this segment cross the X line? */
21115 if (x0 >= x)
21116 {
21117 if (x1 >= x)
21118 continue;
21119 }
21120 else if (x1 < x)
21121 continue;
21122 if (y > y0 && y > y1)
21123 continue;
21124 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
21125 inside = !inside;
21126 }
21127 return inside;
21128 }
21129 }
21130 /* If we don't understand the format, pretend we're not in the hot-spot. */
21131 return 0;
21132 }
21133
21134 Lisp_Object
21135 find_hot_spot (map, x, y)
21136 Lisp_Object map;
21137 int x, y;
21138 {
21139 while (CONSP (map))
21140 {
21141 if (CONSP (XCAR (map))
21142 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
21143 return XCAR (map);
21144 map = XCDR (map);
21145 }
21146
21147 return Qnil;
21148 }
21149
21150 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
21151 3, 3, 0,
21152 doc: /* Lookup in image map MAP coordinates X and Y.
21153 An image map is an alist where each element has the format (AREA ID PLIST).
21154 An AREA is specified as either a rectangle, a circle, or a polygon:
21155 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
21156 pixel coordinates of the upper left and bottom right corners.
21157 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
21158 and the radius of the circle; r may be a float or integer.
21159 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
21160 vector describes one corner in the polygon.
21161 Returns the alist element for the first matching AREA in MAP. */)
21162 (map, x, y)
21163 Lisp_Object map;
21164 Lisp_Object x, y;
21165 {
21166 if (NILP (map))
21167 return Qnil;
21168
21169 CHECK_NUMBER (x);
21170 CHECK_NUMBER (y);
21171
21172 return find_hot_spot (map, XINT (x), XINT (y));
21173 }
21174
21175
21176 /* Display frame CURSOR, optionally using shape defined by POINTER. */
21177 static void
21178 define_frame_cursor1 (f, cursor, pointer)
21179 struct frame *f;
21180 Cursor cursor;
21181 Lisp_Object pointer;
21182 {
21183 /* Do not change cursor shape while dragging mouse. */
21184 if (!NILP (do_mouse_tracking))
21185 return;
21186
21187 if (!NILP (pointer))
21188 {
21189 if (EQ (pointer, Qarrow))
21190 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21191 else if (EQ (pointer, Qhand))
21192 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
21193 else if (EQ (pointer, Qtext))
21194 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21195 else if (EQ (pointer, intern ("hdrag")))
21196 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21197 #ifdef HAVE_X_WINDOWS
21198 else if (EQ (pointer, intern ("vdrag")))
21199 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
21200 #endif
21201 else if (EQ (pointer, intern ("hourglass")))
21202 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
21203 else if (EQ (pointer, Qmodeline))
21204 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
21205 else
21206 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21207 }
21208
21209 if (cursor != No_Cursor)
21210 rif->define_frame_cursor (f, cursor);
21211 }
21212
21213 /* Take proper action when mouse has moved to the mode or header line
21214 or marginal area AREA of window W, x-position X and y-position Y.
21215 X is relative to the start of the text display area of W, so the
21216 width of bitmap areas and scroll bars must be subtracted to get a
21217 position relative to the start of the mode line. */
21218
21219 static void
21220 note_mode_line_or_margin_highlight (w, x, y, area)
21221 struct window *w;
21222 int x, y;
21223 enum window_part area;
21224 {
21225 struct frame *f = XFRAME (w->frame);
21226 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21227 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21228 Lisp_Object pointer = Qnil;
21229 int charpos, dx, dy, width, height;
21230 Lisp_Object string, object = Qnil;
21231 Lisp_Object pos, help;
21232
21233 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
21234 string = mode_line_string (w, area, &x, &y, &charpos,
21235 &object, &dx, &dy, &width, &height);
21236 else
21237 {
21238 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
21239 string = marginal_area_string (w, area, &x, &y, &charpos,
21240 &object, &dx, &dy, &width, &height);
21241 }
21242
21243 help = Qnil;
21244
21245 if (IMAGEP (object))
21246 {
21247 Lisp_Object image_map, hotspot;
21248 if ((image_map = Fsafe_plist_get (XCDR (object), QCmap),
21249 !NILP (image_map))
21250 && (hotspot = find_hot_spot (image_map, dx, dy),
21251 CONSP (hotspot))
21252 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21253 {
21254 Lisp_Object area_id, plist;
21255
21256 area_id = XCAR (hotspot);
21257 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21258 If so, we could look for mouse-enter, mouse-leave
21259 properties in PLIST (and do something...). */
21260 hotspot = XCDR (hotspot);
21261 if (CONSP (hotspot)
21262 && (plist = XCAR (hotspot), CONSP (plist)))
21263 {
21264 pointer = Fsafe_plist_get (plist, Qpointer);
21265 if (NILP (pointer))
21266 pointer = Qhand;
21267 help = Fsafe_plist_get (plist, Qhelp_echo);
21268 if (!NILP (help))
21269 {
21270 help_echo_string = help;
21271 /* Is this correct? ++kfs */
21272 XSETWINDOW (help_echo_window, w);
21273 help_echo_object = w->buffer;
21274 help_echo_pos = charpos;
21275 }
21276 }
21277 }
21278 if (NILP (pointer))
21279 pointer = Fsafe_plist_get (XCDR (object), QCpointer);
21280 }
21281
21282 if (STRINGP (string))
21283 {
21284 pos = make_number (charpos);
21285 /* If we're on a string with `help-echo' text property, arrange
21286 for the help to be displayed. This is done by setting the
21287 global variable help_echo_string to the help string. */
21288 if (NILP (help))
21289 {
21290 help = Fget_text_property (pos, Qhelp_echo, string);
21291 if (!NILP (help))
21292 {
21293 help_echo_string = help;
21294 XSETWINDOW (help_echo_window, w);
21295 help_echo_object = string;
21296 help_echo_pos = charpos;
21297 }
21298 }
21299
21300 if (NILP (pointer))
21301 pointer = Fget_text_property (pos, Qpointer, string);
21302
21303 /* Change the mouse pointer according to what is under X/Y. */
21304 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
21305 {
21306 Lisp_Object map;
21307 map = Fget_text_property (pos, Qlocal_map, string);
21308 if (!KEYMAPP (map))
21309 map = Fget_text_property (pos, Qkeymap, string);
21310 if (!KEYMAPP (map))
21311 cursor = dpyinfo->vertical_scroll_bar_cursor;
21312 }
21313 }
21314
21315 define_frame_cursor1 (f, cursor, pointer);
21316 }
21317
21318
21319 /* EXPORT:
21320 Take proper action when the mouse has moved to position X, Y on
21321 frame F as regards highlighting characters that have mouse-face
21322 properties. Also de-highlighting chars where the mouse was before.
21323 X and Y can be negative or out of range. */
21324
21325 void
21326 note_mouse_highlight (f, x, y)
21327 struct frame *f;
21328 int x, y;
21329 {
21330 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21331 enum window_part part;
21332 Lisp_Object window;
21333 struct window *w;
21334 Cursor cursor = No_Cursor;
21335 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21336 struct buffer *b;
21337
21338 /* When a menu is active, don't highlight because this looks odd. */
21339 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21340 if (popup_activated ())
21341 return;
21342 #endif
21343
21344 if (NILP (Vmouse_highlight)
21345 || !f->glyphs_initialized_p)
21346 return;
21347
21348 dpyinfo->mouse_face_mouse_x = x;
21349 dpyinfo->mouse_face_mouse_y = y;
21350 dpyinfo->mouse_face_mouse_frame = f;
21351
21352 if (dpyinfo->mouse_face_defer)
21353 return;
21354
21355 if (gc_in_progress)
21356 {
21357 dpyinfo->mouse_face_deferred_gc = 1;
21358 return;
21359 }
21360
21361 /* Which window is that in? */
21362 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21363
21364 /* If we were displaying active text in another window, clear that.
21365 Also clear if we move out of text area in same window. */
21366 if (! EQ (window, dpyinfo->mouse_face_window)
21367 || (part != ON_TEXT && !NILP (dpyinfo->mouse_face_window)))
21368 clear_mouse_face (dpyinfo);
21369
21370 /* Not on a window -> return. */
21371 if (!WINDOWP (window))
21372 return;
21373
21374 /* Reset help_echo_string. It will get recomputed below. */
21375 help_echo_string = Qnil;
21376
21377 /* Convert to window-relative pixel coordinates. */
21378 w = XWINDOW (window);
21379 frame_to_window_pixel_xy (w, &x, &y);
21380
21381 /* Handle tool-bar window differently since it doesn't display a
21382 buffer. */
21383 if (EQ (window, f->tool_bar_window))
21384 {
21385 note_tool_bar_highlight (f, x, y);
21386 return;
21387 }
21388
21389 /* Mouse is on the mode, header line or margin? */
21390 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21391 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21392 {
21393 note_mode_line_or_margin_highlight (w, x, y, part);
21394 return;
21395 }
21396
21397 if (part == ON_VERTICAL_BORDER)
21398 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21399 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21400 || part == ON_SCROLL_BAR)
21401 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21402 else
21403 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21404
21405 /* Are we in a window whose display is up to date?
21406 And verify the buffer's text has not changed. */
21407 b = XBUFFER (w->buffer);
21408 if (part == ON_TEXT
21409 && EQ (w->window_end_valid, w->buffer)
21410 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21411 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21412 {
21413 int hpos, vpos, pos, i, dx, dy, area;
21414 struct glyph *glyph;
21415 Lisp_Object object;
21416 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21417 Lisp_Object *overlay_vec = NULL;
21418 int noverlays;
21419 struct buffer *obuf;
21420 int obegv, ozv, same_region;
21421
21422 /* Find the glyph under X/Y. */
21423 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21424
21425 /* Look for :pointer property on image. */
21426 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21427 {
21428 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21429 if (img != NULL && IMAGEP (img->spec))
21430 {
21431 Lisp_Object image_map, hotspot;
21432 if ((image_map = Fsafe_plist_get (XCDR (img->spec), QCmap),
21433 !NILP (image_map))
21434 && (hotspot = find_hot_spot (image_map,
21435 glyph->slice.x + dx,
21436 glyph->slice.y + dy),
21437 CONSP (hotspot))
21438 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21439 {
21440 Lisp_Object area_id, plist;
21441
21442 area_id = XCAR (hotspot);
21443 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21444 If so, we could look for mouse-enter, mouse-leave
21445 properties in PLIST (and do something...). */
21446 hotspot = XCDR (hotspot);
21447 if (CONSP (hotspot)
21448 && (plist = XCAR (hotspot), CONSP (plist)))
21449 {
21450 pointer = Fsafe_plist_get (plist, Qpointer);
21451 if (NILP (pointer))
21452 pointer = Qhand;
21453 help_echo_string = Fsafe_plist_get (plist, Qhelp_echo);
21454 if (!NILP (help_echo_string))
21455 {
21456 help_echo_window = window;
21457 help_echo_object = glyph->object;
21458 help_echo_pos = glyph->charpos;
21459 }
21460 }
21461 }
21462 if (NILP (pointer))
21463 pointer = Fsafe_plist_get (XCDR (img->spec), QCpointer);
21464 }
21465 }
21466
21467 /* Clear mouse face if X/Y not over text. */
21468 if (glyph == NULL
21469 || area != TEXT_AREA
21470 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21471 {
21472 if (clear_mouse_face (dpyinfo))
21473 cursor = No_Cursor;
21474 if (NILP (pointer))
21475 {
21476 if (area != TEXT_AREA)
21477 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21478 else
21479 pointer = Vvoid_text_area_pointer;
21480 }
21481 goto set_cursor;
21482 }
21483
21484 pos = glyph->charpos;
21485 object = glyph->object;
21486 if (!STRINGP (object) && !BUFFERP (object))
21487 goto set_cursor;
21488
21489 /* If we get an out-of-range value, return now; avoid an error. */
21490 if (BUFFERP (object) && pos > BUF_Z (b))
21491 goto set_cursor;
21492
21493 /* Make the window's buffer temporarily current for
21494 overlays_at and compute_char_face. */
21495 obuf = current_buffer;
21496 current_buffer = b;
21497 obegv = BEGV;
21498 ozv = ZV;
21499 BEGV = BEG;
21500 ZV = Z;
21501
21502 /* Is this char mouse-active or does it have help-echo? */
21503 position = make_number (pos);
21504
21505 if (BUFFERP (object))
21506 {
21507 /* Put all the overlays we want in a vector in overlay_vec. */
21508 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21509 /* Sort overlays into increasing priority order. */
21510 noverlays = sort_overlays (overlay_vec, noverlays, w);
21511 }
21512 else
21513 noverlays = 0;
21514
21515 same_region = (EQ (window, dpyinfo->mouse_face_window)
21516 && vpos >= dpyinfo->mouse_face_beg_row
21517 && vpos <= dpyinfo->mouse_face_end_row
21518 && (vpos > dpyinfo->mouse_face_beg_row
21519 || hpos >= dpyinfo->mouse_face_beg_col)
21520 && (vpos < dpyinfo->mouse_face_end_row
21521 || hpos < dpyinfo->mouse_face_end_col
21522 || dpyinfo->mouse_face_past_end));
21523
21524 if (same_region)
21525 cursor = No_Cursor;
21526
21527 /* Check mouse-face highlighting. */
21528 if (! same_region
21529 /* If there exists an overlay with mouse-face overlapping
21530 the one we are currently highlighting, we have to
21531 check if we enter the overlapping overlay, and then
21532 highlight only that. */
21533 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21534 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21535 {
21536 /* Find the highest priority overlay that has a mouse-face
21537 property. */
21538 overlay = Qnil;
21539 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21540 {
21541 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21542 if (!NILP (mouse_face))
21543 overlay = overlay_vec[i];
21544 }
21545
21546 /* If we're actually highlighting the same overlay as
21547 before, there's no need to do that again. */
21548 if (!NILP (overlay)
21549 && EQ (overlay, dpyinfo->mouse_face_overlay))
21550 goto check_help_echo;
21551
21552 dpyinfo->mouse_face_overlay = overlay;
21553
21554 /* Clear the display of the old active region, if any. */
21555 if (clear_mouse_face (dpyinfo))
21556 cursor = No_Cursor;
21557
21558 /* If no overlay applies, get a text property. */
21559 if (NILP (overlay))
21560 mouse_face = Fget_text_property (position, Qmouse_face, object);
21561
21562 /* Handle the overlay case. */
21563 if (!NILP (overlay))
21564 {
21565 /* Find the range of text around this char that
21566 should be active. */
21567 Lisp_Object before, after;
21568 int ignore;
21569
21570 before = Foverlay_start (overlay);
21571 after = Foverlay_end (overlay);
21572 /* Record this as the current active region. */
21573 fast_find_position (w, XFASTINT (before),
21574 &dpyinfo->mouse_face_beg_col,
21575 &dpyinfo->mouse_face_beg_row,
21576 &dpyinfo->mouse_face_beg_x,
21577 &dpyinfo->mouse_face_beg_y, Qnil);
21578
21579 dpyinfo->mouse_face_past_end
21580 = !fast_find_position (w, XFASTINT (after),
21581 &dpyinfo->mouse_face_end_col,
21582 &dpyinfo->mouse_face_end_row,
21583 &dpyinfo->mouse_face_end_x,
21584 &dpyinfo->mouse_face_end_y, Qnil);
21585 dpyinfo->mouse_face_window = window;
21586
21587 dpyinfo->mouse_face_face_id
21588 = face_at_buffer_position (w, pos, 0, 0,
21589 &ignore, pos + 1,
21590 !dpyinfo->mouse_face_hidden);
21591
21592 /* Display it as active. */
21593 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21594 cursor = No_Cursor;
21595 }
21596 /* Handle the text property case. */
21597 else if (!NILP (mouse_face) && BUFFERP (object))
21598 {
21599 /* Find the range of text around this char that
21600 should be active. */
21601 Lisp_Object before, after, beginning, end;
21602 int ignore;
21603
21604 beginning = Fmarker_position (w->start);
21605 end = make_number (BUF_Z (XBUFFER (object))
21606 - XFASTINT (w->window_end_pos));
21607 before
21608 = Fprevious_single_property_change (make_number (pos + 1),
21609 Qmouse_face,
21610 object, beginning);
21611 after
21612 = Fnext_single_property_change (position, Qmouse_face,
21613 object, end);
21614
21615 /* Record this as the current active region. */
21616 fast_find_position (w, XFASTINT (before),
21617 &dpyinfo->mouse_face_beg_col,
21618 &dpyinfo->mouse_face_beg_row,
21619 &dpyinfo->mouse_face_beg_x,
21620 &dpyinfo->mouse_face_beg_y, Qnil);
21621 dpyinfo->mouse_face_past_end
21622 = !fast_find_position (w, XFASTINT (after),
21623 &dpyinfo->mouse_face_end_col,
21624 &dpyinfo->mouse_face_end_row,
21625 &dpyinfo->mouse_face_end_x,
21626 &dpyinfo->mouse_face_end_y, Qnil);
21627 dpyinfo->mouse_face_window = window;
21628
21629 if (BUFFERP (object))
21630 dpyinfo->mouse_face_face_id
21631 = face_at_buffer_position (w, pos, 0, 0,
21632 &ignore, pos + 1,
21633 !dpyinfo->mouse_face_hidden);
21634
21635 /* Display it as active. */
21636 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21637 cursor = No_Cursor;
21638 }
21639 else if (!NILP (mouse_face) && STRINGP (object))
21640 {
21641 Lisp_Object b, e;
21642 int ignore;
21643
21644 b = Fprevious_single_property_change (make_number (pos + 1),
21645 Qmouse_face,
21646 object, Qnil);
21647 e = Fnext_single_property_change (position, Qmouse_face,
21648 object, Qnil);
21649 if (NILP (b))
21650 b = make_number (0);
21651 if (NILP (e))
21652 e = make_number (SCHARS (object) - 1);
21653 fast_find_string_pos (w, XINT (b), object,
21654 &dpyinfo->mouse_face_beg_col,
21655 &dpyinfo->mouse_face_beg_row,
21656 &dpyinfo->mouse_face_beg_x,
21657 &dpyinfo->mouse_face_beg_y, 0);
21658 fast_find_string_pos (w, XINT (e), object,
21659 &dpyinfo->mouse_face_end_col,
21660 &dpyinfo->mouse_face_end_row,
21661 &dpyinfo->mouse_face_end_x,
21662 &dpyinfo->mouse_face_end_y, 1);
21663 dpyinfo->mouse_face_past_end = 0;
21664 dpyinfo->mouse_face_window = window;
21665 dpyinfo->mouse_face_face_id
21666 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21667 glyph->face_id, 1);
21668 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21669 cursor = No_Cursor;
21670 }
21671 else if (STRINGP (object) && NILP (mouse_face))
21672 {
21673 /* A string which doesn't have mouse-face, but
21674 the text ``under'' it might have. */
21675 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21676 int start = MATRIX_ROW_START_CHARPOS (r);
21677
21678 pos = string_buffer_position (w, object, start);
21679 if (pos > 0)
21680 mouse_face = get_char_property_and_overlay (make_number (pos),
21681 Qmouse_face,
21682 w->buffer,
21683 &overlay);
21684 if (!NILP (mouse_face) && !NILP (overlay))
21685 {
21686 Lisp_Object before = Foverlay_start (overlay);
21687 Lisp_Object after = Foverlay_end (overlay);
21688 int ignore;
21689
21690 /* Note that we might not be able to find position
21691 BEFORE in the glyph matrix if the overlay is
21692 entirely covered by a `display' property. In
21693 this case, we overshoot. So let's stop in
21694 the glyph matrix before glyphs for OBJECT. */
21695 fast_find_position (w, XFASTINT (before),
21696 &dpyinfo->mouse_face_beg_col,
21697 &dpyinfo->mouse_face_beg_row,
21698 &dpyinfo->mouse_face_beg_x,
21699 &dpyinfo->mouse_face_beg_y,
21700 object);
21701
21702 dpyinfo->mouse_face_past_end
21703 = !fast_find_position (w, XFASTINT (after),
21704 &dpyinfo->mouse_face_end_col,
21705 &dpyinfo->mouse_face_end_row,
21706 &dpyinfo->mouse_face_end_x,
21707 &dpyinfo->mouse_face_end_y,
21708 Qnil);
21709 dpyinfo->mouse_face_window = window;
21710 dpyinfo->mouse_face_face_id
21711 = face_at_buffer_position (w, pos, 0, 0,
21712 &ignore, pos + 1,
21713 !dpyinfo->mouse_face_hidden);
21714
21715 /* Display it as active. */
21716 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21717 cursor = No_Cursor;
21718 }
21719 }
21720 }
21721
21722 check_help_echo:
21723
21724 /* Look for a `help-echo' property. */
21725 if (NILP (help_echo_string)) {
21726 Lisp_Object help, overlay;
21727
21728 /* Check overlays first. */
21729 help = overlay = Qnil;
21730 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21731 {
21732 overlay = overlay_vec[i];
21733 help = Foverlay_get (overlay, Qhelp_echo);
21734 }
21735
21736 if (!NILP (help))
21737 {
21738 help_echo_string = help;
21739 help_echo_window = window;
21740 help_echo_object = overlay;
21741 help_echo_pos = pos;
21742 }
21743 else
21744 {
21745 Lisp_Object object = glyph->object;
21746 int charpos = glyph->charpos;
21747
21748 /* Try text properties. */
21749 if (STRINGP (object)
21750 && charpos >= 0
21751 && charpos < SCHARS (object))
21752 {
21753 help = Fget_text_property (make_number (charpos),
21754 Qhelp_echo, object);
21755 if (NILP (help))
21756 {
21757 /* If the string itself doesn't specify a help-echo,
21758 see if the buffer text ``under'' it does. */
21759 struct glyph_row *r
21760 = MATRIX_ROW (w->current_matrix, vpos);
21761 int start = MATRIX_ROW_START_CHARPOS (r);
21762 int pos = string_buffer_position (w, object, start);
21763 if (pos > 0)
21764 {
21765 help = Fget_char_property (make_number (pos),
21766 Qhelp_echo, w->buffer);
21767 if (!NILP (help))
21768 {
21769 charpos = pos;
21770 object = w->buffer;
21771 }
21772 }
21773 }
21774 }
21775 else if (BUFFERP (object)
21776 && charpos >= BEGV
21777 && charpos < ZV)
21778 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21779 object);
21780
21781 if (!NILP (help))
21782 {
21783 help_echo_string = help;
21784 help_echo_window = window;
21785 help_echo_object = object;
21786 help_echo_pos = charpos;
21787 }
21788 }
21789 }
21790
21791 /* Look for a `pointer' property. */
21792 if (NILP (pointer))
21793 {
21794 /* Check overlays first. */
21795 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21796 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21797
21798 if (NILP (pointer))
21799 {
21800 Lisp_Object object = glyph->object;
21801 int charpos = glyph->charpos;
21802
21803 /* Try text properties. */
21804 if (STRINGP (object)
21805 && charpos >= 0
21806 && charpos < SCHARS (object))
21807 {
21808 pointer = Fget_text_property (make_number (charpos),
21809 Qpointer, object);
21810 if (NILP (pointer))
21811 {
21812 /* If the string itself doesn't specify a pointer,
21813 see if the buffer text ``under'' it does. */
21814 struct glyph_row *r
21815 = MATRIX_ROW (w->current_matrix, vpos);
21816 int start = MATRIX_ROW_START_CHARPOS (r);
21817 int pos = string_buffer_position (w, object, start);
21818 if (pos > 0)
21819 pointer = Fget_char_property (make_number (pos),
21820 Qpointer, w->buffer);
21821 }
21822 }
21823 else if (BUFFERP (object)
21824 && charpos >= BEGV
21825 && charpos < ZV)
21826 pointer = Fget_text_property (make_number (charpos),
21827 Qpointer, object);
21828 }
21829 }
21830
21831 BEGV = obegv;
21832 ZV = ozv;
21833 current_buffer = obuf;
21834 }
21835
21836 set_cursor:
21837
21838 define_frame_cursor1 (f, cursor, pointer);
21839 }
21840
21841
21842 /* EXPORT for RIF:
21843 Clear any mouse-face on window W. This function is part of the
21844 redisplay interface, and is called from try_window_id and similar
21845 functions to ensure the mouse-highlight is off. */
21846
21847 void
21848 x_clear_window_mouse_face (w)
21849 struct window *w;
21850 {
21851 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21852 Lisp_Object window;
21853
21854 BLOCK_INPUT;
21855 XSETWINDOW (window, w);
21856 if (EQ (window, dpyinfo->mouse_face_window))
21857 clear_mouse_face (dpyinfo);
21858 UNBLOCK_INPUT;
21859 }
21860
21861
21862 /* EXPORT:
21863 Just discard the mouse face information for frame F, if any.
21864 This is used when the size of F is changed. */
21865
21866 void
21867 cancel_mouse_face (f)
21868 struct frame *f;
21869 {
21870 Lisp_Object window;
21871 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21872
21873 window = dpyinfo->mouse_face_window;
21874 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21875 {
21876 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21877 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21878 dpyinfo->mouse_face_window = Qnil;
21879 }
21880 }
21881
21882
21883 #endif /* HAVE_WINDOW_SYSTEM */
21884
21885 \f
21886 /***********************************************************************
21887 Exposure Events
21888 ***********************************************************************/
21889
21890 #ifdef HAVE_WINDOW_SYSTEM
21891
21892 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21893 which intersects rectangle R. R is in window-relative coordinates. */
21894
21895 static void
21896 expose_area (w, row, r, area)
21897 struct window *w;
21898 struct glyph_row *row;
21899 XRectangle *r;
21900 enum glyph_row_area area;
21901 {
21902 struct glyph *first = row->glyphs[area];
21903 struct glyph *end = row->glyphs[area] + row->used[area];
21904 struct glyph *last;
21905 int first_x, start_x, x;
21906
21907 if (area == TEXT_AREA && row->fill_line_p)
21908 /* If row extends face to end of line write the whole line. */
21909 draw_glyphs (w, 0, row, area,
21910 0, row->used[area],
21911 DRAW_NORMAL_TEXT, 0);
21912 else
21913 {
21914 /* Set START_X to the window-relative start position for drawing glyphs of
21915 AREA. The first glyph of the text area can be partially visible.
21916 The first glyphs of other areas cannot. */
21917 start_x = window_box_left_offset (w, area);
21918 x = start_x;
21919 if (area == TEXT_AREA)
21920 x += row->x;
21921
21922 /* Find the first glyph that must be redrawn. */
21923 while (first < end
21924 && x + first->pixel_width < r->x)
21925 {
21926 x += first->pixel_width;
21927 ++first;
21928 }
21929
21930 /* Find the last one. */
21931 last = first;
21932 first_x = x;
21933 while (last < end
21934 && x < r->x + r->width)
21935 {
21936 x += last->pixel_width;
21937 ++last;
21938 }
21939
21940 /* Repaint. */
21941 if (last > first)
21942 draw_glyphs (w, first_x - start_x, row, area,
21943 first - row->glyphs[area], last - row->glyphs[area],
21944 DRAW_NORMAL_TEXT, 0);
21945 }
21946 }
21947
21948
21949 /* Redraw the parts of the glyph row ROW on window W intersecting
21950 rectangle R. R is in window-relative coordinates. Value is
21951 non-zero if mouse-face was overwritten. */
21952
21953 static int
21954 expose_line (w, row, r)
21955 struct window *w;
21956 struct glyph_row *row;
21957 XRectangle *r;
21958 {
21959 xassert (row->enabled_p);
21960
21961 if (row->mode_line_p || w->pseudo_window_p)
21962 draw_glyphs (w, 0, row, TEXT_AREA,
21963 0, row->used[TEXT_AREA],
21964 DRAW_NORMAL_TEXT, 0);
21965 else
21966 {
21967 if (row->used[LEFT_MARGIN_AREA])
21968 expose_area (w, row, r, LEFT_MARGIN_AREA);
21969 if (row->used[TEXT_AREA])
21970 expose_area (w, row, r, TEXT_AREA);
21971 if (row->used[RIGHT_MARGIN_AREA])
21972 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21973 draw_row_fringe_bitmaps (w, row);
21974 }
21975
21976 return row->mouse_face_p;
21977 }
21978
21979
21980 /* Redraw those parts of glyphs rows during expose event handling that
21981 overlap other rows. Redrawing of an exposed line writes over parts
21982 of lines overlapping that exposed line; this function fixes that.
21983
21984 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21985 row in W's current matrix that is exposed and overlaps other rows.
21986 LAST_OVERLAPPING_ROW is the last such row. */
21987
21988 static void
21989 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21990 struct window *w;
21991 struct glyph_row *first_overlapping_row;
21992 struct glyph_row *last_overlapping_row;
21993 {
21994 struct glyph_row *row;
21995
21996 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21997 if (row->overlapping_p)
21998 {
21999 xassert (row->enabled_p && !row->mode_line_p);
22000
22001 if (row->used[LEFT_MARGIN_AREA])
22002 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
22003
22004 if (row->used[TEXT_AREA])
22005 x_fix_overlapping_area (w, row, TEXT_AREA);
22006
22007 if (row->used[RIGHT_MARGIN_AREA])
22008 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
22009 }
22010 }
22011
22012
22013 /* Return non-zero if W's cursor intersects rectangle R. */
22014
22015 static int
22016 phys_cursor_in_rect_p (w, r)
22017 struct window *w;
22018 XRectangle *r;
22019 {
22020 XRectangle cr, result;
22021 struct glyph *cursor_glyph;
22022
22023 cursor_glyph = get_phys_cursor_glyph (w);
22024 if (cursor_glyph)
22025 {
22026 /* r is relative to W's box, but w->phys_cursor.x is relative
22027 to left edge of W's TEXT area. Adjust it. */
22028 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
22029 cr.y = w->phys_cursor.y;
22030 cr.width = cursor_glyph->pixel_width;
22031 cr.height = w->phys_cursor_height;
22032 /* ++KFS: W32 version used W32-specific IntersectRect here, but
22033 I assume the effect is the same -- and this is portable. */
22034 return x_intersect_rectangles (&cr, r, &result);
22035 }
22036 else
22037 return 0;
22038 }
22039
22040
22041 /* EXPORT:
22042 Draw a vertical window border to the right of window W if W doesn't
22043 have vertical scroll bars. */
22044
22045 void
22046 x_draw_vertical_border (w)
22047 struct window *w;
22048 {
22049 /* We could do better, if we knew what type of scroll-bar the adjacent
22050 windows (on either side) have... But we don't :-(
22051 However, I think this works ok. ++KFS 2003-04-25 */
22052
22053 /* Redraw borders between horizontally adjacent windows. Don't
22054 do it for frames with vertical scroll bars because either the
22055 right scroll bar of a window, or the left scroll bar of its
22056 neighbor will suffice as a border. */
22057 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
22058 return;
22059
22060 if (!WINDOW_RIGHTMOST_P (w)
22061 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
22062 {
22063 int x0, x1, y0, y1;
22064
22065 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22066 y1 -= 1;
22067
22068 rif->draw_vertical_window_border (w, x1, y0, y1);
22069 }
22070 else if (!WINDOW_LEFTMOST_P (w)
22071 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
22072 {
22073 int x0, x1, y0, y1;
22074
22075 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22076 y1 -= 1;
22077
22078 rif->draw_vertical_window_border (w, x0, y0, y1);
22079 }
22080 }
22081
22082
22083 /* Redraw the part of window W intersection rectangle FR. Pixel
22084 coordinates in FR are frame-relative. Call this function with
22085 input blocked. Value is non-zero if the exposure overwrites
22086 mouse-face. */
22087
22088 static int
22089 expose_window (w, fr)
22090 struct window *w;
22091 XRectangle *fr;
22092 {
22093 struct frame *f = XFRAME (w->frame);
22094 XRectangle wr, r;
22095 int mouse_face_overwritten_p = 0;
22096
22097 /* If window is not yet fully initialized, do nothing. This can
22098 happen when toolkit scroll bars are used and a window is split.
22099 Reconfiguring the scroll bar will generate an expose for a newly
22100 created window. */
22101 if (w->current_matrix == NULL)
22102 return 0;
22103
22104 /* When we're currently updating the window, display and current
22105 matrix usually don't agree. Arrange for a thorough display
22106 later. */
22107 if (w == updated_window)
22108 {
22109 SET_FRAME_GARBAGED (f);
22110 return 0;
22111 }
22112
22113 /* Frame-relative pixel rectangle of W. */
22114 wr.x = WINDOW_LEFT_EDGE_X (w);
22115 wr.y = WINDOW_TOP_EDGE_Y (w);
22116 wr.width = WINDOW_TOTAL_WIDTH (w);
22117 wr.height = WINDOW_TOTAL_HEIGHT (w);
22118
22119 if (x_intersect_rectangles (fr, &wr, &r))
22120 {
22121 int yb = window_text_bottom_y (w);
22122 struct glyph_row *row;
22123 int cursor_cleared_p;
22124 struct glyph_row *first_overlapping_row, *last_overlapping_row;
22125
22126 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
22127 r.x, r.y, r.width, r.height));
22128
22129 /* Convert to window coordinates. */
22130 r.x -= WINDOW_LEFT_EDGE_X (w);
22131 r.y -= WINDOW_TOP_EDGE_Y (w);
22132
22133 /* Turn off the cursor. */
22134 if (!w->pseudo_window_p
22135 && phys_cursor_in_rect_p (w, &r))
22136 {
22137 x_clear_cursor (w);
22138 cursor_cleared_p = 1;
22139 }
22140 else
22141 cursor_cleared_p = 0;
22142
22143 /* Update lines intersecting rectangle R. */
22144 first_overlapping_row = last_overlapping_row = NULL;
22145 for (row = w->current_matrix->rows;
22146 row->enabled_p;
22147 ++row)
22148 {
22149 int y0 = row->y;
22150 int y1 = MATRIX_ROW_BOTTOM_Y (row);
22151
22152 if ((y0 >= r.y && y0 < r.y + r.height)
22153 || (y1 > r.y && y1 < r.y + r.height)
22154 || (r.y >= y0 && r.y < y1)
22155 || (r.y + r.height > y0 && r.y + r.height < y1))
22156 {
22157 /* A header line may be overlapping, but there is no need
22158 to fix overlapping areas for them. KFS 2005-02-12 */
22159 if (row->overlapping_p && !row->mode_line_p)
22160 {
22161 if (first_overlapping_row == NULL)
22162 first_overlapping_row = row;
22163 last_overlapping_row = row;
22164 }
22165
22166 if (expose_line (w, row, &r))
22167 mouse_face_overwritten_p = 1;
22168 }
22169
22170 if (y1 >= yb)
22171 break;
22172 }
22173
22174 /* Display the mode line if there is one. */
22175 if (WINDOW_WANTS_MODELINE_P (w)
22176 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
22177 row->enabled_p)
22178 && row->y < r.y + r.height)
22179 {
22180 if (expose_line (w, row, &r))
22181 mouse_face_overwritten_p = 1;
22182 }
22183
22184 if (!w->pseudo_window_p)
22185 {
22186 /* Fix the display of overlapping rows. */
22187 if (first_overlapping_row)
22188 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
22189
22190 /* Draw border between windows. */
22191 x_draw_vertical_border (w);
22192
22193 /* Turn the cursor on again. */
22194 if (cursor_cleared_p)
22195 update_window_cursor (w, 1);
22196 }
22197 }
22198
22199 return mouse_face_overwritten_p;
22200 }
22201
22202
22203
22204 /* Redraw (parts) of all windows in the window tree rooted at W that
22205 intersect R. R contains frame pixel coordinates. Value is
22206 non-zero if the exposure overwrites mouse-face. */
22207
22208 static int
22209 expose_window_tree (w, r)
22210 struct window *w;
22211 XRectangle *r;
22212 {
22213 struct frame *f = XFRAME (w->frame);
22214 int mouse_face_overwritten_p = 0;
22215
22216 while (w && !FRAME_GARBAGED_P (f))
22217 {
22218 if (!NILP (w->hchild))
22219 mouse_face_overwritten_p
22220 |= expose_window_tree (XWINDOW (w->hchild), r);
22221 else if (!NILP (w->vchild))
22222 mouse_face_overwritten_p
22223 |= expose_window_tree (XWINDOW (w->vchild), r);
22224 else
22225 mouse_face_overwritten_p |= expose_window (w, r);
22226
22227 w = NILP (w->next) ? NULL : XWINDOW (w->next);
22228 }
22229
22230 return mouse_face_overwritten_p;
22231 }
22232
22233
22234 /* EXPORT:
22235 Redisplay an exposed area of frame F. X and Y are the upper-left
22236 corner of the exposed rectangle. W and H are width and height of
22237 the exposed area. All are pixel values. W or H zero means redraw
22238 the entire frame. */
22239
22240 void
22241 expose_frame (f, x, y, w, h)
22242 struct frame *f;
22243 int x, y, w, h;
22244 {
22245 XRectangle r;
22246 int mouse_face_overwritten_p = 0;
22247
22248 TRACE ((stderr, "expose_frame "));
22249
22250 /* No need to redraw if frame will be redrawn soon. */
22251 if (FRAME_GARBAGED_P (f))
22252 {
22253 TRACE ((stderr, " garbaged\n"));
22254 return;
22255 }
22256
22257 /* If basic faces haven't been realized yet, there is no point in
22258 trying to redraw anything. This can happen when we get an expose
22259 event while Emacs is starting, e.g. by moving another window. */
22260 if (FRAME_FACE_CACHE (f) == NULL
22261 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
22262 {
22263 TRACE ((stderr, " no faces\n"));
22264 return;
22265 }
22266
22267 if (w == 0 || h == 0)
22268 {
22269 r.x = r.y = 0;
22270 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
22271 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
22272 }
22273 else
22274 {
22275 r.x = x;
22276 r.y = y;
22277 r.width = w;
22278 r.height = h;
22279 }
22280
22281 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
22282 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
22283
22284 if (WINDOWP (f->tool_bar_window))
22285 mouse_face_overwritten_p
22286 |= expose_window (XWINDOW (f->tool_bar_window), &r);
22287
22288 #ifdef HAVE_X_WINDOWS
22289 #ifndef MSDOS
22290 #ifndef USE_X_TOOLKIT
22291 if (WINDOWP (f->menu_bar_window))
22292 mouse_face_overwritten_p
22293 |= expose_window (XWINDOW (f->menu_bar_window), &r);
22294 #endif /* not USE_X_TOOLKIT */
22295 #endif
22296 #endif
22297
22298 /* Some window managers support a focus-follows-mouse style with
22299 delayed raising of frames. Imagine a partially obscured frame,
22300 and moving the mouse into partially obscured mouse-face on that
22301 frame. The visible part of the mouse-face will be highlighted,
22302 then the WM raises the obscured frame. With at least one WM, KDE
22303 2.1, Emacs is not getting any event for the raising of the frame
22304 (even tried with SubstructureRedirectMask), only Expose events.
22305 These expose events will draw text normally, i.e. not
22306 highlighted. Which means we must redo the highlight here.
22307 Subsume it under ``we love X''. --gerd 2001-08-15 */
22308 /* Included in Windows version because Windows most likely does not
22309 do the right thing if any third party tool offers
22310 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22311 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22312 {
22313 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22314 if (f == dpyinfo->mouse_face_mouse_frame)
22315 {
22316 int x = dpyinfo->mouse_face_mouse_x;
22317 int y = dpyinfo->mouse_face_mouse_y;
22318 clear_mouse_face (dpyinfo);
22319 note_mouse_highlight (f, x, y);
22320 }
22321 }
22322 }
22323
22324
22325 /* EXPORT:
22326 Determine the intersection of two rectangles R1 and R2. Return
22327 the intersection in *RESULT. Value is non-zero if RESULT is not
22328 empty. */
22329
22330 int
22331 x_intersect_rectangles (r1, r2, result)
22332 XRectangle *r1, *r2, *result;
22333 {
22334 XRectangle *left, *right;
22335 XRectangle *upper, *lower;
22336 int intersection_p = 0;
22337
22338 /* Rearrange so that R1 is the left-most rectangle. */
22339 if (r1->x < r2->x)
22340 left = r1, right = r2;
22341 else
22342 left = r2, right = r1;
22343
22344 /* X0 of the intersection is right.x0, if this is inside R1,
22345 otherwise there is no intersection. */
22346 if (right->x <= left->x + left->width)
22347 {
22348 result->x = right->x;
22349
22350 /* The right end of the intersection is the minimum of the
22351 the right ends of left and right. */
22352 result->width = (min (left->x + left->width, right->x + right->width)
22353 - result->x);
22354
22355 /* Same game for Y. */
22356 if (r1->y < r2->y)
22357 upper = r1, lower = r2;
22358 else
22359 upper = r2, lower = r1;
22360
22361 /* The upper end of the intersection is lower.y0, if this is inside
22362 of upper. Otherwise, there is no intersection. */
22363 if (lower->y <= upper->y + upper->height)
22364 {
22365 result->y = lower->y;
22366
22367 /* The lower end of the intersection is the minimum of the lower
22368 ends of upper and lower. */
22369 result->height = (min (lower->y + lower->height,
22370 upper->y + upper->height)
22371 - result->y);
22372 intersection_p = 1;
22373 }
22374 }
22375
22376 return intersection_p;
22377 }
22378
22379 #endif /* HAVE_WINDOW_SYSTEM */
22380
22381 \f
22382 /***********************************************************************
22383 Initialization
22384 ***********************************************************************/
22385
22386 void
22387 syms_of_xdisp ()
22388 {
22389 Vwith_echo_area_save_vector = Qnil;
22390 staticpro (&Vwith_echo_area_save_vector);
22391
22392 Vmessage_stack = Qnil;
22393 staticpro (&Vmessage_stack);
22394
22395 Qinhibit_redisplay = intern ("inhibit-redisplay");
22396 staticpro (&Qinhibit_redisplay);
22397
22398 message_dolog_marker1 = Fmake_marker ();
22399 staticpro (&message_dolog_marker1);
22400 message_dolog_marker2 = Fmake_marker ();
22401 staticpro (&message_dolog_marker2);
22402 message_dolog_marker3 = Fmake_marker ();
22403 staticpro (&message_dolog_marker3);
22404
22405 #if GLYPH_DEBUG
22406 defsubr (&Sdump_frame_glyph_matrix);
22407 defsubr (&Sdump_glyph_matrix);
22408 defsubr (&Sdump_glyph_row);
22409 defsubr (&Sdump_tool_bar_row);
22410 defsubr (&Strace_redisplay);
22411 defsubr (&Strace_to_stderr);
22412 #endif
22413 #ifdef HAVE_WINDOW_SYSTEM
22414 defsubr (&Stool_bar_lines_needed);
22415 defsubr (&Slookup_image_map);
22416 #endif
22417 defsubr (&Sformat_mode_line);
22418
22419 staticpro (&Qmenu_bar_update_hook);
22420 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22421
22422 staticpro (&Qoverriding_terminal_local_map);
22423 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22424
22425 staticpro (&Qoverriding_local_map);
22426 Qoverriding_local_map = intern ("overriding-local-map");
22427
22428 staticpro (&Qwindow_scroll_functions);
22429 Qwindow_scroll_functions = intern ("window-scroll-functions");
22430
22431 staticpro (&Qredisplay_end_trigger_functions);
22432 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22433
22434 staticpro (&Qinhibit_point_motion_hooks);
22435 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22436
22437 QCdata = intern (":data");
22438 staticpro (&QCdata);
22439 Qdisplay = intern ("display");
22440 staticpro (&Qdisplay);
22441 Qspace_width = intern ("space-width");
22442 staticpro (&Qspace_width);
22443 Qraise = intern ("raise");
22444 staticpro (&Qraise);
22445 Qslice = intern ("slice");
22446 staticpro (&Qslice);
22447 Qspace = intern ("space");
22448 staticpro (&Qspace);
22449 Qmargin = intern ("margin");
22450 staticpro (&Qmargin);
22451 Qpointer = intern ("pointer");
22452 staticpro (&Qpointer);
22453 Qleft_margin = intern ("left-margin");
22454 staticpro (&Qleft_margin);
22455 Qright_margin = intern ("right-margin");
22456 staticpro (&Qright_margin);
22457 Qcenter = intern ("center");
22458 staticpro (&Qcenter);
22459 Qline_height = intern ("line-height");
22460 staticpro (&Qline_height);
22461 QCalign_to = intern (":align-to");
22462 staticpro (&QCalign_to);
22463 QCrelative_width = intern (":relative-width");
22464 staticpro (&QCrelative_width);
22465 QCrelative_height = intern (":relative-height");
22466 staticpro (&QCrelative_height);
22467 QCeval = intern (":eval");
22468 staticpro (&QCeval);
22469 QCpropertize = intern (":propertize");
22470 staticpro (&QCpropertize);
22471 QCfile = intern (":file");
22472 staticpro (&QCfile);
22473 Qfontified = intern ("fontified");
22474 staticpro (&Qfontified);
22475 Qfontification_functions = intern ("fontification-functions");
22476 staticpro (&Qfontification_functions);
22477 Qtrailing_whitespace = intern ("trailing-whitespace");
22478 staticpro (&Qtrailing_whitespace);
22479 Qescape_glyph = intern ("escape-glyph");
22480 staticpro (&Qescape_glyph);
22481 Qimage = intern ("image");
22482 staticpro (&Qimage);
22483 QCmap = intern (":map");
22484 staticpro (&QCmap);
22485 QCpointer = intern (":pointer");
22486 staticpro (&QCpointer);
22487 Qrect = intern ("rect");
22488 staticpro (&Qrect);
22489 Qcircle = intern ("circle");
22490 staticpro (&Qcircle);
22491 Qpoly = intern ("poly");
22492 staticpro (&Qpoly);
22493 Qmessage_truncate_lines = intern ("message-truncate-lines");
22494 staticpro (&Qmessage_truncate_lines);
22495 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22496 staticpro (&Qcursor_in_non_selected_windows);
22497 Qgrow_only = intern ("grow-only");
22498 staticpro (&Qgrow_only);
22499 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22500 staticpro (&Qinhibit_menubar_update);
22501 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22502 staticpro (&Qinhibit_eval_during_redisplay);
22503 Qposition = intern ("position");
22504 staticpro (&Qposition);
22505 Qbuffer_position = intern ("buffer-position");
22506 staticpro (&Qbuffer_position);
22507 Qobject = intern ("object");
22508 staticpro (&Qobject);
22509 Qbar = intern ("bar");
22510 staticpro (&Qbar);
22511 Qhbar = intern ("hbar");
22512 staticpro (&Qhbar);
22513 Qbox = intern ("box");
22514 staticpro (&Qbox);
22515 Qhollow = intern ("hollow");
22516 staticpro (&Qhollow);
22517 Qhand = intern ("hand");
22518 staticpro (&Qhand);
22519 Qarrow = intern ("arrow");
22520 staticpro (&Qarrow);
22521 Qtext = intern ("text");
22522 staticpro (&Qtext);
22523 Qrisky_local_variable = intern ("risky-local-variable");
22524 staticpro (&Qrisky_local_variable);
22525 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22526 staticpro (&Qinhibit_free_realized_faces);
22527
22528 list_of_error = Fcons (Fcons (intern ("error"),
22529 Fcons (intern ("void-variable"), Qnil)),
22530 Qnil);
22531 staticpro (&list_of_error);
22532
22533 Qlast_arrow_position = intern ("last-arrow-position");
22534 staticpro (&Qlast_arrow_position);
22535 Qlast_arrow_string = intern ("last-arrow-string");
22536 staticpro (&Qlast_arrow_string);
22537
22538 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22539 staticpro (&Qoverlay_arrow_string);
22540 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22541 staticpro (&Qoverlay_arrow_bitmap);
22542
22543 echo_buffer[0] = echo_buffer[1] = Qnil;
22544 staticpro (&echo_buffer[0]);
22545 staticpro (&echo_buffer[1]);
22546
22547 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22548 staticpro (&echo_area_buffer[0]);
22549 staticpro (&echo_area_buffer[1]);
22550
22551 Vmessages_buffer_name = build_string ("*Messages*");
22552 staticpro (&Vmessages_buffer_name);
22553
22554 mode_line_proptrans_alist = Qnil;
22555 staticpro (&mode_line_proptrans_alist);
22556
22557 mode_line_string_list = Qnil;
22558 staticpro (&mode_line_string_list);
22559
22560 help_echo_string = Qnil;
22561 staticpro (&help_echo_string);
22562 help_echo_object = Qnil;
22563 staticpro (&help_echo_object);
22564 help_echo_window = Qnil;
22565 staticpro (&help_echo_window);
22566 previous_help_echo_string = Qnil;
22567 staticpro (&previous_help_echo_string);
22568 help_echo_pos = -1;
22569
22570 #ifdef HAVE_WINDOW_SYSTEM
22571 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22572 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22573 For example, if a block cursor is over a tab, it will be drawn as
22574 wide as that tab on the display. */);
22575 x_stretch_cursor_p = 0;
22576 #endif
22577
22578 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22579 doc: /* *Non-nil means highlight trailing whitespace.
22580 The face used for trailing whitespace is `trailing-whitespace'. */);
22581 Vshow_trailing_whitespace = Qnil;
22582
22583 DEFVAR_LISP ("show-nonbreak-escape", &Vshow_nonbreak_escape,
22584 doc: /* *Non-nil means display escape character before non-break space and hyphen. */);
22585 Vshow_nonbreak_escape = Qt;
22586
22587 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22588 doc: /* *The pointer shape to show in void text areas.
22589 Nil means to show the text pointer. Other options are `arrow', `text',
22590 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22591 Vvoid_text_area_pointer = Qarrow;
22592
22593 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22594 doc: /* Non-nil means don't actually do any redisplay.
22595 This is used for internal purposes. */);
22596 Vinhibit_redisplay = Qnil;
22597
22598 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22599 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22600 Vglobal_mode_string = Qnil;
22601
22602 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22603 doc: /* Marker for where to display an arrow on top of the buffer text.
22604 This must be the beginning of a line in order to work.
22605 See also `overlay-arrow-string'. */);
22606 Voverlay_arrow_position = Qnil;
22607
22608 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22609 doc: /* String to display as an arrow in non-window frames.
22610 See also `overlay-arrow-position'. */);
22611 Voverlay_arrow_string = Qnil;
22612
22613 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22614 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22615 The symbols on this list are examined during redisplay to determine
22616 where to display overlay arrows. */);
22617 Voverlay_arrow_variable_list
22618 = Fcons (intern ("overlay-arrow-position"), Qnil);
22619
22620 DEFVAR_INT ("scroll-step", &scroll_step,
22621 doc: /* *The number of lines to try scrolling a window by when point moves out.
22622 If that fails to bring point back on frame, point is centered instead.
22623 If this is zero, point is always centered after it moves off frame.
22624 If you want scrolling to always be a line at a time, you should set
22625 `scroll-conservatively' to a large value rather than set this to 1. */);
22626
22627 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22628 doc: /* *Scroll up to this many lines, to bring point back on screen.
22629 A value of zero means to scroll the text to center point vertically
22630 in the window. */);
22631 scroll_conservatively = 0;
22632
22633 DEFVAR_INT ("scroll-margin", &scroll_margin,
22634 doc: /* *Number of lines of margin at the top and bottom of a window.
22635 Recenter the window whenever point gets within this many lines
22636 of the top or bottom of the window. */);
22637 scroll_margin = 0;
22638
22639 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22640 doc: /* Pixels per inch on current display.
22641 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22642 Vdisplay_pixels_per_inch = make_float (72.0);
22643
22644 #if GLYPH_DEBUG
22645 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22646 #endif
22647
22648 DEFVAR_BOOL ("truncate-partial-width-windows",
22649 &truncate_partial_width_windows,
22650 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22651 truncate_partial_width_windows = 1;
22652
22653 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22654 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22655 Any other value means to use the appropriate face, `mode-line',
22656 `header-line', or `menu' respectively. */);
22657 mode_line_inverse_video = 1;
22658
22659 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22660 doc: /* *Maximum buffer size for which line number should be displayed.
22661 If the buffer is bigger than this, the line number does not appear
22662 in the mode line. A value of nil means no limit. */);
22663 Vline_number_display_limit = Qnil;
22664
22665 DEFVAR_INT ("line-number-display-limit-width",
22666 &line_number_display_limit_width,
22667 doc: /* *Maximum line width (in characters) for line number display.
22668 If the average length of the lines near point is bigger than this, then the
22669 line number may be omitted from the mode line. */);
22670 line_number_display_limit_width = 200;
22671
22672 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22673 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22674 highlight_nonselected_windows = 0;
22675
22676 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22677 doc: /* Non-nil if more than one frame is visible on this display.
22678 Minibuffer-only frames don't count, but iconified frames do.
22679 This variable is not guaranteed to be accurate except while processing
22680 `frame-title-format' and `icon-title-format'. */);
22681
22682 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22683 doc: /* Template for displaying the title bar of visible frames.
22684 \(Assuming the window manager supports this feature.)
22685 This variable has the same structure as `mode-line-format' (which see),
22686 and is used only on frames for which no explicit name has been set
22687 \(see `modify-frame-parameters'). */);
22688
22689 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22690 doc: /* Template for displaying the title bar of an iconified frame.
22691 \(Assuming the window manager supports this feature.)
22692 This variable has the same structure as `mode-line-format' (which see),
22693 and is used only on frames for which no explicit name has been set
22694 \(see `modify-frame-parameters'). */);
22695 Vicon_title_format
22696 = Vframe_title_format
22697 = Fcons (intern ("multiple-frames"),
22698 Fcons (build_string ("%b"),
22699 Fcons (Fcons (empty_string,
22700 Fcons (intern ("invocation-name"),
22701 Fcons (build_string ("@"),
22702 Fcons (intern ("system-name"),
22703 Qnil)))),
22704 Qnil)));
22705
22706 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22707 doc: /* Maximum number of lines to keep in the message log buffer.
22708 If nil, disable message logging. If t, log messages but don't truncate
22709 the buffer when it becomes large. */);
22710 Vmessage_log_max = make_number (50);
22711
22712 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22713 doc: /* Functions called before redisplay, if window sizes have changed.
22714 The value should be a list of functions that take one argument.
22715 Just before redisplay, for each frame, if any of its windows have changed
22716 size since the last redisplay, or have been split or deleted,
22717 all the functions in the list are called, with the frame as argument. */);
22718 Vwindow_size_change_functions = Qnil;
22719
22720 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22721 doc: /* List of functions to call before redisplaying a window with scrolling.
22722 Each function is called with two arguments, the window
22723 and its new display-start position. Note that the value of `window-end'
22724 is not valid when these functions are called. */);
22725 Vwindow_scroll_functions = Qnil;
22726
22727 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22728 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22729 mouse_autoselect_window = 0;
22730
22731 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22732 doc: /* *Non-nil means automatically resize tool-bars.
22733 This increases a tool-bar's height if not all tool-bar items are visible.
22734 It decreases a tool-bar's height when it would display blank lines
22735 otherwise. */);
22736 auto_resize_tool_bars_p = 1;
22737
22738 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22739 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22740 auto_raise_tool_bar_buttons_p = 1;
22741
22742 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
22743 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
22744 make_cursor_line_fully_visible_p = 1;
22745
22746 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22747 doc: /* *Margin around tool-bar buttons in pixels.
22748 If an integer, use that for both horizontal and vertical margins.
22749 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22750 HORZ specifying the horizontal margin, and VERT specifying the
22751 vertical margin. */);
22752 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22753
22754 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22755 doc: /* *Relief thickness of tool-bar buttons. */);
22756 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22757
22758 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22759 doc: /* List of functions to call to fontify regions of text.
22760 Each function is called with one argument POS. Functions must
22761 fontify a region starting at POS in the current buffer, and give
22762 fontified regions the property `fontified'. */);
22763 Vfontification_functions = Qnil;
22764 Fmake_variable_buffer_local (Qfontification_functions);
22765
22766 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22767 &unibyte_display_via_language_environment,
22768 doc: /* *Non-nil means display unibyte text according to language environment.
22769 Specifically this means that unibyte non-ASCII characters
22770 are displayed by converting them to the equivalent multibyte characters
22771 according to the current language environment. As a result, they are
22772 displayed according to the current fontset. */);
22773 unibyte_display_via_language_environment = 0;
22774
22775 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22776 doc: /* *Maximum height for resizing mini-windows.
22777 If a float, it specifies a fraction of the mini-window frame's height.
22778 If an integer, it specifies a number of lines. */);
22779 Vmax_mini_window_height = make_float (0.25);
22780
22781 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22782 doc: /* *How to resize mini-windows.
22783 A value of nil means don't automatically resize mini-windows.
22784 A value of t means resize them to fit the text displayed in them.
22785 A value of `grow-only', the default, means let mini-windows grow
22786 only, until their display becomes empty, at which point the windows
22787 go back to their normal size. */);
22788 Vresize_mini_windows = Qgrow_only;
22789
22790 DEFVAR_LISP ("cursor-in-non-selected-windows",
22791 &Vcursor_in_non_selected_windows,
22792 doc: /* *Cursor type to display in non-selected windows.
22793 t means to use hollow box cursor. See `cursor-type' for other values. */);
22794 Vcursor_in_non_selected_windows = Qt;
22795
22796 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22797 doc: /* Alist specifying how to blink the cursor off.
22798 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22799 `cursor-type' frame-parameter or variable equals ON-STATE,
22800 comparing using `equal', Emacs uses OFF-STATE to specify
22801 how to blink it off. */);
22802 Vblink_cursor_alist = Qnil;
22803
22804 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22805 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22806 automatic_hscrolling_p = 1;
22807
22808 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22809 doc: /* *How many columns away from the window edge point is allowed to get
22810 before automatic hscrolling will horizontally scroll the window. */);
22811 hscroll_margin = 5;
22812
22813 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22814 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22815 When point is less than `automatic-hscroll-margin' columns from the window
22816 edge, automatic hscrolling will scroll the window by the amount of columns
22817 determined by this variable. If its value is a positive integer, scroll that
22818 many columns. If it's a positive floating-point number, it specifies the
22819 fraction of the window's width to scroll. If it's nil or zero, point will be
22820 centered horizontally after the scroll. Any other value, including negative
22821 numbers, are treated as if the value were zero.
22822
22823 Automatic hscrolling always moves point outside the scroll margin, so if
22824 point was more than scroll step columns inside the margin, the window will
22825 scroll more than the value given by the scroll step.
22826
22827 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22828 and `scroll-right' overrides this variable's effect. */);
22829 Vhscroll_step = make_number (0);
22830
22831 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22832 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22833 Bind this around calls to `message' to let it take effect. */);
22834 message_truncate_lines = 0;
22835
22836 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22837 doc: /* Normal hook run to update the menu bar definitions.
22838 Redisplay runs this hook before it redisplays the menu bar.
22839 This is used to update submenus such as Buffers,
22840 whose contents depend on various data. */);
22841 Vmenu_bar_update_hook = Qnil;
22842
22843 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22844 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22845 inhibit_menubar_update = 0;
22846
22847 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22848 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22849 inhibit_eval_during_redisplay = 0;
22850
22851 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22852 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22853 inhibit_free_realized_faces = 0;
22854
22855 #if GLYPH_DEBUG
22856 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22857 doc: /* Inhibit try_window_id display optimization. */);
22858 inhibit_try_window_id = 0;
22859
22860 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22861 doc: /* Inhibit try_window_reusing display optimization. */);
22862 inhibit_try_window_reusing = 0;
22863
22864 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22865 doc: /* Inhibit try_cursor_movement display optimization. */);
22866 inhibit_try_cursor_movement = 0;
22867 #endif /* GLYPH_DEBUG */
22868 }
22869
22870
22871 /* Initialize this module when Emacs starts. */
22872
22873 void
22874 init_xdisp ()
22875 {
22876 Lisp_Object root_window;
22877 struct window *mini_w;
22878
22879 current_header_line_height = current_mode_line_height = -1;
22880
22881 CHARPOS (this_line_start_pos) = 0;
22882
22883 mini_w = XWINDOW (minibuf_window);
22884 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22885
22886 if (!noninteractive)
22887 {
22888 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22889 int i;
22890
22891 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22892 set_window_height (root_window,
22893 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22894 0);
22895 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22896 set_window_height (minibuf_window, 1, 0);
22897
22898 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22899 mini_w->total_cols = make_number (FRAME_COLS (f));
22900
22901 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22902 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22903 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22904
22905 /* The default ellipsis glyphs `...'. */
22906 for (i = 0; i < 3; ++i)
22907 default_invis_vector[i] = make_number ('.');
22908 }
22909
22910 {
22911 /* Allocate the buffer for frame titles.
22912 Also used for `format-mode-line'. */
22913 int size = 100;
22914 frame_title_buf = (char *) xmalloc (size);
22915 frame_title_buf_end = frame_title_buf + size;
22916 frame_title_ptr = NULL;
22917 }
22918
22919 help_echo_showing_p = 0;
22920 }
22921
22922
22923 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22924 (do not change this comment) */