]> code.delx.au - gnu-emacs/blob - src/xdisp.c
Merged in changes from CVS trunk. Plus added lisp/term tweaks.
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995,
3 1997, 1998, 1999, 2000, 2001, 2002, 2003,
4 2004, 2005 Free Software Foundation, Inc.
5
6 This file is part of GNU Emacs.
7
8 GNU Emacs is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
12
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA. */
22
23 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
24
25 Redisplay.
26
27 Emacs separates the task of updating the display from code
28 modifying global state, e.g. buffer text. This way functions
29 operating on buffers don't also have to be concerned with updating
30 the display.
31
32 Updating the display is triggered by the Lisp interpreter when it
33 decides it's time to do it. This is done either automatically for
34 you as part of the interpreter's command loop or as the result of
35 calling Lisp functions like `sit-for'. The C function `redisplay'
36 in xdisp.c is the only entry into the inner redisplay code. (Or,
37 let's say almost---see the description of direct update
38 operations, below.)
39
40 The following diagram shows how redisplay code is invoked. As you
41 can see, Lisp calls redisplay and vice versa. Under window systems
42 like X, some portions of the redisplay code are also called
43 asynchronously during mouse movement or expose events. It is very
44 important that these code parts do NOT use the C library (malloc,
45 free) because many C libraries under Unix are not reentrant. They
46 may also NOT call functions of the Lisp interpreter which could
47 change the interpreter's state. If you don't follow these rules,
48 you will encounter bugs which are very hard to explain.
49
50 (Direct functions, see below)
51 direct_output_for_insert,
52 direct_forward_char (dispnew.c)
53 +---------------------------------+
54 | |
55 | V
56 +--------------+ redisplay +----------------+
57 | Lisp machine |---------------->| Redisplay code |<--+
58 +--------------+ (xdisp.c) +----------------+ |
59 ^ | |
60 +----------------------------------+ |
61 Don't use this path when called |
62 asynchronously! |
63 |
64 expose_window (asynchronous) |
65 |
66 X expose events -----+
67
68 What does redisplay do? Obviously, it has to figure out somehow what
69 has been changed since the last time the display has been updated,
70 and to make these changes visible. Preferably it would do that in
71 a moderately intelligent way, i.e. fast.
72
73 Changes in buffer text can be deduced from window and buffer
74 structures, and from some global variables like `beg_unchanged' and
75 `end_unchanged'. The contents of the display are additionally
76 recorded in a `glyph matrix', a two-dimensional matrix of glyph
77 structures. Each row in such a matrix corresponds to a line on the
78 display, and each glyph in a row corresponds to a column displaying
79 a character, an image, or what else. This matrix is called the
80 `current glyph matrix' or `current matrix' in redisplay
81 terminology.
82
83 For buffer parts that have been changed since the last update, a
84 second glyph matrix is constructed, the so called `desired glyph
85 matrix' or short `desired matrix'. Current and desired matrix are
86 then compared to find a cheap way to update the display, e.g. by
87 reusing part of the display by scrolling lines.
88
89
90 Direct operations.
91
92 You will find a lot of redisplay optimizations when you start
93 looking at the innards of redisplay. The overall goal of all these
94 optimizations is to make redisplay fast because it is done
95 frequently.
96
97 Two optimizations are not found in xdisp.c. These are the direct
98 operations mentioned above. As the name suggests they follow a
99 different principle than the rest of redisplay. Instead of
100 building a desired matrix and then comparing it with the current
101 display, they perform their actions directly on the display and on
102 the current matrix.
103
104 One direct operation updates the display after one character has
105 been entered. The other one moves the cursor by one position
106 forward or backward. You find these functions under the names
107 `direct_output_for_insert' and `direct_output_forward_char' in
108 dispnew.c.
109
110
111 Desired matrices.
112
113 Desired matrices are always built per Emacs window. The function
114 `display_line' is the central function to look at if you are
115 interested. It constructs one row in a desired matrix given an
116 iterator structure containing both a buffer position and a
117 description of the environment in which the text is to be
118 displayed. But this is too early, read on.
119
120 Characters and pixmaps displayed for a range of buffer text depend
121 on various settings of buffers and windows, on overlays and text
122 properties, on display tables, on selective display. The good news
123 is that all this hairy stuff is hidden behind a small set of
124 interface functions taking an iterator structure (struct it)
125 argument.
126
127 Iteration over things to be displayed is then simple. It is
128 started by initializing an iterator with a call to init_iterator.
129 Calls to get_next_display_element fill the iterator structure with
130 relevant information about the next thing to display. Calls to
131 set_iterator_to_next move the iterator to the next thing.
132
133 Besides this, an iterator also contains information about the
134 display environment in which glyphs for display elements are to be
135 produced. It has fields for the width and height of the display,
136 the information whether long lines are truncated or continued, a
137 current X and Y position, and lots of other stuff you can better
138 see in dispextern.h.
139
140 Glyphs in a desired matrix are normally constructed in a loop
141 calling get_next_display_element and then produce_glyphs. The call
142 to produce_glyphs will fill the iterator structure with pixel
143 information about the element being displayed and at the same time
144 produce glyphs for it. If the display element fits on the line
145 being displayed, set_iterator_to_next is called next, otherwise the
146 glyphs produced are discarded.
147
148
149 Frame matrices.
150
151 That just couldn't be all, could it? What about terminal types not
152 supporting operations on sub-windows of the screen? To update the
153 display on such a terminal, window-based glyph matrices are not
154 well suited. To be able to reuse part of the display (scrolling
155 lines up and down), we must instead have a view of the whole
156 screen. This is what `frame matrices' are for. They are a trick.
157
158 Frames on terminals like above have a glyph pool. Windows on such
159 a frame sub-allocate their glyph memory from their frame's glyph
160 pool. The frame itself is given its own glyph matrices. By
161 coincidence---or maybe something else---rows in window glyph
162 matrices are slices of corresponding rows in frame matrices. Thus
163 writing to window matrices implicitly updates a frame matrix which
164 provides us with the view of the whole screen that we originally
165 wanted to have without having to move many bytes around. To be
166 honest, there is a little bit more done, but not much more. If you
167 plan to extend that code, take a look at dispnew.c. The function
168 build_frame_matrix is a good starting point. */
169
170 #include <config.h>
171 #include <stdio.h>
172
173 #include "lisp.h"
174 #include "keyboard.h"
175 #include "frame.h"
176 #include "window.h"
177 #include "termchar.h"
178 #include "dispextern.h"
179 #include "buffer.h"
180 #include "charset.h"
181 #include "indent.h"
182 #include "commands.h"
183 #include "keymap.h"
184 #include "macros.h"
185 #include "disptab.h"
186 #include "termhooks.h"
187 #include "intervals.h"
188 #include "coding.h"
189 #include "process.h"
190 #include "region-cache.h"
191 #include "fontset.h"
192 #include "blockinput.h"
193
194 #ifdef HAVE_X_WINDOWS
195 #include "xterm.h"
196 #endif
197 #ifdef WINDOWSNT
198 #include "w32term.h"
199 #endif
200 #ifdef MAC_OS
201 #include "macterm.h"
202 #endif
203
204 #ifndef FRAME_X_OUTPUT
205 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
206 #endif
207
208 #define INFINITY 10000000
209
210 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
211 || defined (USE_GTK)
212 extern void set_frame_menubar P_ ((struct frame *f, int, int));
213 extern int pending_menu_activation;
214 #endif
215
216 extern int interrupt_input;
217 extern int command_loop_level;
218
219 extern Lisp_Object do_mouse_tracking;
220
221 extern int minibuffer_auto_raise;
222 extern Lisp_Object Vminibuffer_list;
223
224 extern Lisp_Object Qface;
225 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
226
227 extern Lisp_Object Voverriding_local_map;
228 extern Lisp_Object Voverriding_local_map_menu_flag;
229 extern Lisp_Object Qmenu_item;
230 extern Lisp_Object Qwhen;
231 extern Lisp_Object Qhelp_echo;
232
233 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
234 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
235 Lisp_Object Qredisplay_end_trigger_functions, Vredisplay_end_trigger_functions;
236 Lisp_Object Qinhibit_point_motion_hooks;
237 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
238 Lisp_Object Qfontified;
239 Lisp_Object Qgrow_only;
240 Lisp_Object Qinhibit_eval_during_redisplay;
241 Lisp_Object Qbuffer_position, Qposition, Qobject;
242
243 /* Cursor shapes */
244 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
245
246 /* Pointer shapes */
247 Lisp_Object Qarrow, Qhand, Qtext;
248
249 Lisp_Object Qrisky_local_variable;
250
251 /* Holds the list (error). */
252 Lisp_Object list_of_error;
253
254 /* Functions called to fontify regions of text. */
255
256 Lisp_Object Vfontification_functions;
257 Lisp_Object Qfontification_functions;
258
259 /* Non-zero means automatically select any window when the mouse
260 cursor moves into it. */
261 int mouse_autoselect_window;
262
263 /* Non-zero means draw tool bar buttons raised when the mouse moves
264 over them. */
265
266 int auto_raise_tool_bar_buttons_p;
267
268 /* Non-zero means to reposition window if cursor line is only partially visible. */
269
270 int make_cursor_line_fully_visible_p;
271
272 /* Margin around tool bar buttons in pixels. */
273
274 Lisp_Object Vtool_bar_button_margin;
275
276 /* Thickness of shadow to draw around tool bar buttons. */
277
278 EMACS_INT tool_bar_button_relief;
279
280 /* Non-zero means automatically resize tool-bars so that all tool-bar
281 items are visible, and no blank lines remain. */
282
283 int auto_resize_tool_bars_p;
284
285 /* Non-zero means draw block and hollow cursor as wide as the glyph
286 under it. For example, if a block cursor is over a tab, it will be
287 drawn as wide as that tab on the display. */
288
289 int x_stretch_cursor_p;
290
291 /* Non-nil means don't actually do any redisplay. */
292
293 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
294
295 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
296
297 int inhibit_eval_during_redisplay;
298
299 /* Names of text properties relevant for redisplay. */
300
301 Lisp_Object Qdisplay;
302 extern Lisp_Object Qface, Qinvisible, Qwidth;
303
304 /* Symbols used in text property values. */
305
306 Lisp_Object Vdisplay_pixels_per_inch;
307 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
308 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
309 Lisp_Object Qslice;
310 Lisp_Object Qcenter;
311 Lisp_Object Qmargin, Qpointer;
312 Lisp_Object Qline_height;
313 extern Lisp_Object Qheight;
314 extern Lisp_Object QCwidth, QCheight, QCascent;
315 extern Lisp_Object Qscroll_bar;
316 extern Lisp_Object Qcursor;
317
318 /* Non-nil means highlight trailing whitespace. */
319
320 Lisp_Object Vshow_trailing_whitespace;
321
322 /* Non-nil means escape non-break space and hyphens. */
323
324 Lisp_Object Vnobreak_char_display;
325
326 #ifdef HAVE_WINDOW_SYSTEM
327 extern Lisp_Object Voverflow_newline_into_fringe;
328
329 /* Test if overflow newline into fringe. Called with iterator IT
330 at or past right window margin, and with IT->current_x set. */
331
332 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
333 (!NILP (Voverflow_newline_into_fringe) \
334 && FRAME_WINDOW_P (it->f) \
335 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
336 && it->current_x == it->last_visible_x)
337
338 #endif /* HAVE_WINDOW_SYSTEM */
339
340 /* Non-nil means show the text cursor in void text areas
341 i.e. in blank areas after eol and eob. This used to be
342 the default in 21.3. */
343
344 Lisp_Object Vvoid_text_area_pointer;
345
346 /* Name of the face used to highlight trailing whitespace. */
347
348 Lisp_Object Qtrailing_whitespace;
349
350 /* Name and number of the face used to highlight escape glyphs. */
351
352 Lisp_Object Qescape_glyph;
353
354 /* Name and number of the face used to highlight non-breaking spaces. */
355
356 Lisp_Object Qnobreak_space;
357
358 /* The symbol `image' which is the car of the lists used to represent
359 images in Lisp. */
360
361 Lisp_Object Qimage;
362
363 /* The image map types. */
364 Lisp_Object QCmap, QCpointer;
365 Lisp_Object Qrect, Qcircle, Qpoly;
366
367 /* Non-zero means print newline to stdout before next mini-buffer
368 message. */
369
370 int noninteractive_need_newline;
371
372 /* Non-zero means print newline to message log before next message. */
373
374 static int message_log_need_newline;
375
376 /* Three markers that message_dolog uses.
377 It could allocate them itself, but that causes trouble
378 in handling memory-full errors. */
379 static Lisp_Object message_dolog_marker1;
380 static Lisp_Object message_dolog_marker2;
381 static Lisp_Object message_dolog_marker3;
382 \f
383 /* The buffer position of the first character appearing entirely or
384 partially on the line of the selected window which contains the
385 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
386 redisplay optimization in redisplay_internal. */
387
388 static struct text_pos this_line_start_pos;
389
390 /* Number of characters past the end of the line above, including the
391 terminating newline. */
392
393 static struct text_pos this_line_end_pos;
394
395 /* The vertical positions and the height of this line. */
396
397 static int this_line_vpos;
398 static int this_line_y;
399 static int this_line_pixel_height;
400
401 /* X position at which this display line starts. Usually zero;
402 negative if first character is partially visible. */
403
404 static int this_line_start_x;
405
406 /* Buffer that this_line_.* variables are referring to. */
407
408 static struct buffer *this_line_buffer;
409
410 /* Nonzero means truncate lines in all windows less wide than the
411 frame. */
412
413 int truncate_partial_width_windows;
414
415 /* A flag to control how to display unibyte 8-bit character. */
416
417 int unibyte_display_via_language_environment;
418
419 /* Nonzero means we have more than one non-mini-buffer-only frame.
420 Not guaranteed to be accurate except while parsing
421 frame-title-format. */
422
423 int multiple_frames;
424
425 Lisp_Object Vglobal_mode_string;
426
427
428 /* List of variables (symbols) which hold markers for overlay arrows.
429 The symbols on this list are examined during redisplay to determine
430 where to display overlay arrows. */
431
432 Lisp_Object Voverlay_arrow_variable_list;
433
434 /* Marker for where to display an arrow on top of the buffer text. */
435
436 Lisp_Object Voverlay_arrow_position;
437
438 /* String to display for the arrow. Only used on terminal frames. */
439
440 Lisp_Object Voverlay_arrow_string;
441
442 /* Values of those variables at last redisplay are stored as
443 properties on `overlay-arrow-position' symbol. However, if
444 Voverlay_arrow_position is a marker, last-arrow-position is its
445 numerical position. */
446
447 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
448
449 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
450 properties on a symbol in overlay-arrow-variable-list. */
451
452 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
453
454 /* Like mode-line-format, but for the title bar on a visible frame. */
455
456 Lisp_Object Vframe_title_format;
457
458 /* Like mode-line-format, but for the title bar on an iconified frame. */
459
460 Lisp_Object Vicon_title_format;
461
462 /* List of functions to call when a window's size changes. These
463 functions get one arg, a frame on which one or more windows' sizes
464 have changed. */
465
466 static Lisp_Object Vwindow_size_change_functions;
467
468 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
469
470 /* Nonzero if an overlay arrow has been displayed in this window. */
471
472 static int overlay_arrow_seen;
473
474 /* Nonzero means highlight the region even in nonselected windows. */
475
476 int highlight_nonselected_windows;
477
478 /* If cursor motion alone moves point off frame, try scrolling this
479 many lines up or down if that will bring it back. */
480
481 static EMACS_INT scroll_step;
482
483 /* Nonzero means scroll just far enough to bring point back on the
484 screen, when appropriate. */
485
486 static EMACS_INT scroll_conservatively;
487
488 /* Recenter the window whenever point gets within this many lines of
489 the top or bottom of the window. This value is translated into a
490 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
491 that there is really a fixed pixel height scroll margin. */
492
493 EMACS_INT scroll_margin;
494
495 /* Number of windows showing the buffer of the selected window (or
496 another buffer with the same base buffer). keyboard.c refers to
497 this. */
498
499 int buffer_shared;
500
501 /* Vector containing glyphs for an ellipsis `...'. */
502
503 static Lisp_Object default_invis_vector[3];
504
505 /* Zero means display the mode-line/header-line/menu-bar in the default face
506 (this slightly odd definition is for compatibility with previous versions
507 of emacs), non-zero means display them using their respective faces.
508
509 This variable is deprecated. */
510
511 int mode_line_inverse_video;
512
513 /* Prompt to display in front of the mini-buffer contents. */
514
515 Lisp_Object minibuf_prompt;
516
517 /* Width of current mini-buffer prompt. Only set after display_line
518 of the line that contains the prompt. */
519
520 int minibuf_prompt_width;
521
522 /* This is the window where the echo area message was displayed. It
523 is always a mini-buffer window, but it may not be the same window
524 currently active as a mini-buffer. */
525
526 Lisp_Object echo_area_window;
527
528 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
529 pushes the current message and the value of
530 message_enable_multibyte on the stack, the function restore_message
531 pops the stack and displays MESSAGE again. */
532
533 Lisp_Object Vmessage_stack;
534
535 /* Nonzero means multibyte characters were enabled when the echo area
536 message was specified. */
537
538 int message_enable_multibyte;
539
540 /* Nonzero if we should redraw the mode lines on the next redisplay. */
541
542 int update_mode_lines;
543
544 /* Nonzero if window sizes or contents have changed since last
545 redisplay that finished. */
546
547 int windows_or_buffers_changed;
548
549 /* Nonzero means a frame's cursor type has been changed. */
550
551 int cursor_type_changed;
552
553 /* Nonzero after display_mode_line if %l was used and it displayed a
554 line number. */
555
556 int line_number_displayed;
557
558 /* Maximum buffer size for which to display line numbers. */
559
560 Lisp_Object Vline_number_display_limit;
561
562 /* Line width to consider when repositioning for line number display. */
563
564 static EMACS_INT line_number_display_limit_width;
565
566 /* Number of lines to keep in the message log buffer. t means
567 infinite. nil means don't log at all. */
568
569 Lisp_Object Vmessage_log_max;
570
571 /* The name of the *Messages* buffer, a string. */
572
573 static Lisp_Object Vmessages_buffer_name;
574
575 /* Current, index 0, and last displayed echo area message. Either
576 buffers from echo_buffers, or nil to indicate no message. */
577
578 Lisp_Object echo_area_buffer[2];
579
580 /* The buffers referenced from echo_area_buffer. */
581
582 static Lisp_Object echo_buffer[2];
583
584 /* A vector saved used in with_area_buffer to reduce consing. */
585
586 static Lisp_Object Vwith_echo_area_save_vector;
587
588 /* Non-zero means display_echo_area should display the last echo area
589 message again. Set by redisplay_preserve_echo_area. */
590
591 static int display_last_displayed_message_p;
592
593 /* Nonzero if echo area is being used by print; zero if being used by
594 message. */
595
596 int message_buf_print;
597
598 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
599
600 Lisp_Object Qinhibit_menubar_update;
601 int inhibit_menubar_update;
602
603 /* Maximum height for resizing mini-windows. Either a float
604 specifying a fraction of the available height, or an integer
605 specifying a number of lines. */
606
607 Lisp_Object Vmax_mini_window_height;
608
609 /* Non-zero means messages should be displayed with truncated
610 lines instead of being continued. */
611
612 int message_truncate_lines;
613 Lisp_Object Qmessage_truncate_lines;
614
615 /* Set to 1 in clear_message to make redisplay_internal aware
616 of an emptied echo area. */
617
618 static int message_cleared_p;
619
620 /* How to blink the default frame cursor off. */
621 Lisp_Object Vblink_cursor_alist;
622
623 /* A scratch glyph row with contents used for generating truncation
624 glyphs. Also used in direct_output_for_insert. */
625
626 #define MAX_SCRATCH_GLYPHS 100
627 struct glyph_row scratch_glyph_row;
628 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
629
630 /* Ascent and height of the last line processed by move_it_to. */
631
632 static int last_max_ascent, last_height;
633
634 /* Non-zero if there's a help-echo in the echo area. */
635
636 int help_echo_showing_p;
637
638 /* If >= 0, computed, exact values of mode-line and header-line height
639 to use in the macros CURRENT_MODE_LINE_HEIGHT and
640 CURRENT_HEADER_LINE_HEIGHT. */
641
642 int current_mode_line_height, current_header_line_height;
643
644 /* The maximum distance to look ahead for text properties. Values
645 that are too small let us call compute_char_face and similar
646 functions too often which is expensive. Values that are too large
647 let us call compute_char_face and alike too often because we
648 might not be interested in text properties that far away. */
649
650 #define TEXT_PROP_DISTANCE_LIMIT 100
651
652 #if GLYPH_DEBUG
653
654 /* Variables to turn off display optimizations from Lisp. */
655
656 int inhibit_try_window_id, inhibit_try_window_reusing;
657 int inhibit_try_cursor_movement;
658
659 /* Non-zero means print traces of redisplay if compiled with
660 GLYPH_DEBUG != 0. */
661
662 int trace_redisplay_p;
663
664 #endif /* GLYPH_DEBUG */
665
666 #ifdef DEBUG_TRACE_MOVE
667 /* Non-zero means trace with TRACE_MOVE to stderr. */
668 int trace_move;
669
670 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
671 #else
672 #define TRACE_MOVE(x) (void) 0
673 #endif
674
675 /* Non-zero means automatically scroll windows horizontally to make
676 point visible. */
677
678 int automatic_hscrolling_p;
679
680 /* How close to the margin can point get before the window is scrolled
681 horizontally. */
682 EMACS_INT hscroll_margin;
683
684 /* How much to scroll horizontally when point is inside the above margin. */
685 Lisp_Object Vhscroll_step;
686
687 /* The variable `resize-mini-windows'. If nil, don't resize
688 mini-windows. If t, always resize them to fit the text they
689 display. If `grow-only', let mini-windows grow only until they
690 become empty. */
691
692 Lisp_Object Vresize_mini_windows;
693
694 /* Buffer being redisplayed -- for redisplay_window_error. */
695
696 struct buffer *displayed_buffer;
697
698 /* Value returned from text property handlers (see below). */
699
700 enum prop_handled
701 {
702 HANDLED_NORMALLY,
703 HANDLED_RECOMPUTE_PROPS,
704 HANDLED_OVERLAY_STRING_CONSUMED,
705 HANDLED_RETURN
706 };
707
708 /* A description of text properties that redisplay is interested
709 in. */
710
711 struct props
712 {
713 /* The name of the property. */
714 Lisp_Object *name;
715
716 /* A unique index for the property. */
717 enum prop_idx idx;
718
719 /* A handler function called to set up iterator IT from the property
720 at IT's current position. Value is used to steer handle_stop. */
721 enum prop_handled (*handler) P_ ((struct it *it));
722 };
723
724 static enum prop_handled handle_face_prop P_ ((struct it *));
725 static enum prop_handled handle_invisible_prop P_ ((struct it *));
726 static enum prop_handled handle_display_prop P_ ((struct it *));
727 static enum prop_handled handle_composition_prop P_ ((struct it *));
728 static enum prop_handled handle_overlay_change P_ ((struct it *));
729 static enum prop_handled handle_fontified_prop P_ ((struct it *));
730
731 /* Properties handled by iterators. */
732
733 static struct props it_props[] =
734 {
735 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
736 /* Handle `face' before `display' because some sub-properties of
737 `display' need to know the face. */
738 {&Qface, FACE_PROP_IDX, handle_face_prop},
739 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
740 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
741 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
742 {NULL, 0, NULL}
743 };
744
745 /* Value is the position described by X. If X is a marker, value is
746 the marker_position of X. Otherwise, value is X. */
747
748 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
749
750 /* Enumeration returned by some move_it_.* functions internally. */
751
752 enum move_it_result
753 {
754 /* Not used. Undefined value. */
755 MOVE_UNDEFINED,
756
757 /* Move ended at the requested buffer position or ZV. */
758 MOVE_POS_MATCH_OR_ZV,
759
760 /* Move ended at the requested X pixel position. */
761 MOVE_X_REACHED,
762
763 /* Move within a line ended at the end of a line that must be
764 continued. */
765 MOVE_LINE_CONTINUED,
766
767 /* Move within a line ended at the end of a line that would
768 be displayed truncated. */
769 MOVE_LINE_TRUNCATED,
770
771 /* Move within a line ended at a line end. */
772 MOVE_NEWLINE_OR_CR
773 };
774
775 /* This counter is used to clear the face cache every once in a while
776 in redisplay_internal. It is incremented for each redisplay.
777 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
778 cleared. */
779
780 #define CLEAR_FACE_CACHE_COUNT 500
781 static int clear_face_cache_count;
782
783 /* Similarly for the image cache. */
784
785 #ifdef HAVE_WINDOW_SYSTEM
786 #define CLEAR_IMAGE_CACHE_COUNT 101
787 static int clear_image_cache_count;
788 #endif
789
790 /* Non-zero while redisplay_internal is in progress. */
791
792 int redisplaying_p;
793
794 /* Non-zero means don't free realized faces. Bound while freeing
795 realized faces is dangerous because glyph matrices might still
796 reference them. */
797
798 int inhibit_free_realized_faces;
799 Lisp_Object Qinhibit_free_realized_faces;
800
801 /* If a string, XTread_socket generates an event to display that string.
802 (The display is done in read_char.) */
803
804 Lisp_Object help_echo_string;
805 Lisp_Object help_echo_window;
806 Lisp_Object help_echo_object;
807 int help_echo_pos;
808
809 /* Temporary variable for XTread_socket. */
810
811 Lisp_Object previous_help_echo_string;
812
813 /* Null glyph slice */
814
815 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
816
817 \f
818 /* Function prototypes. */
819
820 static void setup_for_ellipsis P_ ((struct it *, int));
821 static void mark_window_display_accurate_1 P_ ((struct window *, int));
822 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
823 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
824 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
825 static int redisplay_mode_lines P_ ((Lisp_Object, int));
826 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
827
828 #if 0
829 static int invisible_text_between_p P_ ((struct it *, int, int));
830 #endif
831
832 static void pint2str P_ ((char *, int, int));
833 static void pint2hrstr P_ ((char *, int, int));
834 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
835 struct text_pos));
836 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
837 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
838 static void store_mode_line_noprop_char P_ ((char));
839 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
840 static void x_consider_frame_title P_ ((Lisp_Object));
841 static void handle_stop P_ ((struct it *));
842 static int tool_bar_lines_needed P_ ((struct frame *));
843 static int single_display_spec_intangible_p P_ ((Lisp_Object));
844 static void ensure_echo_area_buffers P_ ((void));
845 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
846 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
847 static int with_echo_area_buffer P_ ((struct window *, int,
848 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
849 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
850 static void clear_garbaged_frames P_ ((void));
851 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
852 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
853 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
854 static int display_echo_area P_ ((struct window *));
855 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
856 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
857 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
858 static int string_char_and_length P_ ((const unsigned char *, int, int *));
859 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
860 struct text_pos));
861 static int compute_window_start_on_continuation_line P_ ((struct window *));
862 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
863 static void insert_left_trunc_glyphs P_ ((struct it *));
864 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
865 Lisp_Object));
866 static void extend_face_to_end_of_line P_ ((struct it *));
867 static int append_space_for_newline P_ ((struct it *, int));
868 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
869 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
870 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
871 static int trailing_whitespace_p P_ ((int));
872 static int message_log_check_duplicate P_ ((int, int, int, int));
873 static void push_it P_ ((struct it *));
874 static void pop_it P_ ((struct it *));
875 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
876 static void select_frame_for_redisplay P_ ((Lisp_Object));
877 static void redisplay_internal P_ ((int));
878 static int echo_area_display P_ ((int));
879 static void redisplay_windows P_ ((Lisp_Object));
880 static void redisplay_window P_ ((Lisp_Object, int));
881 static Lisp_Object redisplay_window_error ();
882 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
883 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
884 static void update_menu_bar P_ ((struct frame *, int));
885 static int try_window_reusing_current_matrix P_ ((struct window *));
886 static int try_window_id P_ ((struct window *));
887 static int display_line P_ ((struct it *));
888 static int display_mode_lines P_ ((struct window *));
889 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
890 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
891 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
892 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
893 static void display_menu_bar P_ ((struct window *));
894 static int display_count_lines P_ ((int, int, int, int, int *));
895 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
896 int, int, struct it *, int, int, int, int));
897 static void compute_line_metrics P_ ((struct it *));
898 static void run_redisplay_end_trigger_hook P_ ((struct it *));
899 static int get_overlay_strings P_ ((struct it *, int));
900 static void next_overlay_string P_ ((struct it *));
901 static void reseat P_ ((struct it *, struct text_pos, int));
902 static void reseat_1 P_ ((struct it *, struct text_pos, int));
903 static void back_to_previous_visible_line_start P_ ((struct it *));
904 void reseat_at_previous_visible_line_start P_ ((struct it *));
905 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
906 static int next_element_from_ellipsis P_ ((struct it *));
907 static int next_element_from_display_vector P_ ((struct it *));
908 static int next_element_from_string P_ ((struct it *));
909 static int next_element_from_c_string P_ ((struct it *));
910 static int next_element_from_buffer P_ ((struct it *));
911 static int next_element_from_composition P_ ((struct it *));
912 static int next_element_from_image P_ ((struct it *));
913 static int next_element_from_stretch P_ ((struct it *));
914 static void load_overlay_strings P_ ((struct it *, int));
915 static int init_from_display_pos P_ ((struct it *, struct window *,
916 struct display_pos *));
917 static void reseat_to_string P_ ((struct it *, unsigned char *,
918 Lisp_Object, int, int, int, int));
919 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
920 int, int, int));
921 void move_it_vertically_backward P_ ((struct it *, int));
922 static void init_to_row_start P_ ((struct it *, struct window *,
923 struct glyph_row *));
924 static int init_to_row_end P_ ((struct it *, struct window *,
925 struct glyph_row *));
926 static void back_to_previous_line_start P_ ((struct it *));
927 static int forward_to_next_line_start P_ ((struct it *, int *));
928 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
929 Lisp_Object, int));
930 static struct text_pos string_pos P_ ((int, Lisp_Object));
931 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
932 static int number_of_chars P_ ((unsigned char *, int));
933 static void compute_stop_pos P_ ((struct it *));
934 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
935 Lisp_Object));
936 static int face_before_or_after_it_pos P_ ((struct it *, int));
937 static int next_overlay_change P_ ((int));
938 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
939 Lisp_Object, struct text_pos *,
940 int));
941 static int underlying_face_id P_ ((struct it *));
942 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
943 struct window *));
944
945 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
946 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
947
948 #ifdef HAVE_WINDOW_SYSTEM
949
950 static void update_tool_bar P_ ((struct frame *, int));
951 static void build_desired_tool_bar_string P_ ((struct frame *f));
952 static int redisplay_tool_bar P_ ((struct frame *));
953 static void display_tool_bar_line P_ ((struct it *));
954 static void notice_overwritten_cursor P_ ((struct window *,
955 enum glyph_row_area,
956 int, int, int, int));
957
958
959
960 #endif /* HAVE_WINDOW_SYSTEM */
961
962 \f
963 /***********************************************************************
964 Window display dimensions
965 ***********************************************************************/
966
967 /* Return the bottom boundary y-position for text lines in window W.
968 This is the first y position at which a line cannot start.
969 It is relative to the top of the window.
970
971 This is the height of W minus the height of a mode line, if any. */
972
973 INLINE int
974 window_text_bottom_y (w)
975 struct window *w;
976 {
977 int height = WINDOW_TOTAL_HEIGHT (w);
978
979 if (WINDOW_WANTS_MODELINE_P (w))
980 height -= CURRENT_MODE_LINE_HEIGHT (w);
981 return height;
982 }
983
984 /* Return the pixel width of display area AREA of window W. AREA < 0
985 means return the total width of W, not including fringes to
986 the left and right of the window. */
987
988 INLINE int
989 window_box_width (w, area)
990 struct window *w;
991 int area;
992 {
993 int cols = XFASTINT (w->total_cols);
994 int pixels = 0;
995
996 if (!w->pseudo_window_p)
997 {
998 cols -= WINDOW_SCROLL_BAR_COLS (w);
999
1000 if (area == TEXT_AREA)
1001 {
1002 if (INTEGERP (w->left_margin_cols))
1003 cols -= XFASTINT (w->left_margin_cols);
1004 if (INTEGERP (w->right_margin_cols))
1005 cols -= XFASTINT (w->right_margin_cols);
1006 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1007 }
1008 else if (area == LEFT_MARGIN_AREA)
1009 {
1010 cols = (INTEGERP (w->left_margin_cols)
1011 ? XFASTINT (w->left_margin_cols) : 0);
1012 pixels = 0;
1013 }
1014 else if (area == RIGHT_MARGIN_AREA)
1015 {
1016 cols = (INTEGERP (w->right_margin_cols)
1017 ? XFASTINT (w->right_margin_cols) : 0);
1018 pixels = 0;
1019 }
1020 }
1021
1022 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1023 }
1024
1025
1026 /* Return the pixel height of the display area of window W, not
1027 including mode lines of W, if any. */
1028
1029 INLINE int
1030 window_box_height (w)
1031 struct window *w;
1032 {
1033 struct frame *f = XFRAME (w->frame);
1034 int height = WINDOW_TOTAL_HEIGHT (w);
1035
1036 xassert (height >= 0);
1037
1038 /* Note: the code below that determines the mode-line/header-line
1039 height is essentially the same as that contained in the macro
1040 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1041 the appropriate glyph row has its `mode_line_p' flag set,
1042 and if it doesn't, uses estimate_mode_line_height instead. */
1043
1044 if (WINDOW_WANTS_MODELINE_P (w))
1045 {
1046 struct glyph_row *ml_row
1047 = (w->current_matrix && w->current_matrix->rows
1048 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1049 : 0);
1050 if (ml_row && ml_row->mode_line_p)
1051 height -= ml_row->height;
1052 else
1053 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1054 }
1055
1056 if (WINDOW_WANTS_HEADER_LINE_P (w))
1057 {
1058 struct glyph_row *hl_row
1059 = (w->current_matrix && w->current_matrix->rows
1060 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1061 : 0);
1062 if (hl_row && hl_row->mode_line_p)
1063 height -= hl_row->height;
1064 else
1065 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1066 }
1067
1068 /* With a very small font and a mode-line that's taller than
1069 default, we might end up with a negative height. */
1070 return max (0, height);
1071 }
1072
1073 /* Return the window-relative coordinate of the left edge of display
1074 area AREA of window W. AREA < 0 means return the left edge of the
1075 whole window, to the right of the left fringe of W. */
1076
1077 INLINE int
1078 window_box_left_offset (w, area)
1079 struct window *w;
1080 int area;
1081 {
1082 int x;
1083
1084 if (w->pseudo_window_p)
1085 return 0;
1086
1087 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1088
1089 if (area == TEXT_AREA)
1090 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1091 + window_box_width (w, LEFT_MARGIN_AREA));
1092 else if (area == RIGHT_MARGIN_AREA)
1093 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1094 + window_box_width (w, LEFT_MARGIN_AREA)
1095 + window_box_width (w, TEXT_AREA)
1096 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1097 ? 0
1098 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1099 else if (area == LEFT_MARGIN_AREA
1100 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1101 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1102
1103 return x;
1104 }
1105
1106
1107 /* Return the window-relative coordinate of the right edge of display
1108 area AREA of window W. AREA < 0 means return the left edge of the
1109 whole window, to the left of the right fringe of W. */
1110
1111 INLINE int
1112 window_box_right_offset (w, area)
1113 struct window *w;
1114 int area;
1115 {
1116 return window_box_left_offset (w, area) + window_box_width (w, area);
1117 }
1118
1119 /* Return the frame-relative coordinate of the left edge of display
1120 area AREA of window W. AREA < 0 means return the left edge of the
1121 whole window, to the right of the left fringe of W. */
1122
1123 INLINE int
1124 window_box_left (w, area)
1125 struct window *w;
1126 int area;
1127 {
1128 struct frame *f = XFRAME (w->frame);
1129 int x;
1130
1131 if (w->pseudo_window_p)
1132 return FRAME_INTERNAL_BORDER_WIDTH (f);
1133
1134 x = (WINDOW_LEFT_EDGE_X (w)
1135 + window_box_left_offset (w, area));
1136
1137 return x;
1138 }
1139
1140
1141 /* Return the frame-relative coordinate of the right edge of display
1142 area AREA of window W. AREA < 0 means return the left edge of the
1143 whole window, to the left of the right fringe of W. */
1144
1145 INLINE int
1146 window_box_right (w, area)
1147 struct window *w;
1148 int area;
1149 {
1150 return window_box_left (w, area) + window_box_width (w, area);
1151 }
1152
1153 /* Get the bounding box of the display area AREA of window W, without
1154 mode lines, in frame-relative coordinates. AREA < 0 means the
1155 whole window, not including the left and right fringes of
1156 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1157 coordinates of the upper-left corner of the box. Return in
1158 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1159
1160 INLINE void
1161 window_box (w, area, box_x, box_y, box_width, box_height)
1162 struct window *w;
1163 int area;
1164 int *box_x, *box_y, *box_width, *box_height;
1165 {
1166 if (box_width)
1167 *box_width = window_box_width (w, area);
1168 if (box_height)
1169 *box_height = window_box_height (w);
1170 if (box_x)
1171 *box_x = window_box_left (w, area);
1172 if (box_y)
1173 {
1174 *box_y = WINDOW_TOP_EDGE_Y (w);
1175 if (WINDOW_WANTS_HEADER_LINE_P (w))
1176 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1177 }
1178 }
1179
1180
1181 /* Get the bounding box of the display area AREA of window W, without
1182 mode lines. AREA < 0 means the whole window, not including the
1183 left and right fringe of the window. Return in *TOP_LEFT_X
1184 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1185 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1186 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1187 box. */
1188
1189 INLINE void
1190 window_box_edges (w, area, top_left_x, top_left_y,
1191 bottom_right_x, bottom_right_y)
1192 struct window *w;
1193 int area;
1194 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1195 {
1196 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1197 bottom_right_y);
1198 *bottom_right_x += *top_left_x;
1199 *bottom_right_y += *top_left_y;
1200 }
1201
1202
1203 \f
1204 /***********************************************************************
1205 Utilities
1206 ***********************************************************************/
1207
1208 /* Return the bottom y-position of the line the iterator IT is in.
1209 This can modify IT's settings. */
1210
1211 int
1212 line_bottom_y (it)
1213 struct it *it;
1214 {
1215 int line_height = it->max_ascent + it->max_descent;
1216 int line_top_y = it->current_y;
1217
1218 if (line_height == 0)
1219 {
1220 if (last_height)
1221 line_height = last_height;
1222 else if (IT_CHARPOS (*it) < ZV)
1223 {
1224 move_it_by_lines (it, 1, 1);
1225 line_height = (it->max_ascent || it->max_descent
1226 ? it->max_ascent + it->max_descent
1227 : last_height);
1228 }
1229 else
1230 {
1231 struct glyph_row *row = it->glyph_row;
1232
1233 /* Use the default character height. */
1234 it->glyph_row = NULL;
1235 it->what = IT_CHARACTER;
1236 it->c = ' ';
1237 it->len = 1;
1238 PRODUCE_GLYPHS (it);
1239 line_height = it->ascent + it->descent;
1240 it->glyph_row = row;
1241 }
1242 }
1243
1244 return line_top_y + line_height;
1245 }
1246
1247
1248 /* Return 1 if position CHARPOS is visible in window W.
1249 If visible, set *X and *Y to pixel coordinates of top left corner.
1250 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1251 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1252 and header-lines heights. */
1253
1254 int
1255 pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1256 struct window *w;
1257 int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
1258 {
1259 struct it it;
1260 struct text_pos top;
1261 int visible_p = 0;
1262 struct buffer *old_buffer = NULL;
1263
1264 if (noninteractive)
1265 return visible_p;
1266
1267 if (XBUFFER (w->buffer) != current_buffer)
1268 {
1269 old_buffer = current_buffer;
1270 set_buffer_internal_1 (XBUFFER (w->buffer));
1271 }
1272
1273 SET_TEXT_POS_FROM_MARKER (top, w->start);
1274
1275 /* Compute exact mode line heights, if requested. */
1276 if (exact_mode_line_heights_p)
1277 {
1278 if (WINDOW_WANTS_MODELINE_P (w))
1279 current_mode_line_height
1280 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1281 current_buffer->mode_line_format);
1282
1283 if (WINDOW_WANTS_HEADER_LINE_P (w))
1284 current_header_line_height
1285 = display_mode_line (w, HEADER_LINE_FACE_ID,
1286 current_buffer->header_line_format);
1287 }
1288
1289 start_display (&it, w, top);
1290 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1291 MOVE_TO_POS | MOVE_TO_Y);
1292
1293 /* Note that we may overshoot because of invisible text. */
1294 if (IT_CHARPOS (it) >= charpos)
1295 {
1296 int top_x = it.current_x;
1297 int top_y = it.current_y;
1298 int bottom_y = (last_height = 0, line_bottom_y (&it));
1299 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1300
1301 if (top_y < window_top_y)
1302 visible_p = bottom_y > window_top_y;
1303 else if (top_y < it.last_visible_y)
1304 visible_p = 1;
1305 if (visible_p)
1306 {
1307 *x = top_x;
1308 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1309 *rtop = max (0, window_top_y - top_y);
1310 *rbot = max (0, bottom_y - it.last_visible_y);
1311 }
1312 }
1313 else
1314 {
1315 struct it it2;
1316
1317 it2 = it;
1318 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1319 move_it_by_lines (&it, 1, 0);
1320 if (charpos < IT_CHARPOS (it))
1321 {
1322 visible_p = 1;
1323 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1324 *x = it2.current_x;
1325 *y = it2.current_y + it2.max_ascent - it2.ascent;
1326 *rtop = max (0, -it2.current_y);
1327 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1328 - it.last_visible_y));
1329 }
1330 }
1331
1332 if (old_buffer)
1333 set_buffer_internal_1 (old_buffer);
1334
1335 current_header_line_height = current_mode_line_height = -1;
1336
1337 if (visible_p && XFASTINT (w->hscroll) > 0)
1338 *x -= XFASTINT (w->hscroll);
1339
1340 return visible_p;
1341 }
1342
1343
1344 /* Return the next character from STR which is MAXLEN bytes long.
1345 Return in *LEN the length of the character. This is like
1346 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1347 we find one, we return a `?', but with the length of the invalid
1348 character. */
1349
1350 static INLINE int
1351 string_char_and_length (str, maxlen, len)
1352 const unsigned char *str;
1353 int maxlen, *len;
1354 {
1355 int c;
1356
1357 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1358 if (!CHAR_VALID_P (c, 1))
1359 /* We may not change the length here because other places in Emacs
1360 don't use this function, i.e. they silently accept invalid
1361 characters. */
1362 c = '?';
1363
1364 return c;
1365 }
1366
1367
1368
1369 /* Given a position POS containing a valid character and byte position
1370 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1371
1372 static struct text_pos
1373 string_pos_nchars_ahead (pos, string, nchars)
1374 struct text_pos pos;
1375 Lisp_Object string;
1376 int nchars;
1377 {
1378 xassert (STRINGP (string) && nchars >= 0);
1379
1380 if (STRING_MULTIBYTE (string))
1381 {
1382 int rest = SBYTES (string) - BYTEPOS (pos);
1383 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1384 int len;
1385
1386 while (nchars--)
1387 {
1388 string_char_and_length (p, rest, &len);
1389 p += len, rest -= len;
1390 xassert (rest >= 0);
1391 CHARPOS (pos) += 1;
1392 BYTEPOS (pos) += len;
1393 }
1394 }
1395 else
1396 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1397
1398 return pos;
1399 }
1400
1401
1402 /* Value is the text position, i.e. character and byte position,
1403 for character position CHARPOS in STRING. */
1404
1405 static INLINE struct text_pos
1406 string_pos (charpos, string)
1407 int charpos;
1408 Lisp_Object string;
1409 {
1410 struct text_pos pos;
1411 xassert (STRINGP (string));
1412 xassert (charpos >= 0);
1413 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1414 return pos;
1415 }
1416
1417
1418 /* Value is a text position, i.e. character and byte position, for
1419 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1420 means recognize multibyte characters. */
1421
1422 static struct text_pos
1423 c_string_pos (charpos, s, multibyte_p)
1424 int charpos;
1425 unsigned char *s;
1426 int multibyte_p;
1427 {
1428 struct text_pos pos;
1429
1430 xassert (s != NULL);
1431 xassert (charpos >= 0);
1432
1433 if (multibyte_p)
1434 {
1435 int rest = strlen (s), len;
1436
1437 SET_TEXT_POS (pos, 0, 0);
1438 while (charpos--)
1439 {
1440 string_char_and_length (s, rest, &len);
1441 s += len, rest -= len;
1442 xassert (rest >= 0);
1443 CHARPOS (pos) += 1;
1444 BYTEPOS (pos) += len;
1445 }
1446 }
1447 else
1448 SET_TEXT_POS (pos, charpos, charpos);
1449
1450 return pos;
1451 }
1452
1453
1454 /* Value is the number of characters in C string S. MULTIBYTE_P
1455 non-zero means recognize multibyte characters. */
1456
1457 static int
1458 number_of_chars (s, multibyte_p)
1459 unsigned char *s;
1460 int multibyte_p;
1461 {
1462 int nchars;
1463
1464 if (multibyte_p)
1465 {
1466 int rest = strlen (s), len;
1467 unsigned char *p = (unsigned char *) s;
1468
1469 for (nchars = 0; rest > 0; ++nchars)
1470 {
1471 string_char_and_length (p, rest, &len);
1472 rest -= len, p += len;
1473 }
1474 }
1475 else
1476 nchars = strlen (s);
1477
1478 return nchars;
1479 }
1480
1481
1482 /* Compute byte position NEWPOS->bytepos corresponding to
1483 NEWPOS->charpos. POS is a known position in string STRING.
1484 NEWPOS->charpos must be >= POS.charpos. */
1485
1486 static void
1487 compute_string_pos (newpos, pos, string)
1488 struct text_pos *newpos, pos;
1489 Lisp_Object string;
1490 {
1491 xassert (STRINGP (string));
1492 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1493
1494 if (STRING_MULTIBYTE (string))
1495 *newpos = string_pos_nchars_ahead (pos, string,
1496 CHARPOS (*newpos) - CHARPOS (pos));
1497 else
1498 BYTEPOS (*newpos) = CHARPOS (*newpos);
1499 }
1500
1501 /* EXPORT:
1502 Return an estimation of the pixel height of mode or top lines on
1503 frame F. FACE_ID specifies what line's height to estimate. */
1504
1505 int
1506 estimate_mode_line_height (f, face_id)
1507 struct frame *f;
1508 enum face_id face_id;
1509 {
1510 #ifdef HAVE_WINDOW_SYSTEM
1511 if (FRAME_WINDOW_P (f))
1512 {
1513 int height = FONT_HEIGHT (FRAME_FONT (f));
1514
1515 /* This function is called so early when Emacs starts that the face
1516 cache and mode line face are not yet initialized. */
1517 if (FRAME_FACE_CACHE (f))
1518 {
1519 struct face *face = FACE_FROM_ID (f, face_id);
1520 if (face)
1521 {
1522 if (face->font)
1523 height = FONT_HEIGHT (face->font);
1524 if (face->box_line_width > 0)
1525 height += 2 * face->box_line_width;
1526 }
1527 }
1528
1529 return height;
1530 }
1531 #endif
1532
1533 return 1;
1534 }
1535
1536 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1537 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1538 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1539 not force the value into range. */
1540
1541 void
1542 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1543 FRAME_PTR f;
1544 register int pix_x, pix_y;
1545 int *x, *y;
1546 NativeRectangle *bounds;
1547 int noclip;
1548 {
1549
1550 #ifdef HAVE_WINDOW_SYSTEM
1551 if (FRAME_WINDOW_P (f))
1552 {
1553 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1554 even for negative values. */
1555 if (pix_x < 0)
1556 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1557 if (pix_y < 0)
1558 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1559
1560 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1561 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1562
1563 if (bounds)
1564 STORE_NATIVE_RECT (*bounds,
1565 FRAME_COL_TO_PIXEL_X (f, pix_x),
1566 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1567 FRAME_COLUMN_WIDTH (f) - 1,
1568 FRAME_LINE_HEIGHT (f) - 1);
1569
1570 if (!noclip)
1571 {
1572 if (pix_x < 0)
1573 pix_x = 0;
1574 else if (pix_x > FRAME_TOTAL_COLS (f))
1575 pix_x = FRAME_TOTAL_COLS (f);
1576
1577 if (pix_y < 0)
1578 pix_y = 0;
1579 else if (pix_y > FRAME_LINES (f))
1580 pix_y = FRAME_LINES (f);
1581 }
1582 }
1583 #endif
1584
1585 *x = pix_x;
1586 *y = pix_y;
1587 }
1588
1589
1590 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1591 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1592 can't tell the positions because W's display is not up to date,
1593 return 0. */
1594
1595 int
1596 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1597 struct window *w;
1598 int hpos, vpos;
1599 int *frame_x, *frame_y;
1600 {
1601 #ifdef HAVE_WINDOW_SYSTEM
1602 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1603 {
1604 int success_p;
1605
1606 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1607 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1608
1609 if (display_completed)
1610 {
1611 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1612 struct glyph *glyph = row->glyphs[TEXT_AREA];
1613 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1614
1615 hpos = row->x;
1616 vpos = row->y;
1617 while (glyph < end)
1618 {
1619 hpos += glyph->pixel_width;
1620 ++glyph;
1621 }
1622
1623 /* If first glyph is partially visible, its first visible position is still 0. */
1624 if (hpos < 0)
1625 hpos = 0;
1626
1627 success_p = 1;
1628 }
1629 else
1630 {
1631 hpos = vpos = 0;
1632 success_p = 0;
1633 }
1634
1635 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1636 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1637 return success_p;
1638 }
1639 #endif
1640
1641 *frame_x = hpos;
1642 *frame_y = vpos;
1643 return 1;
1644 }
1645
1646
1647 #ifdef HAVE_WINDOW_SYSTEM
1648
1649 /* Find the glyph under window-relative coordinates X/Y in window W.
1650 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1651 strings. Return in *HPOS and *VPOS the row and column number of
1652 the glyph found. Return in *AREA the glyph area containing X.
1653 Value is a pointer to the glyph found or null if X/Y is not on
1654 text, or we can't tell because W's current matrix is not up to
1655 date. */
1656
1657 static struct glyph *
1658 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1659 struct window *w;
1660 int x, y;
1661 int *hpos, *vpos, *dx, *dy, *area;
1662 {
1663 struct glyph *glyph, *end;
1664 struct glyph_row *row = NULL;
1665 int x0, i;
1666
1667 /* Find row containing Y. Give up if some row is not enabled. */
1668 for (i = 0; i < w->current_matrix->nrows; ++i)
1669 {
1670 row = MATRIX_ROW (w->current_matrix, i);
1671 if (!row->enabled_p)
1672 return NULL;
1673 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1674 break;
1675 }
1676
1677 *vpos = i;
1678 *hpos = 0;
1679
1680 /* Give up if Y is not in the window. */
1681 if (i == w->current_matrix->nrows)
1682 return NULL;
1683
1684 /* Get the glyph area containing X. */
1685 if (w->pseudo_window_p)
1686 {
1687 *area = TEXT_AREA;
1688 x0 = 0;
1689 }
1690 else
1691 {
1692 if (x < window_box_left_offset (w, TEXT_AREA))
1693 {
1694 *area = LEFT_MARGIN_AREA;
1695 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1696 }
1697 else if (x < window_box_right_offset (w, TEXT_AREA))
1698 {
1699 *area = TEXT_AREA;
1700 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1701 }
1702 else
1703 {
1704 *area = RIGHT_MARGIN_AREA;
1705 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1706 }
1707 }
1708
1709 /* Find glyph containing X. */
1710 glyph = row->glyphs[*area];
1711 end = glyph + row->used[*area];
1712 x -= x0;
1713 while (glyph < end && x >= glyph->pixel_width)
1714 {
1715 x -= glyph->pixel_width;
1716 ++glyph;
1717 }
1718
1719 if (glyph == end)
1720 return NULL;
1721
1722 if (dx)
1723 {
1724 *dx = x;
1725 *dy = y - (row->y + row->ascent - glyph->ascent);
1726 }
1727
1728 *hpos = glyph - row->glyphs[*area];
1729 return glyph;
1730 }
1731
1732
1733 /* EXPORT:
1734 Convert frame-relative x/y to coordinates relative to window W.
1735 Takes pseudo-windows into account. */
1736
1737 void
1738 frame_to_window_pixel_xy (w, x, y)
1739 struct window *w;
1740 int *x, *y;
1741 {
1742 if (w->pseudo_window_p)
1743 {
1744 /* A pseudo-window is always full-width, and starts at the
1745 left edge of the frame, plus a frame border. */
1746 struct frame *f = XFRAME (w->frame);
1747 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1748 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1749 }
1750 else
1751 {
1752 *x -= WINDOW_LEFT_EDGE_X (w);
1753 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1754 }
1755 }
1756
1757 /* EXPORT:
1758 Return in *R the clipping rectangle for glyph string S. */
1759
1760 void
1761 get_glyph_string_clip_rect (s, nr)
1762 struct glyph_string *s;
1763 NativeRectangle *nr;
1764 {
1765 XRectangle r;
1766
1767 if (s->row->full_width_p)
1768 {
1769 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1770 r.x = WINDOW_LEFT_EDGE_X (s->w);
1771 r.width = WINDOW_TOTAL_WIDTH (s->w);
1772
1773 /* Unless displaying a mode or menu bar line, which are always
1774 fully visible, clip to the visible part of the row. */
1775 if (s->w->pseudo_window_p)
1776 r.height = s->row->visible_height;
1777 else
1778 r.height = s->height;
1779 }
1780 else
1781 {
1782 /* This is a text line that may be partially visible. */
1783 r.x = window_box_left (s->w, s->area);
1784 r.width = window_box_width (s->w, s->area);
1785 r.height = s->row->visible_height;
1786 }
1787
1788 if (s->clip_head)
1789 if (r.x < s->clip_head->x)
1790 {
1791 if (r.width >= s->clip_head->x - r.x)
1792 r.width -= s->clip_head->x - r.x;
1793 else
1794 r.width = 0;
1795 r.x = s->clip_head->x;
1796 }
1797 if (s->clip_tail)
1798 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1799 {
1800 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1801 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1802 else
1803 r.width = 0;
1804 }
1805
1806 /* If S draws overlapping rows, it's sufficient to use the top and
1807 bottom of the window for clipping because this glyph string
1808 intentionally draws over other lines. */
1809 if (s->for_overlaps_p)
1810 {
1811 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1812 r.height = window_text_bottom_y (s->w) - r.y;
1813 }
1814 else
1815 {
1816 /* Don't use S->y for clipping because it doesn't take partially
1817 visible lines into account. For example, it can be negative for
1818 partially visible lines at the top of a window. */
1819 if (!s->row->full_width_p
1820 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1821 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1822 else
1823 r.y = max (0, s->row->y);
1824
1825 /* If drawing a tool-bar window, draw it over the internal border
1826 at the top of the window. */
1827 if (WINDOWP (s->f->tool_bar_window)
1828 && s->w == XWINDOW (s->f->tool_bar_window))
1829 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1830 }
1831
1832 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1833
1834 /* If drawing the cursor, don't let glyph draw outside its
1835 advertised boundaries. Cleartype does this under some circumstances. */
1836 if (s->hl == DRAW_CURSOR)
1837 {
1838 struct glyph *glyph = s->first_glyph;
1839 int height, max_y;
1840
1841 if (s->x > r.x)
1842 {
1843 r.width -= s->x - r.x;
1844 r.x = s->x;
1845 }
1846 r.width = min (r.width, glyph->pixel_width);
1847
1848 /* If r.y is below window bottom, ensure that we still see a cursor. */
1849 height = min (glyph->ascent + glyph->descent,
1850 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1851 max_y = window_text_bottom_y (s->w) - height;
1852 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1853 if (s->ybase - glyph->ascent > max_y)
1854 {
1855 r.y = max_y;
1856 r.height = height;
1857 }
1858 else
1859 {
1860 /* Don't draw cursor glyph taller than our actual glyph. */
1861 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1862 if (height < r.height)
1863 {
1864 max_y = r.y + r.height;
1865 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1866 r.height = min (max_y - r.y, height);
1867 }
1868 }
1869 }
1870
1871 #ifdef CONVERT_FROM_XRECT
1872 CONVERT_FROM_XRECT (r, *nr);
1873 #else
1874 *nr = r;
1875 #endif
1876 }
1877
1878
1879 /* EXPORT:
1880 Return the position and height of the phys cursor in window W.
1881 Set w->phys_cursor_width to width of phys cursor.
1882 */
1883
1884 int
1885 get_phys_cursor_geometry (w, row, glyph, heightp)
1886 struct window *w;
1887 struct glyph_row *row;
1888 struct glyph *glyph;
1889 int *heightp;
1890 {
1891 struct frame *f = XFRAME (WINDOW_FRAME (w));
1892 int y, wd, h, h0, y0;
1893
1894 /* Compute the width of the rectangle to draw. If on a stretch
1895 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1896 rectangle as wide as the glyph, but use a canonical character
1897 width instead. */
1898 wd = glyph->pixel_width - 1;
1899 #ifdef HAVE_NTGUI
1900 wd++; /* Why? */
1901 #endif
1902 if (glyph->type == STRETCH_GLYPH
1903 && !x_stretch_cursor_p)
1904 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1905 w->phys_cursor_width = wd;
1906
1907 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1908
1909 /* If y is below window bottom, ensure that we still see a cursor. */
1910 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1911
1912 h = max (h0, glyph->ascent + glyph->descent);
1913 h0 = min (h0, glyph->ascent + glyph->descent);
1914
1915 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1916 if (y < y0)
1917 {
1918 h = max (h - (y0 - y) + 1, h0);
1919 y = y0 - 1;
1920 }
1921 else
1922 {
1923 y0 = window_text_bottom_y (w) - h0;
1924 if (y > y0)
1925 {
1926 h += y - y0;
1927 y = y0;
1928 }
1929 }
1930
1931 *heightp = h - 1;
1932 return WINDOW_TO_FRAME_PIXEL_Y (w, y);
1933 }
1934
1935
1936 #endif /* HAVE_WINDOW_SYSTEM */
1937
1938 \f
1939 /***********************************************************************
1940 Lisp form evaluation
1941 ***********************************************************************/
1942
1943 /* Error handler for safe_eval and safe_call. */
1944
1945 static Lisp_Object
1946 safe_eval_handler (arg)
1947 Lisp_Object arg;
1948 {
1949 add_to_log ("Error during redisplay: %s", arg, Qnil);
1950 return Qnil;
1951 }
1952
1953
1954 /* Evaluate SEXPR and return the result, or nil if something went
1955 wrong. Prevent redisplay during the evaluation. */
1956
1957 Lisp_Object
1958 safe_eval (sexpr)
1959 Lisp_Object sexpr;
1960 {
1961 Lisp_Object val;
1962
1963 if (inhibit_eval_during_redisplay)
1964 val = Qnil;
1965 else
1966 {
1967 int count = SPECPDL_INDEX ();
1968 struct gcpro gcpro1;
1969
1970 GCPRO1 (sexpr);
1971 specbind (Qinhibit_redisplay, Qt);
1972 /* Use Qt to ensure debugger does not run,
1973 so there is no possibility of wanting to redisplay. */
1974 val = internal_condition_case_1 (Feval, sexpr, Qt,
1975 safe_eval_handler);
1976 UNGCPRO;
1977 val = unbind_to (count, val);
1978 }
1979
1980 return val;
1981 }
1982
1983
1984 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1985 Return the result, or nil if something went wrong. Prevent
1986 redisplay during the evaluation. */
1987
1988 Lisp_Object
1989 safe_call (nargs, args)
1990 int nargs;
1991 Lisp_Object *args;
1992 {
1993 Lisp_Object val;
1994
1995 if (inhibit_eval_during_redisplay)
1996 val = Qnil;
1997 else
1998 {
1999 int count = SPECPDL_INDEX ();
2000 struct gcpro gcpro1;
2001
2002 GCPRO1 (args[0]);
2003 gcpro1.nvars = nargs;
2004 specbind (Qinhibit_redisplay, Qt);
2005 /* Use Qt to ensure debugger does not run,
2006 so there is no possibility of wanting to redisplay. */
2007 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2008 safe_eval_handler);
2009 UNGCPRO;
2010 val = unbind_to (count, val);
2011 }
2012
2013 return val;
2014 }
2015
2016
2017 /* Call function FN with one argument ARG.
2018 Return the result, or nil if something went wrong. */
2019
2020 Lisp_Object
2021 safe_call1 (fn, arg)
2022 Lisp_Object fn, arg;
2023 {
2024 Lisp_Object args[2];
2025 args[0] = fn;
2026 args[1] = arg;
2027 return safe_call (2, args);
2028 }
2029
2030
2031 \f
2032 /***********************************************************************
2033 Debugging
2034 ***********************************************************************/
2035
2036 #if 0
2037
2038 /* Define CHECK_IT to perform sanity checks on iterators.
2039 This is for debugging. It is too slow to do unconditionally. */
2040
2041 static void
2042 check_it (it)
2043 struct it *it;
2044 {
2045 if (it->method == GET_FROM_STRING)
2046 {
2047 xassert (STRINGP (it->string));
2048 xassert (IT_STRING_CHARPOS (*it) >= 0);
2049 }
2050 else
2051 {
2052 xassert (IT_STRING_CHARPOS (*it) < 0);
2053 if (it->method == GET_FROM_BUFFER)
2054 {
2055 /* Check that character and byte positions agree. */
2056 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2057 }
2058 }
2059
2060 if (it->dpvec)
2061 xassert (it->current.dpvec_index >= 0);
2062 else
2063 xassert (it->current.dpvec_index < 0);
2064 }
2065
2066 #define CHECK_IT(IT) check_it ((IT))
2067
2068 #else /* not 0 */
2069
2070 #define CHECK_IT(IT) (void) 0
2071
2072 #endif /* not 0 */
2073
2074
2075 #if GLYPH_DEBUG
2076
2077 /* Check that the window end of window W is what we expect it
2078 to be---the last row in the current matrix displaying text. */
2079
2080 static void
2081 check_window_end (w)
2082 struct window *w;
2083 {
2084 if (!MINI_WINDOW_P (w)
2085 && !NILP (w->window_end_valid))
2086 {
2087 struct glyph_row *row;
2088 xassert ((row = MATRIX_ROW (w->current_matrix,
2089 XFASTINT (w->window_end_vpos)),
2090 !row->enabled_p
2091 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2092 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2093 }
2094 }
2095
2096 #define CHECK_WINDOW_END(W) check_window_end ((W))
2097
2098 #else /* not GLYPH_DEBUG */
2099
2100 #define CHECK_WINDOW_END(W) (void) 0
2101
2102 #endif /* not GLYPH_DEBUG */
2103
2104
2105 \f
2106 /***********************************************************************
2107 Iterator initialization
2108 ***********************************************************************/
2109
2110 /* Initialize IT for displaying current_buffer in window W, starting
2111 at character position CHARPOS. CHARPOS < 0 means that no buffer
2112 position is specified which is useful when the iterator is assigned
2113 a position later. BYTEPOS is the byte position corresponding to
2114 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2115
2116 If ROW is not null, calls to produce_glyphs with IT as parameter
2117 will produce glyphs in that row.
2118
2119 BASE_FACE_ID is the id of a base face to use. It must be one of
2120 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2121 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2122 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2123
2124 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2125 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2126 will be initialized to use the corresponding mode line glyph row of
2127 the desired matrix of W. */
2128
2129 void
2130 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2131 struct it *it;
2132 struct window *w;
2133 int charpos, bytepos;
2134 struct glyph_row *row;
2135 enum face_id base_face_id;
2136 {
2137 int highlight_region_p;
2138
2139 /* Some precondition checks. */
2140 xassert (w != NULL && it != NULL);
2141 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2142 && charpos <= ZV));
2143
2144 /* If face attributes have been changed since the last redisplay,
2145 free realized faces now because they depend on face definitions
2146 that might have changed. Don't free faces while there might be
2147 desired matrices pending which reference these faces. */
2148 if (face_change_count && !inhibit_free_realized_faces)
2149 {
2150 face_change_count = 0;
2151 free_all_realized_faces (Qnil);
2152 }
2153
2154 /* Use one of the mode line rows of W's desired matrix if
2155 appropriate. */
2156 if (row == NULL)
2157 {
2158 if (base_face_id == MODE_LINE_FACE_ID
2159 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2160 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2161 else if (base_face_id == HEADER_LINE_FACE_ID)
2162 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2163 }
2164
2165 /* Clear IT. */
2166 bzero (it, sizeof *it);
2167 it->current.overlay_string_index = -1;
2168 it->current.dpvec_index = -1;
2169 it->base_face_id = base_face_id;
2170 it->string = Qnil;
2171 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2172
2173 /* The window in which we iterate over current_buffer: */
2174 XSETWINDOW (it->window, w);
2175 it->w = w;
2176 it->f = XFRAME (w->frame);
2177
2178 /* Extra space between lines (on window systems only). */
2179 if (base_face_id == DEFAULT_FACE_ID
2180 && FRAME_WINDOW_P (it->f))
2181 {
2182 if (NATNUMP (current_buffer->extra_line_spacing))
2183 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2184 else if (FLOATP (current_buffer->extra_line_spacing))
2185 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2186 * FRAME_LINE_HEIGHT (it->f));
2187 else if (it->f->extra_line_spacing > 0)
2188 it->extra_line_spacing = it->f->extra_line_spacing;
2189 it->max_extra_line_spacing = 0;
2190 }
2191
2192 /* If realized faces have been removed, e.g. because of face
2193 attribute changes of named faces, recompute them. When running
2194 in batch mode, the face cache of the initial frame is null. If
2195 we happen to get called, make a dummy face cache. */
2196 if (FRAME_FACE_CACHE (it->f) == NULL)
2197 init_frame_faces (it->f);
2198 if (FRAME_FACE_CACHE (it->f)->used == 0)
2199 recompute_basic_faces (it->f);
2200
2201 /* Current value of the `slice', `space-width', and 'height' properties. */
2202 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2203 it->space_width = Qnil;
2204 it->font_height = Qnil;
2205 it->override_ascent = -1;
2206
2207 /* Are control characters displayed as `^C'? */
2208 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2209
2210 /* -1 means everything between a CR and the following line end
2211 is invisible. >0 means lines indented more than this value are
2212 invisible. */
2213 it->selective = (INTEGERP (current_buffer->selective_display)
2214 ? XFASTINT (current_buffer->selective_display)
2215 : (!NILP (current_buffer->selective_display)
2216 ? -1 : 0));
2217 it->selective_display_ellipsis_p
2218 = !NILP (current_buffer->selective_display_ellipses);
2219
2220 /* Display table to use. */
2221 it->dp = window_display_table (w);
2222
2223 /* Are multibyte characters enabled in current_buffer? */
2224 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2225
2226 /* Non-zero if we should highlight the region. */
2227 highlight_region_p
2228 = (!NILP (Vtransient_mark_mode)
2229 && !NILP (current_buffer->mark_active)
2230 && XMARKER (current_buffer->mark)->buffer != 0);
2231
2232 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2233 start and end of a visible region in window IT->w. Set both to
2234 -1 to indicate no region. */
2235 if (highlight_region_p
2236 /* Maybe highlight only in selected window. */
2237 && (/* Either show region everywhere. */
2238 highlight_nonselected_windows
2239 /* Or show region in the selected window. */
2240 || w == XWINDOW (selected_window)
2241 /* Or show the region if we are in the mini-buffer and W is
2242 the window the mini-buffer refers to. */
2243 || (MINI_WINDOW_P (XWINDOW (selected_window))
2244 && WINDOWP (minibuf_selected_window)
2245 && w == XWINDOW (minibuf_selected_window))))
2246 {
2247 int charpos = marker_position (current_buffer->mark);
2248 it->region_beg_charpos = min (PT, charpos);
2249 it->region_end_charpos = max (PT, charpos);
2250 }
2251 else
2252 it->region_beg_charpos = it->region_end_charpos = -1;
2253
2254 /* Get the position at which the redisplay_end_trigger hook should
2255 be run, if it is to be run at all. */
2256 if (MARKERP (w->redisplay_end_trigger)
2257 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2258 it->redisplay_end_trigger_charpos
2259 = marker_position (w->redisplay_end_trigger);
2260 else if (INTEGERP (w->redisplay_end_trigger))
2261 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2262
2263 /* Correct bogus values of tab_width. */
2264 it->tab_width = XINT (current_buffer->tab_width);
2265 if (it->tab_width <= 0 || it->tab_width > 1000)
2266 it->tab_width = 8;
2267
2268 /* Are lines in the display truncated? */
2269 it->truncate_lines_p
2270 = (base_face_id != DEFAULT_FACE_ID
2271 || XINT (it->w->hscroll)
2272 || (truncate_partial_width_windows
2273 && !WINDOW_FULL_WIDTH_P (it->w))
2274 || !NILP (current_buffer->truncate_lines));
2275
2276 /* Get dimensions of truncation and continuation glyphs. These are
2277 displayed as fringe bitmaps under X, so we don't need them for such
2278 frames. */
2279 if (!FRAME_WINDOW_P (it->f))
2280 {
2281 if (it->truncate_lines_p)
2282 {
2283 /* We will need the truncation glyph. */
2284 xassert (it->glyph_row == NULL);
2285 produce_special_glyphs (it, IT_TRUNCATION);
2286 it->truncation_pixel_width = it->pixel_width;
2287 }
2288 else
2289 {
2290 /* We will need the continuation glyph. */
2291 xassert (it->glyph_row == NULL);
2292 produce_special_glyphs (it, IT_CONTINUATION);
2293 it->continuation_pixel_width = it->pixel_width;
2294 }
2295
2296 /* Reset these values to zero because the produce_special_glyphs
2297 above has changed them. */
2298 it->pixel_width = it->ascent = it->descent = 0;
2299 it->phys_ascent = it->phys_descent = 0;
2300 }
2301
2302 /* Set this after getting the dimensions of truncation and
2303 continuation glyphs, so that we don't produce glyphs when calling
2304 produce_special_glyphs, above. */
2305 it->glyph_row = row;
2306 it->area = TEXT_AREA;
2307
2308 /* Get the dimensions of the display area. The display area
2309 consists of the visible window area plus a horizontally scrolled
2310 part to the left of the window. All x-values are relative to the
2311 start of this total display area. */
2312 if (base_face_id != DEFAULT_FACE_ID)
2313 {
2314 /* Mode lines, menu bar in terminal frames. */
2315 it->first_visible_x = 0;
2316 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2317 }
2318 else
2319 {
2320 it->first_visible_x
2321 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2322 it->last_visible_x = (it->first_visible_x
2323 + window_box_width (w, TEXT_AREA));
2324
2325 /* If we truncate lines, leave room for the truncator glyph(s) at
2326 the right margin. Otherwise, leave room for the continuation
2327 glyph(s). Truncation and continuation glyphs are not inserted
2328 for window-based redisplay. */
2329 if (!FRAME_WINDOW_P (it->f))
2330 {
2331 if (it->truncate_lines_p)
2332 it->last_visible_x -= it->truncation_pixel_width;
2333 else
2334 it->last_visible_x -= it->continuation_pixel_width;
2335 }
2336
2337 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2338 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2339 }
2340
2341 /* Leave room for a border glyph. */
2342 if (!FRAME_WINDOW_P (it->f)
2343 && !WINDOW_RIGHTMOST_P (it->w))
2344 it->last_visible_x -= 1;
2345
2346 it->last_visible_y = window_text_bottom_y (w);
2347
2348 /* For mode lines and alike, arrange for the first glyph having a
2349 left box line if the face specifies a box. */
2350 if (base_face_id != DEFAULT_FACE_ID)
2351 {
2352 struct face *face;
2353
2354 it->face_id = base_face_id;
2355
2356 /* If we have a boxed mode line, make the first character appear
2357 with a left box line. */
2358 face = FACE_FROM_ID (it->f, base_face_id);
2359 if (face->box != FACE_NO_BOX)
2360 it->start_of_box_run_p = 1;
2361 }
2362
2363 /* If a buffer position was specified, set the iterator there,
2364 getting overlays and face properties from that position. */
2365 if (charpos >= BUF_BEG (current_buffer))
2366 {
2367 it->end_charpos = ZV;
2368 it->face_id = -1;
2369 IT_CHARPOS (*it) = charpos;
2370
2371 /* Compute byte position if not specified. */
2372 if (bytepos < charpos)
2373 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2374 else
2375 IT_BYTEPOS (*it) = bytepos;
2376
2377 it->start = it->current;
2378
2379 /* Compute faces etc. */
2380 reseat (it, it->current.pos, 1);
2381 }
2382
2383 CHECK_IT (it);
2384 }
2385
2386
2387 /* Initialize IT for the display of window W with window start POS. */
2388
2389 void
2390 start_display (it, w, pos)
2391 struct it *it;
2392 struct window *w;
2393 struct text_pos pos;
2394 {
2395 struct glyph_row *row;
2396 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2397
2398 row = w->desired_matrix->rows + first_vpos;
2399 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2400 it->first_vpos = first_vpos;
2401
2402 /* Don't reseat to previous visible line start if current start
2403 position is in a string or image. */
2404 if (it->method == GET_FROM_BUFFER && !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 /* Use face of preceding text for ellipsis (if invisible) */
2701 if (it->selective_display_ellipsis_p)
2702 it->saved_face_id = it->face_id;
2703
2704 do
2705 {
2706 handled = HANDLED_NORMALLY;
2707
2708 /* Call text property handlers. */
2709 for (p = it_props; p->handler; ++p)
2710 {
2711 handled = p->handler (it);
2712
2713 if (handled == HANDLED_RECOMPUTE_PROPS)
2714 break;
2715 else if (handled == HANDLED_RETURN)
2716 return;
2717 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2718 handle_overlay_change_p = 0;
2719 }
2720
2721 if (handled != HANDLED_RECOMPUTE_PROPS)
2722 {
2723 /* Don't check for overlay strings below when set to deliver
2724 characters from a display vector. */
2725 if (it->method == GET_FROM_DISPLAY_VECTOR)
2726 handle_overlay_change_p = 0;
2727
2728 /* Handle overlay changes. */
2729 if (handle_overlay_change_p)
2730 handled = handle_overlay_change (it);
2731
2732 /* Determine where to stop next. */
2733 if (handled == HANDLED_NORMALLY)
2734 compute_stop_pos (it);
2735 }
2736 }
2737 while (handled == HANDLED_RECOMPUTE_PROPS);
2738 }
2739
2740
2741 /* Compute IT->stop_charpos from text property and overlay change
2742 information for IT's current position. */
2743
2744 static void
2745 compute_stop_pos (it)
2746 struct it *it;
2747 {
2748 register INTERVAL iv, next_iv;
2749 Lisp_Object object, limit, position;
2750
2751 /* If nowhere else, stop at the end. */
2752 it->stop_charpos = it->end_charpos;
2753
2754 if (STRINGP (it->string))
2755 {
2756 /* Strings are usually short, so don't limit the search for
2757 properties. */
2758 object = it->string;
2759 limit = Qnil;
2760 position = make_number (IT_STRING_CHARPOS (*it));
2761 }
2762 else
2763 {
2764 int charpos;
2765
2766 /* If next overlay change is in front of the current stop pos
2767 (which is IT->end_charpos), stop there. Note: value of
2768 next_overlay_change is point-max if no overlay change
2769 follows. */
2770 charpos = next_overlay_change (IT_CHARPOS (*it));
2771 if (charpos < it->stop_charpos)
2772 it->stop_charpos = charpos;
2773
2774 /* If showing the region, we have to stop at the region
2775 start or end because the face might change there. */
2776 if (it->region_beg_charpos > 0)
2777 {
2778 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2779 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2780 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2781 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2782 }
2783
2784 /* Set up variables for computing the stop position from text
2785 property changes. */
2786 XSETBUFFER (object, current_buffer);
2787 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2788 position = make_number (IT_CHARPOS (*it));
2789
2790 }
2791
2792 /* Get the interval containing IT's position. Value is a null
2793 interval if there isn't such an interval. */
2794 iv = validate_interval_range (object, &position, &position, 0);
2795 if (!NULL_INTERVAL_P (iv))
2796 {
2797 Lisp_Object values_here[LAST_PROP_IDX];
2798 struct props *p;
2799
2800 /* Get properties here. */
2801 for (p = it_props; p->handler; ++p)
2802 values_here[p->idx] = textget (iv->plist, *p->name);
2803
2804 /* Look for an interval following iv that has different
2805 properties. */
2806 for (next_iv = next_interval (iv);
2807 (!NULL_INTERVAL_P (next_iv)
2808 && (NILP (limit)
2809 || XFASTINT (limit) > next_iv->position));
2810 next_iv = next_interval (next_iv))
2811 {
2812 for (p = it_props; p->handler; ++p)
2813 {
2814 Lisp_Object new_value;
2815
2816 new_value = textget (next_iv->plist, *p->name);
2817 if (!EQ (values_here[p->idx], new_value))
2818 break;
2819 }
2820
2821 if (p->handler)
2822 break;
2823 }
2824
2825 if (!NULL_INTERVAL_P (next_iv))
2826 {
2827 if (INTEGERP (limit)
2828 && next_iv->position >= XFASTINT (limit))
2829 /* No text property change up to limit. */
2830 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2831 else
2832 /* Text properties change in next_iv. */
2833 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2834 }
2835 }
2836
2837 xassert (STRINGP (it->string)
2838 || (it->stop_charpos >= BEGV
2839 && it->stop_charpos >= IT_CHARPOS (*it)));
2840 }
2841
2842
2843 /* Return the position of the next overlay change after POS in
2844 current_buffer. Value is point-max if no overlay change
2845 follows. This is like `next-overlay-change' but doesn't use
2846 xmalloc. */
2847
2848 static int
2849 next_overlay_change (pos)
2850 int pos;
2851 {
2852 int noverlays;
2853 int endpos;
2854 Lisp_Object *overlays;
2855 int i;
2856
2857 /* Get all overlays at the given position. */
2858 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2859
2860 /* If any of these overlays ends before endpos,
2861 use its ending point instead. */
2862 for (i = 0; i < noverlays; ++i)
2863 {
2864 Lisp_Object oend;
2865 int oendpos;
2866
2867 oend = OVERLAY_END (overlays[i]);
2868 oendpos = OVERLAY_POSITION (oend);
2869 endpos = min (endpos, oendpos);
2870 }
2871
2872 return endpos;
2873 }
2874
2875
2876 \f
2877 /***********************************************************************
2878 Fontification
2879 ***********************************************************************/
2880
2881 /* Handle changes in the `fontified' property of the current buffer by
2882 calling hook functions from Qfontification_functions to fontify
2883 regions of text. */
2884
2885 static enum prop_handled
2886 handle_fontified_prop (it)
2887 struct it *it;
2888 {
2889 Lisp_Object prop, pos;
2890 enum prop_handled handled = HANDLED_NORMALLY;
2891
2892 /* Get the value of the `fontified' property at IT's current buffer
2893 position. (The `fontified' property doesn't have a special
2894 meaning in strings.) If the value is nil, call functions from
2895 Qfontification_functions. */
2896 if (!STRINGP (it->string)
2897 && it->s == NULL
2898 && !NILP (Vfontification_functions)
2899 && !NILP (Vrun_hooks)
2900 && (pos = make_number (IT_CHARPOS (*it)),
2901 prop = Fget_char_property (pos, Qfontified, Qnil),
2902 NILP (prop)))
2903 {
2904 int count = SPECPDL_INDEX ();
2905 Lisp_Object val;
2906
2907 val = Vfontification_functions;
2908 specbind (Qfontification_functions, Qnil);
2909
2910 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2911 safe_call1 (val, pos);
2912 else
2913 {
2914 Lisp_Object globals, fn;
2915 struct gcpro gcpro1, gcpro2;
2916
2917 globals = Qnil;
2918 GCPRO2 (val, globals);
2919
2920 for (; CONSP (val); val = XCDR (val))
2921 {
2922 fn = XCAR (val);
2923
2924 if (EQ (fn, Qt))
2925 {
2926 /* A value of t indicates this hook has a local
2927 binding; it means to run the global binding too.
2928 In a global value, t should not occur. If it
2929 does, we must ignore it to avoid an endless
2930 loop. */
2931 for (globals = Fdefault_value (Qfontification_functions);
2932 CONSP (globals);
2933 globals = XCDR (globals))
2934 {
2935 fn = XCAR (globals);
2936 if (!EQ (fn, Qt))
2937 safe_call1 (fn, pos);
2938 }
2939 }
2940 else
2941 safe_call1 (fn, pos);
2942 }
2943
2944 UNGCPRO;
2945 }
2946
2947 unbind_to (count, Qnil);
2948
2949 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2950 something. This avoids an endless loop if they failed to
2951 fontify the text for which reason ever. */
2952 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2953 handled = HANDLED_RECOMPUTE_PROPS;
2954 }
2955
2956 return handled;
2957 }
2958
2959
2960 \f
2961 /***********************************************************************
2962 Faces
2963 ***********************************************************************/
2964
2965 /* Set up iterator IT from face properties at its current position.
2966 Called from handle_stop. */
2967
2968 static enum prop_handled
2969 handle_face_prop (it)
2970 struct it *it;
2971 {
2972 int new_face_id, next_stop;
2973
2974 if (!STRINGP (it->string))
2975 {
2976 new_face_id
2977 = face_at_buffer_position (it->w,
2978 IT_CHARPOS (*it),
2979 it->region_beg_charpos,
2980 it->region_end_charpos,
2981 &next_stop,
2982 (IT_CHARPOS (*it)
2983 + TEXT_PROP_DISTANCE_LIMIT),
2984 0);
2985
2986 /* Is this a start of a run of characters with box face?
2987 Caveat: this can be called for a freshly initialized
2988 iterator; face_id is -1 in this case. We know that the new
2989 face will not change until limit, i.e. if the new face has a
2990 box, all characters up to limit will have one. But, as
2991 usual, we don't know whether limit is really the end. */
2992 if (new_face_id != it->face_id)
2993 {
2994 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
2995
2996 /* If new face has a box but old face has not, this is
2997 the start of a run of characters with box, i.e. it has
2998 a shadow on the left side. The value of face_id of the
2999 iterator will be -1 if this is the initial call that gets
3000 the face. In this case, we have to look in front of IT's
3001 position and see whether there is a face != new_face_id. */
3002 it->start_of_box_run_p
3003 = (new_face->box != FACE_NO_BOX
3004 && (it->face_id >= 0
3005 || IT_CHARPOS (*it) == BEG
3006 || new_face_id != face_before_it_pos (it)));
3007 it->face_box_p = new_face->box != FACE_NO_BOX;
3008 }
3009 }
3010 else
3011 {
3012 int base_face_id, bufpos;
3013
3014 if (it->current.overlay_string_index >= 0)
3015 bufpos = IT_CHARPOS (*it);
3016 else
3017 bufpos = 0;
3018
3019 /* For strings from a buffer, i.e. overlay strings or strings
3020 from a `display' property, use the face at IT's current
3021 buffer position as the base face to merge with, so that
3022 overlay strings appear in the same face as surrounding
3023 text, unless they specify their own faces. */
3024 base_face_id = underlying_face_id (it);
3025
3026 new_face_id = face_at_string_position (it->w,
3027 it->string,
3028 IT_STRING_CHARPOS (*it),
3029 bufpos,
3030 it->region_beg_charpos,
3031 it->region_end_charpos,
3032 &next_stop,
3033 base_face_id, 0);
3034
3035 #if 0 /* This shouldn't be neccessary. Let's check it. */
3036 /* If IT is used to display a mode line we would really like to
3037 use the mode line face instead of the frame's default face. */
3038 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3039 && new_face_id == DEFAULT_FACE_ID)
3040 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3041 #endif
3042
3043 /* Is this a start of a run of characters with box? Caveat:
3044 this can be called for a freshly allocated iterator; face_id
3045 is -1 is this case. We know that the new face will not
3046 change until the next check pos, i.e. if the new face has a
3047 box, all characters up to that position will have a
3048 box. But, as usual, we don't know whether that position
3049 is really the end. */
3050 if (new_face_id != it->face_id)
3051 {
3052 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3053 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3054
3055 /* If new face has a box but old face hasn't, this is the
3056 start of a run of characters with box, i.e. it has a
3057 shadow on the left side. */
3058 it->start_of_box_run_p
3059 = new_face->box && (old_face == NULL || !old_face->box);
3060 it->face_box_p = new_face->box != FACE_NO_BOX;
3061 }
3062 }
3063
3064 it->face_id = new_face_id;
3065 return HANDLED_NORMALLY;
3066 }
3067
3068
3069 /* Return the ID of the face ``underlying'' IT's current position,
3070 which is in a string. If the iterator is associated with a
3071 buffer, return the face at IT's current buffer position.
3072 Otherwise, use the iterator's base_face_id. */
3073
3074 static int
3075 underlying_face_id (it)
3076 struct it *it;
3077 {
3078 int face_id = it->base_face_id, i;
3079
3080 xassert (STRINGP (it->string));
3081
3082 for (i = it->sp - 1; i >= 0; --i)
3083 if (NILP (it->stack[i].string))
3084 face_id = it->stack[i].face_id;
3085
3086 return face_id;
3087 }
3088
3089
3090 /* Compute the face one character before or after the current position
3091 of IT. BEFORE_P non-zero means get the face in front of IT's
3092 position. Value is the id of the face. */
3093
3094 static int
3095 face_before_or_after_it_pos (it, before_p)
3096 struct it *it;
3097 int before_p;
3098 {
3099 int face_id, limit;
3100 int next_check_charpos;
3101 struct text_pos pos;
3102
3103 xassert (it->s == NULL);
3104
3105 if (STRINGP (it->string))
3106 {
3107 int bufpos, base_face_id;
3108
3109 /* No face change past the end of the string (for the case
3110 we are padding with spaces). No face change before the
3111 string start. */
3112 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3113 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3114 return it->face_id;
3115
3116 /* Set pos to the position before or after IT's current position. */
3117 if (before_p)
3118 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3119 else
3120 /* For composition, we must check the character after the
3121 composition. */
3122 pos = (it->what == IT_COMPOSITION
3123 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3124 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3125
3126 if (it->current.overlay_string_index >= 0)
3127 bufpos = IT_CHARPOS (*it);
3128 else
3129 bufpos = 0;
3130
3131 base_face_id = underlying_face_id (it);
3132
3133 /* Get the face for ASCII, or unibyte. */
3134 face_id = face_at_string_position (it->w,
3135 it->string,
3136 CHARPOS (pos),
3137 bufpos,
3138 it->region_beg_charpos,
3139 it->region_end_charpos,
3140 &next_check_charpos,
3141 base_face_id, 0);
3142
3143 /* Correct the face for charsets different from ASCII. Do it
3144 for the multibyte case only. The face returned above is
3145 suitable for unibyte text if IT->string is unibyte. */
3146 if (STRING_MULTIBYTE (it->string))
3147 {
3148 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3149 int rest = SBYTES (it->string) - BYTEPOS (pos);
3150 int c, len;
3151 struct face *face = FACE_FROM_ID (it->f, face_id);
3152
3153 c = string_char_and_length (p, rest, &len);
3154 face_id = FACE_FOR_CHAR (it->f, face, c);
3155 }
3156 }
3157 else
3158 {
3159 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3160 || (IT_CHARPOS (*it) <= BEGV && before_p))
3161 return it->face_id;
3162
3163 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3164 pos = it->current.pos;
3165
3166 if (before_p)
3167 DEC_TEXT_POS (pos, it->multibyte_p);
3168 else
3169 {
3170 if (it->what == IT_COMPOSITION)
3171 /* For composition, we must check the position after the
3172 composition. */
3173 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3174 else
3175 INC_TEXT_POS (pos, it->multibyte_p);
3176 }
3177
3178 /* Determine face for CHARSET_ASCII, or unibyte. */
3179 face_id = face_at_buffer_position (it->w,
3180 CHARPOS (pos),
3181 it->region_beg_charpos,
3182 it->region_end_charpos,
3183 &next_check_charpos,
3184 limit, 0);
3185
3186 /* Correct the face for charsets different from ASCII. Do it
3187 for the multibyte case only. The face returned above is
3188 suitable for unibyte text if current_buffer is unibyte. */
3189 if (it->multibyte_p)
3190 {
3191 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3192 struct face *face = FACE_FROM_ID (it->f, face_id);
3193 face_id = FACE_FOR_CHAR (it->f, face, c);
3194 }
3195 }
3196
3197 return face_id;
3198 }
3199
3200
3201 \f
3202 /***********************************************************************
3203 Invisible text
3204 ***********************************************************************/
3205
3206 /* Set up iterator IT from invisible properties at its current
3207 position. Called from handle_stop. */
3208
3209 static enum prop_handled
3210 handle_invisible_prop (it)
3211 struct it *it;
3212 {
3213 enum prop_handled handled = HANDLED_NORMALLY;
3214
3215 if (STRINGP (it->string))
3216 {
3217 extern Lisp_Object Qinvisible;
3218 Lisp_Object prop, end_charpos, limit, charpos;
3219
3220 /* Get the value of the invisible text property at the
3221 current position. Value will be nil if there is no such
3222 property. */
3223 charpos = make_number (IT_STRING_CHARPOS (*it));
3224 prop = Fget_text_property (charpos, Qinvisible, it->string);
3225
3226 if (!NILP (prop)
3227 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3228 {
3229 handled = HANDLED_RECOMPUTE_PROPS;
3230
3231 /* Get the position at which the next change of the
3232 invisible text property can be found in IT->string.
3233 Value will be nil if the property value is the same for
3234 all the rest of IT->string. */
3235 XSETINT (limit, SCHARS (it->string));
3236 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3237 it->string, limit);
3238
3239 /* Text at current position is invisible. The next
3240 change in the property is at position end_charpos.
3241 Move IT's current position to that position. */
3242 if (INTEGERP (end_charpos)
3243 && XFASTINT (end_charpos) < XFASTINT (limit))
3244 {
3245 struct text_pos old;
3246 old = it->current.string_pos;
3247 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3248 compute_string_pos (&it->current.string_pos, old, it->string);
3249 }
3250 else
3251 {
3252 /* The rest of the string is invisible. If this is an
3253 overlay string, proceed with the next overlay string
3254 or whatever comes and return a character from there. */
3255 if (it->current.overlay_string_index >= 0)
3256 {
3257 next_overlay_string (it);
3258 /* Don't check for overlay strings when we just
3259 finished processing them. */
3260 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3261 }
3262 else
3263 {
3264 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3265 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3266 }
3267 }
3268 }
3269 }
3270 else
3271 {
3272 int invis_p, newpos, next_stop, start_charpos;
3273 Lisp_Object pos, prop, overlay;
3274
3275 /* First of all, is there invisible text at this position? */
3276 start_charpos = IT_CHARPOS (*it);
3277 pos = make_number (IT_CHARPOS (*it));
3278 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3279 &overlay);
3280 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3281
3282 /* If we are on invisible text, skip over it. */
3283 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3284 {
3285 /* Record whether we have to display an ellipsis for the
3286 invisible text. */
3287 int display_ellipsis_p = invis_p == 2;
3288
3289 handled = HANDLED_RECOMPUTE_PROPS;
3290
3291 /* Loop skipping over invisible text. The loop is left at
3292 ZV or with IT on the first char being visible again. */
3293 do
3294 {
3295 /* Try to skip some invisible text. Return value is the
3296 position reached which can be equal to IT's position
3297 if there is nothing invisible here. This skips both
3298 over invisible text properties and overlays with
3299 invisible property. */
3300 newpos = skip_invisible (IT_CHARPOS (*it),
3301 &next_stop, ZV, it->window);
3302
3303 /* If we skipped nothing at all we weren't at invisible
3304 text in the first place. If everything to the end of
3305 the buffer was skipped, end the loop. */
3306 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3307 invis_p = 0;
3308 else
3309 {
3310 /* We skipped some characters but not necessarily
3311 all there are. Check if we ended up on visible
3312 text. Fget_char_property returns the property of
3313 the char before the given position, i.e. if we
3314 get invis_p = 0, this means that the char at
3315 newpos is visible. */
3316 pos = make_number (newpos);
3317 prop = Fget_char_property (pos, Qinvisible, it->window);
3318 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3319 }
3320
3321 /* If we ended up on invisible text, proceed to
3322 skip starting with next_stop. */
3323 if (invis_p)
3324 IT_CHARPOS (*it) = next_stop;
3325 }
3326 while (invis_p);
3327
3328 /* The position newpos is now either ZV or on visible text. */
3329 IT_CHARPOS (*it) = newpos;
3330 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3331
3332 /* If there are before-strings at the start of invisible
3333 text, and the text is invisible because of a text
3334 property, arrange to show before-strings because 20.x did
3335 it that way. (If the text is invisible because of an
3336 overlay property instead of a text property, this is
3337 already handled in the overlay code.) */
3338 if (NILP (overlay)
3339 && get_overlay_strings (it, start_charpos))
3340 {
3341 handled = HANDLED_RECOMPUTE_PROPS;
3342 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3343 }
3344 else if (display_ellipsis_p)
3345 setup_for_ellipsis (it, 0);
3346 }
3347 }
3348
3349 return handled;
3350 }
3351
3352
3353 /* Make iterator IT return `...' next.
3354 Replaces LEN characters from buffer. */
3355
3356 static void
3357 setup_for_ellipsis (it, len)
3358 struct it *it;
3359 int len;
3360 {
3361 /* Use the display table definition for `...'. Invalid glyphs
3362 will be handled by the method returning elements from dpvec. */
3363 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3364 {
3365 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3366 it->dpvec = v->contents;
3367 it->dpend = v->contents + v->size;
3368 }
3369 else
3370 {
3371 /* Default `...'. */
3372 it->dpvec = default_invis_vector;
3373 it->dpend = default_invis_vector + 3;
3374 }
3375
3376 it->dpvec_char_len = len;
3377 it->current.dpvec_index = 0;
3378 it->dpvec_face_id = -1;
3379
3380 /* Remember the current face id in case glyphs specify faces.
3381 IT's face is restored in set_iterator_to_next.
3382 saved_face_id was set to preceding char's face in handle_stop. */
3383 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3384 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3385
3386 it->method = GET_FROM_DISPLAY_VECTOR;
3387 it->ellipsis_p = 1;
3388 }
3389
3390
3391 \f
3392 /***********************************************************************
3393 'display' property
3394 ***********************************************************************/
3395
3396 /* Set up iterator IT from `display' property at its current position.
3397 Called from handle_stop.
3398 We return HANDLED_RETURN if some part of the display property
3399 overrides the display of the buffer text itself.
3400 Otherwise we return HANDLED_NORMALLY. */
3401
3402 static enum prop_handled
3403 handle_display_prop (it)
3404 struct it *it;
3405 {
3406 Lisp_Object prop, object;
3407 struct text_pos *position;
3408 /* Nonzero if some property replaces the display of the text itself. */
3409 int display_replaced_p = 0;
3410
3411 if (STRINGP (it->string))
3412 {
3413 object = it->string;
3414 position = &it->current.string_pos;
3415 }
3416 else
3417 {
3418 object = it->w->buffer;
3419 position = &it->current.pos;
3420 }
3421
3422 /* Reset those iterator values set from display property values. */
3423 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3424 it->space_width = Qnil;
3425 it->font_height = Qnil;
3426 it->voffset = 0;
3427
3428 /* We don't support recursive `display' properties, i.e. string
3429 values that have a string `display' property, that have a string
3430 `display' property etc. */
3431 if (!it->string_from_display_prop_p)
3432 it->area = TEXT_AREA;
3433
3434 prop = Fget_char_property (make_number (position->charpos),
3435 Qdisplay, object);
3436 if (NILP (prop))
3437 return HANDLED_NORMALLY;
3438
3439 if (CONSP (prop)
3440 /* Simple properties. */
3441 && !EQ (XCAR (prop), Qimage)
3442 && !EQ (XCAR (prop), Qspace)
3443 && !EQ (XCAR (prop), Qwhen)
3444 && !EQ (XCAR (prop), Qslice)
3445 && !EQ (XCAR (prop), Qspace_width)
3446 && !EQ (XCAR (prop), Qheight)
3447 && !EQ (XCAR (prop), Qraise)
3448 /* Marginal area specifications. */
3449 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3450 && !EQ (XCAR (prop), Qleft_fringe)
3451 && !EQ (XCAR (prop), Qright_fringe)
3452 && !NILP (XCAR (prop)))
3453 {
3454 for (; CONSP (prop); prop = XCDR (prop))
3455 {
3456 if (handle_single_display_spec (it, XCAR (prop), object,
3457 position, display_replaced_p))
3458 display_replaced_p = 1;
3459 }
3460 }
3461 else if (VECTORP (prop))
3462 {
3463 int i;
3464 for (i = 0; i < ASIZE (prop); ++i)
3465 if (handle_single_display_spec (it, AREF (prop, i), object,
3466 position, display_replaced_p))
3467 display_replaced_p = 1;
3468 }
3469 else
3470 {
3471 int ret = handle_single_display_spec (it, prop, object, position, 0);
3472 if (ret < 0) /* Replaced by "", i.e. nothing. */
3473 return HANDLED_RECOMPUTE_PROPS;
3474 if (ret)
3475 display_replaced_p = 1;
3476 }
3477
3478 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3479 }
3480
3481
3482 /* Value is the position of the end of the `display' property starting
3483 at START_POS in OBJECT. */
3484
3485 static struct text_pos
3486 display_prop_end (it, object, start_pos)
3487 struct it *it;
3488 Lisp_Object object;
3489 struct text_pos start_pos;
3490 {
3491 Lisp_Object end;
3492 struct text_pos end_pos;
3493
3494 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3495 Qdisplay, object, Qnil);
3496 CHARPOS (end_pos) = XFASTINT (end);
3497 if (STRINGP (object))
3498 compute_string_pos (&end_pos, start_pos, it->string);
3499 else
3500 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3501
3502 return end_pos;
3503 }
3504
3505
3506 /* Set up IT from a single `display' specification PROP. OBJECT
3507 is the object in which the `display' property was found. *POSITION
3508 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3509 means that we previously saw a display specification which already
3510 replaced text display with something else, for example an image;
3511 we ignore such properties after the first one has been processed.
3512
3513 If PROP is a `space' or `image' specification, and in some other
3514 cases too, set *POSITION to the position where the `display'
3515 property ends.
3516
3517 Value is non-zero if something was found which replaces the display
3518 of buffer or string text. Specifically, the value is -1 if that
3519 "something" is "nothing". */
3520
3521 static int
3522 handle_single_display_spec (it, spec, object, position,
3523 display_replaced_before_p)
3524 struct it *it;
3525 Lisp_Object spec;
3526 Lisp_Object object;
3527 struct text_pos *position;
3528 int display_replaced_before_p;
3529 {
3530 Lisp_Object form;
3531 Lisp_Object location, value;
3532 struct text_pos start_pos;
3533 int valid_p;
3534
3535 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3536 If the result is non-nil, use VALUE instead of SPEC. */
3537 form = Qt;
3538 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3539 {
3540 spec = XCDR (spec);
3541 if (!CONSP (spec))
3542 return 0;
3543 form = XCAR (spec);
3544 spec = XCDR (spec);
3545 }
3546
3547 if (!NILP (form) && !EQ (form, Qt))
3548 {
3549 int count = SPECPDL_INDEX ();
3550 struct gcpro gcpro1;
3551
3552 /* Bind `object' to the object having the `display' property, a
3553 buffer or string. Bind `position' to the position in the
3554 object where the property was found, and `buffer-position'
3555 to the current position in the buffer. */
3556 specbind (Qobject, object);
3557 specbind (Qposition, make_number (CHARPOS (*position)));
3558 specbind (Qbuffer_position,
3559 make_number (STRINGP (object)
3560 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3561 GCPRO1 (form);
3562 form = safe_eval (form);
3563 UNGCPRO;
3564 unbind_to (count, Qnil);
3565 }
3566
3567 if (NILP (form))
3568 return 0;
3569
3570 /* Handle `(height HEIGHT)' specifications. */
3571 if (CONSP (spec)
3572 && EQ (XCAR (spec), Qheight)
3573 && CONSP (XCDR (spec)))
3574 {
3575 if (!FRAME_WINDOW_P (it->f))
3576 return 0;
3577
3578 it->font_height = XCAR (XCDR (spec));
3579 if (!NILP (it->font_height))
3580 {
3581 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3582 int new_height = -1;
3583
3584 if (CONSP (it->font_height)
3585 && (EQ (XCAR (it->font_height), Qplus)
3586 || EQ (XCAR (it->font_height), Qminus))
3587 && CONSP (XCDR (it->font_height))
3588 && INTEGERP (XCAR (XCDR (it->font_height))))
3589 {
3590 /* `(+ N)' or `(- N)' where N is an integer. */
3591 int steps = XINT (XCAR (XCDR (it->font_height)));
3592 if (EQ (XCAR (it->font_height), Qplus))
3593 steps = - steps;
3594 it->face_id = smaller_face (it->f, it->face_id, steps);
3595 }
3596 else if (FUNCTIONP (it->font_height))
3597 {
3598 /* Call function with current height as argument.
3599 Value is the new height. */
3600 Lisp_Object height;
3601 height = safe_call1 (it->font_height,
3602 face->lface[LFACE_HEIGHT_INDEX]);
3603 if (NUMBERP (height))
3604 new_height = XFLOATINT (height);
3605 }
3606 else if (NUMBERP (it->font_height))
3607 {
3608 /* Value is a multiple of the canonical char height. */
3609 struct face *face;
3610
3611 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3612 new_height = (XFLOATINT (it->font_height)
3613 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3614 }
3615 else
3616 {
3617 /* Evaluate IT->font_height with `height' bound to the
3618 current specified height to get the new height. */
3619 int count = SPECPDL_INDEX ();
3620
3621 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3622 value = safe_eval (it->font_height);
3623 unbind_to (count, Qnil);
3624
3625 if (NUMBERP (value))
3626 new_height = XFLOATINT (value);
3627 }
3628
3629 if (new_height > 0)
3630 it->face_id = face_with_height (it->f, it->face_id, new_height);
3631 }
3632
3633 return 0;
3634 }
3635
3636 /* Handle `(space_width WIDTH)'. */
3637 if (CONSP (spec)
3638 && EQ (XCAR (spec), Qspace_width)
3639 && CONSP (XCDR (spec)))
3640 {
3641 if (!FRAME_WINDOW_P (it->f))
3642 return 0;
3643
3644 value = XCAR (XCDR (spec));
3645 if (NUMBERP (value) && XFLOATINT (value) > 0)
3646 it->space_width = value;
3647
3648 return 0;
3649 }
3650
3651 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3652 if (CONSP (spec)
3653 && EQ (XCAR (spec), Qslice))
3654 {
3655 Lisp_Object tem;
3656
3657 if (!FRAME_WINDOW_P (it->f))
3658 return 0;
3659
3660 if (tem = XCDR (spec), CONSP (tem))
3661 {
3662 it->slice.x = XCAR (tem);
3663 if (tem = XCDR (tem), CONSP (tem))
3664 {
3665 it->slice.y = XCAR (tem);
3666 if (tem = XCDR (tem), CONSP (tem))
3667 {
3668 it->slice.width = XCAR (tem);
3669 if (tem = XCDR (tem), CONSP (tem))
3670 it->slice.height = XCAR (tem);
3671 }
3672 }
3673 }
3674
3675 return 0;
3676 }
3677
3678 /* Handle `(raise FACTOR)'. */
3679 if (CONSP (spec)
3680 && EQ (XCAR (spec), Qraise)
3681 && CONSP (XCDR (spec)))
3682 {
3683 if (!FRAME_WINDOW_P (it->f))
3684 return 0;
3685
3686 #ifdef HAVE_WINDOW_SYSTEM
3687 value = XCAR (XCDR (spec));
3688 if (NUMBERP (value))
3689 {
3690 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3691 it->voffset = - (XFLOATINT (value)
3692 * (FONT_HEIGHT (face->font)));
3693 }
3694 #endif /* HAVE_WINDOW_SYSTEM */
3695
3696 return 0;
3697 }
3698
3699 /* Don't handle the other kinds of display specifications
3700 inside a string that we got from a `display' property. */
3701 if (it->string_from_display_prop_p)
3702 return 0;
3703
3704 /* Characters having this form of property are not displayed, so
3705 we have to find the end of the property. */
3706 start_pos = *position;
3707 *position = display_prop_end (it, object, start_pos);
3708 value = Qnil;
3709
3710 /* Stop the scan at that end position--we assume that all
3711 text properties change there. */
3712 it->stop_charpos = position->charpos;
3713
3714 /* Handle `(left-fringe BITMAP [FACE])'
3715 and `(right-fringe BITMAP [FACE])'. */
3716 if (CONSP (spec)
3717 && (EQ (XCAR (spec), Qleft_fringe)
3718 || EQ (XCAR (spec), Qright_fringe))
3719 && CONSP (XCDR (spec)))
3720 {
3721 int face_id = DEFAULT_FACE_ID;
3722 int fringe_bitmap;
3723
3724 if (!FRAME_WINDOW_P (it->f))
3725 /* If we return here, POSITION has been advanced
3726 across the text with this property. */
3727 return 0;
3728
3729 #ifdef HAVE_WINDOW_SYSTEM
3730 value = XCAR (XCDR (spec));
3731 if (!SYMBOLP (value)
3732 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3733 /* If we return here, POSITION has been advanced
3734 across the text with this property. */
3735 return 0;
3736
3737 if (CONSP (XCDR (XCDR (spec))))
3738 {
3739 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
3740 int face_id2 = lookup_derived_face (it->f, face_name,
3741 'A', FRINGE_FACE_ID, 0);
3742 if (face_id2 >= 0)
3743 face_id = face_id2;
3744 }
3745
3746 /* Save current settings of IT so that we can restore them
3747 when we are finished with the glyph property value. */
3748
3749 push_it (it);
3750
3751 it->area = TEXT_AREA;
3752 it->what = IT_IMAGE;
3753 it->image_id = -1; /* no image */
3754 it->position = start_pos;
3755 it->object = NILP (object) ? it->w->buffer : object;
3756 it->method = GET_FROM_IMAGE;
3757 it->face_id = face_id;
3758
3759 /* Say that we haven't consumed the characters with
3760 `display' property yet. The call to pop_it in
3761 set_iterator_to_next will clean this up. */
3762 *position = start_pos;
3763
3764 if (EQ (XCAR (spec), Qleft_fringe))
3765 {
3766 it->left_user_fringe_bitmap = fringe_bitmap;
3767 it->left_user_fringe_face_id = face_id;
3768 }
3769 else
3770 {
3771 it->right_user_fringe_bitmap = fringe_bitmap;
3772 it->right_user_fringe_face_id = face_id;
3773 }
3774 #endif /* HAVE_WINDOW_SYSTEM */
3775 return 1;
3776 }
3777
3778 /* Prepare to handle `((margin left-margin) ...)',
3779 `((margin right-margin) ...)' and `((margin nil) ...)'
3780 prefixes for display specifications. */
3781 location = Qunbound;
3782 if (CONSP (spec) && CONSP (XCAR (spec)))
3783 {
3784 Lisp_Object tem;
3785
3786 value = XCDR (spec);
3787 if (CONSP (value))
3788 value = XCAR (value);
3789
3790 tem = XCAR (spec);
3791 if (EQ (XCAR (tem), Qmargin)
3792 && (tem = XCDR (tem),
3793 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3794 (NILP (tem)
3795 || EQ (tem, Qleft_margin)
3796 || EQ (tem, Qright_margin))))
3797 location = tem;
3798 }
3799
3800 if (EQ (location, Qunbound))
3801 {
3802 location = Qnil;
3803 value = spec;
3804 }
3805
3806 /* After this point, VALUE is the property after any
3807 margin prefix has been stripped. It must be a string,
3808 an image specification, or `(space ...)'.
3809
3810 LOCATION specifies where to display: `left-margin',
3811 `right-margin' or nil. */
3812
3813 valid_p = (STRINGP (value)
3814 #ifdef HAVE_WINDOW_SYSTEM
3815 || (FRAME_WINDOW_P (it->f) && valid_image_p (value))
3816 #endif /* not HAVE_WINDOW_SYSTEM */
3817 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3818
3819 if (valid_p && !display_replaced_before_p)
3820 {
3821 /* Save current settings of IT so that we can restore them
3822 when we are finished with the glyph property value. */
3823 push_it (it);
3824 if (NILP (location))
3825 it->area = TEXT_AREA;
3826 else if (EQ (location, Qleft_margin))
3827 it->area = LEFT_MARGIN_AREA;
3828 else
3829 it->area = RIGHT_MARGIN_AREA;
3830
3831 if (STRINGP (value))
3832 {
3833 if (SCHARS (value) == 0)
3834 {
3835 pop_it (it);
3836 return -1; /* Replaced by "", i.e. nothing. */
3837 }
3838 it->string = value;
3839 it->multibyte_p = STRING_MULTIBYTE (it->string);
3840 it->current.overlay_string_index = -1;
3841 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3842 it->end_charpos = it->string_nchars = SCHARS (it->string);
3843 it->method = GET_FROM_STRING;
3844 it->stop_charpos = 0;
3845 it->string_from_display_prop_p = 1;
3846 /* Say that we haven't consumed the characters with
3847 `display' property yet. The call to pop_it in
3848 set_iterator_to_next will clean this up. */
3849 *position = start_pos;
3850 }
3851 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3852 {
3853 it->method = GET_FROM_STRETCH;
3854 it->object = value;
3855 it->current.pos = it->position = start_pos;
3856
3857 }
3858 #ifdef HAVE_WINDOW_SYSTEM
3859 else
3860 {
3861 it->what = IT_IMAGE;
3862 it->image_id = lookup_image (it->f, value);
3863 it->position = start_pos;
3864 it->object = NILP (object) ? it->w->buffer : object;
3865 it->method = GET_FROM_IMAGE;
3866
3867 /* Say that we haven't consumed the characters with
3868 `display' property yet. The call to pop_it in
3869 set_iterator_to_next will clean this up. */
3870 *position = start_pos;
3871 }
3872 #endif /* HAVE_WINDOW_SYSTEM */
3873
3874 return 1;
3875 }
3876
3877 /* Invalid property or property not supported. Restore
3878 POSITION to what it was before. */
3879 *position = start_pos;
3880 return 0;
3881 }
3882
3883
3884 /* Check if SPEC is a display sub-property value whose text should be
3885 treated as intangible. */
3886
3887 static int
3888 single_display_spec_intangible_p (prop)
3889 Lisp_Object prop;
3890 {
3891 /* Skip over `when FORM'. */
3892 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3893 {
3894 prop = XCDR (prop);
3895 if (!CONSP (prop))
3896 return 0;
3897 prop = XCDR (prop);
3898 }
3899
3900 if (STRINGP (prop))
3901 return 1;
3902
3903 if (!CONSP (prop))
3904 return 0;
3905
3906 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3907 we don't need to treat text as intangible. */
3908 if (EQ (XCAR (prop), Qmargin))
3909 {
3910 prop = XCDR (prop);
3911 if (!CONSP (prop))
3912 return 0;
3913
3914 prop = XCDR (prop);
3915 if (!CONSP (prop)
3916 || EQ (XCAR (prop), Qleft_margin)
3917 || EQ (XCAR (prop), Qright_margin))
3918 return 0;
3919 }
3920
3921 return (CONSP (prop)
3922 && (EQ (XCAR (prop), Qimage)
3923 || EQ (XCAR (prop), Qspace)));
3924 }
3925
3926
3927 /* Check if PROP is a display property value whose text should be
3928 treated as intangible. */
3929
3930 int
3931 display_prop_intangible_p (prop)
3932 Lisp_Object prop;
3933 {
3934 if (CONSP (prop)
3935 && CONSP (XCAR (prop))
3936 && !EQ (Qmargin, XCAR (XCAR (prop))))
3937 {
3938 /* A list of sub-properties. */
3939 while (CONSP (prop))
3940 {
3941 if (single_display_spec_intangible_p (XCAR (prop)))
3942 return 1;
3943 prop = XCDR (prop);
3944 }
3945 }
3946 else if (VECTORP (prop))
3947 {
3948 /* A vector of sub-properties. */
3949 int i;
3950 for (i = 0; i < ASIZE (prop); ++i)
3951 if (single_display_spec_intangible_p (AREF (prop, i)))
3952 return 1;
3953 }
3954 else
3955 return single_display_spec_intangible_p (prop);
3956
3957 return 0;
3958 }
3959
3960
3961 /* Return 1 if PROP is a display sub-property value containing STRING. */
3962
3963 static int
3964 single_display_spec_string_p (prop, string)
3965 Lisp_Object prop, string;
3966 {
3967 if (EQ (string, prop))
3968 return 1;
3969
3970 /* Skip over `when FORM'. */
3971 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3972 {
3973 prop = XCDR (prop);
3974 if (!CONSP (prop))
3975 return 0;
3976 prop = XCDR (prop);
3977 }
3978
3979 if (CONSP (prop))
3980 /* Skip over `margin LOCATION'. */
3981 if (EQ (XCAR (prop), Qmargin))
3982 {
3983 prop = XCDR (prop);
3984 if (!CONSP (prop))
3985 return 0;
3986
3987 prop = XCDR (prop);
3988 if (!CONSP (prop))
3989 return 0;
3990 }
3991
3992 return CONSP (prop) && EQ (XCAR (prop), string);
3993 }
3994
3995
3996 /* Return 1 if STRING appears in the `display' property PROP. */
3997
3998 static int
3999 display_prop_string_p (prop, string)
4000 Lisp_Object prop, string;
4001 {
4002 if (CONSP (prop)
4003 && CONSP (XCAR (prop))
4004 && !EQ (Qmargin, XCAR (XCAR (prop))))
4005 {
4006 /* A list of sub-properties. */
4007 while (CONSP (prop))
4008 {
4009 if (single_display_spec_string_p (XCAR (prop), string))
4010 return 1;
4011 prop = XCDR (prop);
4012 }
4013 }
4014 else if (VECTORP (prop))
4015 {
4016 /* A vector of sub-properties. */
4017 int i;
4018 for (i = 0; i < ASIZE (prop); ++i)
4019 if (single_display_spec_string_p (AREF (prop, i), string))
4020 return 1;
4021 }
4022 else
4023 return single_display_spec_string_p (prop, string);
4024
4025 return 0;
4026 }
4027
4028
4029 /* Determine from which buffer position in W's buffer STRING comes
4030 from. AROUND_CHARPOS is an approximate position where it could
4031 be from. Value is the buffer position or 0 if it couldn't be
4032 determined.
4033
4034 W's buffer must be current.
4035
4036 This function is necessary because we don't record buffer positions
4037 in glyphs generated from strings (to keep struct glyph small).
4038 This function may only use code that doesn't eval because it is
4039 called asynchronously from note_mouse_highlight. */
4040
4041 int
4042 string_buffer_position (w, string, around_charpos)
4043 struct window *w;
4044 Lisp_Object string;
4045 int around_charpos;
4046 {
4047 Lisp_Object limit, prop, pos;
4048 const int MAX_DISTANCE = 1000;
4049 int found = 0;
4050
4051 pos = make_number (around_charpos);
4052 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4053 while (!found && !EQ (pos, limit))
4054 {
4055 prop = Fget_char_property (pos, Qdisplay, Qnil);
4056 if (!NILP (prop) && display_prop_string_p (prop, string))
4057 found = 1;
4058 else
4059 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4060 }
4061
4062 if (!found)
4063 {
4064 pos = make_number (around_charpos);
4065 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4066 while (!found && !EQ (pos, limit))
4067 {
4068 prop = Fget_char_property (pos, Qdisplay, Qnil);
4069 if (!NILP (prop) && display_prop_string_p (prop, string))
4070 found = 1;
4071 else
4072 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4073 limit);
4074 }
4075 }
4076
4077 return found ? XINT (pos) : 0;
4078 }
4079
4080
4081 \f
4082 /***********************************************************************
4083 `composition' property
4084 ***********************************************************************/
4085
4086 /* Set up iterator IT from `composition' property at its current
4087 position. Called from handle_stop. */
4088
4089 static enum prop_handled
4090 handle_composition_prop (it)
4091 struct it *it;
4092 {
4093 Lisp_Object prop, string;
4094 int pos, pos_byte, end;
4095 enum prop_handled handled = HANDLED_NORMALLY;
4096
4097 if (STRINGP (it->string))
4098 {
4099 pos = IT_STRING_CHARPOS (*it);
4100 pos_byte = IT_STRING_BYTEPOS (*it);
4101 string = it->string;
4102 }
4103 else
4104 {
4105 pos = IT_CHARPOS (*it);
4106 pos_byte = IT_BYTEPOS (*it);
4107 string = Qnil;
4108 }
4109
4110 /* If there's a valid composition and point is not inside of the
4111 composition (in the case that the composition is from the current
4112 buffer), draw a glyph composed from the composition components. */
4113 if (find_composition (pos, -1, &pos, &end, &prop, string)
4114 && COMPOSITION_VALID_P (pos, end, prop)
4115 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4116 {
4117 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4118
4119 if (id >= 0)
4120 {
4121 it->method = GET_FROM_COMPOSITION;
4122 it->cmp_id = id;
4123 it->cmp_len = COMPOSITION_LENGTH (prop);
4124 /* For a terminal, draw only the first character of the
4125 components. */
4126 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4127 it->len = (STRINGP (it->string)
4128 ? string_char_to_byte (it->string, end)
4129 : CHAR_TO_BYTE (end)) - pos_byte;
4130 it->stop_charpos = end;
4131 handled = HANDLED_RETURN;
4132 }
4133 }
4134
4135 return handled;
4136 }
4137
4138
4139 \f
4140 /***********************************************************************
4141 Overlay strings
4142 ***********************************************************************/
4143
4144 /* The following structure is used to record overlay strings for
4145 later sorting in load_overlay_strings. */
4146
4147 struct overlay_entry
4148 {
4149 Lisp_Object overlay;
4150 Lisp_Object string;
4151 int priority;
4152 int after_string_p;
4153 };
4154
4155
4156 /* Set up iterator IT from overlay strings at its current position.
4157 Called from handle_stop. */
4158
4159 static enum prop_handled
4160 handle_overlay_change (it)
4161 struct it *it;
4162 {
4163 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4164 return HANDLED_RECOMPUTE_PROPS;
4165 else
4166 return HANDLED_NORMALLY;
4167 }
4168
4169
4170 /* Set up the next overlay string for delivery by IT, if there is an
4171 overlay string to deliver. Called by set_iterator_to_next when the
4172 end of the current overlay string is reached. If there are more
4173 overlay strings to display, IT->string and
4174 IT->current.overlay_string_index are set appropriately here.
4175 Otherwise IT->string is set to nil. */
4176
4177 static void
4178 next_overlay_string (it)
4179 struct it *it;
4180 {
4181 ++it->current.overlay_string_index;
4182 if (it->current.overlay_string_index == it->n_overlay_strings)
4183 {
4184 /* No more overlay strings. Restore IT's settings to what
4185 they were before overlay strings were processed, and
4186 continue to deliver from current_buffer. */
4187 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4188
4189 pop_it (it);
4190 xassert (it->stop_charpos >= BEGV
4191 && it->stop_charpos <= it->end_charpos);
4192 it->string = Qnil;
4193 it->current.overlay_string_index = -1;
4194 SET_TEXT_POS (it->current.string_pos, -1, -1);
4195 it->n_overlay_strings = 0;
4196 it->method = GET_FROM_BUFFER;
4197
4198 /* If we're at the end of the buffer, record that we have
4199 processed the overlay strings there already, so that
4200 next_element_from_buffer doesn't try it again. */
4201 if (IT_CHARPOS (*it) >= it->end_charpos)
4202 it->overlay_strings_at_end_processed_p = 1;
4203
4204 /* If we have to display `...' for invisible text, set
4205 the iterator up for that. */
4206 if (display_ellipsis_p)
4207 setup_for_ellipsis (it, 0);
4208 }
4209 else
4210 {
4211 /* There are more overlay strings to process. If
4212 IT->current.overlay_string_index has advanced to a position
4213 where we must load IT->overlay_strings with more strings, do
4214 it. */
4215 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4216
4217 if (it->current.overlay_string_index && i == 0)
4218 load_overlay_strings (it, 0);
4219
4220 /* Initialize IT to deliver display elements from the overlay
4221 string. */
4222 it->string = it->overlay_strings[i];
4223 it->multibyte_p = STRING_MULTIBYTE (it->string);
4224 SET_TEXT_POS (it->current.string_pos, 0, 0);
4225 it->method = GET_FROM_STRING;
4226 it->stop_charpos = 0;
4227 }
4228
4229 CHECK_IT (it);
4230 }
4231
4232
4233 /* Compare two overlay_entry structures E1 and E2. Used as a
4234 comparison function for qsort in load_overlay_strings. Overlay
4235 strings for the same position are sorted so that
4236
4237 1. All after-strings come in front of before-strings, except
4238 when they come from the same overlay.
4239
4240 2. Within after-strings, strings are sorted so that overlay strings
4241 from overlays with higher priorities come first.
4242
4243 2. Within before-strings, strings are sorted so that overlay
4244 strings from overlays with higher priorities come last.
4245
4246 Value is analogous to strcmp. */
4247
4248
4249 static int
4250 compare_overlay_entries (e1, e2)
4251 void *e1, *e2;
4252 {
4253 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4254 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4255 int result;
4256
4257 if (entry1->after_string_p != entry2->after_string_p)
4258 {
4259 /* Let after-strings appear in front of before-strings if
4260 they come from different overlays. */
4261 if (EQ (entry1->overlay, entry2->overlay))
4262 result = entry1->after_string_p ? 1 : -1;
4263 else
4264 result = entry1->after_string_p ? -1 : 1;
4265 }
4266 else if (entry1->after_string_p)
4267 /* After-strings sorted in order of decreasing priority. */
4268 result = entry2->priority - entry1->priority;
4269 else
4270 /* Before-strings sorted in order of increasing priority. */
4271 result = entry1->priority - entry2->priority;
4272
4273 return result;
4274 }
4275
4276
4277 /* Load the vector IT->overlay_strings with overlay strings from IT's
4278 current buffer position, or from CHARPOS if that is > 0. Set
4279 IT->n_overlays to the total number of overlay strings found.
4280
4281 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4282 a time. On entry into load_overlay_strings,
4283 IT->current.overlay_string_index gives the number of overlay
4284 strings that have already been loaded by previous calls to this
4285 function.
4286
4287 IT->add_overlay_start contains an additional overlay start
4288 position to consider for taking overlay strings from, if non-zero.
4289 This position comes into play when the overlay has an `invisible'
4290 property, and both before and after-strings. When we've skipped to
4291 the end of the overlay, because of its `invisible' property, we
4292 nevertheless want its before-string to appear.
4293 IT->add_overlay_start will contain the overlay start position
4294 in this case.
4295
4296 Overlay strings are sorted so that after-string strings come in
4297 front of before-string strings. Within before and after-strings,
4298 strings are sorted by overlay priority. See also function
4299 compare_overlay_entries. */
4300
4301 static void
4302 load_overlay_strings (it, charpos)
4303 struct it *it;
4304 int charpos;
4305 {
4306 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4307 Lisp_Object overlay, window, str, invisible;
4308 struct Lisp_Overlay *ov;
4309 int start, end;
4310 int size = 20;
4311 int n = 0, i, j, invis_p;
4312 struct overlay_entry *entries
4313 = (struct overlay_entry *) alloca (size * sizeof *entries);
4314
4315 if (charpos <= 0)
4316 charpos = IT_CHARPOS (*it);
4317
4318 /* Append the overlay string STRING of overlay OVERLAY to vector
4319 `entries' which has size `size' and currently contains `n'
4320 elements. AFTER_P non-zero means STRING is an after-string of
4321 OVERLAY. */
4322 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4323 do \
4324 { \
4325 Lisp_Object priority; \
4326 \
4327 if (n == size) \
4328 { \
4329 int new_size = 2 * size; \
4330 struct overlay_entry *old = entries; \
4331 entries = \
4332 (struct overlay_entry *) alloca (new_size \
4333 * sizeof *entries); \
4334 bcopy (old, entries, size * sizeof *entries); \
4335 size = new_size; \
4336 } \
4337 \
4338 entries[n].string = (STRING); \
4339 entries[n].overlay = (OVERLAY); \
4340 priority = Foverlay_get ((OVERLAY), Qpriority); \
4341 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4342 entries[n].after_string_p = (AFTER_P); \
4343 ++n; \
4344 } \
4345 while (0)
4346
4347 /* Process overlay before the overlay center. */
4348 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4349 {
4350 XSETMISC (overlay, ov);
4351 xassert (OVERLAYP (overlay));
4352 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4353 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4354
4355 if (end < charpos)
4356 break;
4357
4358 /* Skip this overlay if it doesn't start or end at IT's current
4359 position. */
4360 if (end != charpos && start != charpos)
4361 continue;
4362
4363 /* Skip this overlay if it doesn't apply to IT->w. */
4364 window = Foverlay_get (overlay, Qwindow);
4365 if (WINDOWP (window) && XWINDOW (window) != it->w)
4366 continue;
4367
4368 /* If the text ``under'' the overlay is invisible, both before-
4369 and after-strings from this overlay are visible; start and
4370 end position are indistinguishable. */
4371 invisible = Foverlay_get (overlay, Qinvisible);
4372 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4373
4374 /* If overlay has a non-empty before-string, record it. */
4375 if ((start == charpos || (end == charpos && invis_p))
4376 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4377 && SCHARS (str))
4378 RECORD_OVERLAY_STRING (overlay, str, 0);
4379
4380 /* If overlay has a non-empty after-string, record it. */
4381 if ((end == charpos || (start == charpos && invis_p))
4382 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4383 && SCHARS (str))
4384 RECORD_OVERLAY_STRING (overlay, str, 1);
4385 }
4386
4387 /* Process overlays after the overlay center. */
4388 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4389 {
4390 XSETMISC (overlay, ov);
4391 xassert (OVERLAYP (overlay));
4392 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4393 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4394
4395 if (start > charpos)
4396 break;
4397
4398 /* Skip this overlay if it doesn't start or end at IT's current
4399 position. */
4400 if (end != charpos && start != charpos)
4401 continue;
4402
4403 /* Skip this overlay if it doesn't apply to IT->w. */
4404 window = Foverlay_get (overlay, Qwindow);
4405 if (WINDOWP (window) && XWINDOW (window) != it->w)
4406 continue;
4407
4408 /* If the text ``under'' the overlay is invisible, it has a zero
4409 dimension, and both before- and after-strings apply. */
4410 invisible = Foverlay_get (overlay, Qinvisible);
4411 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4412
4413 /* If overlay has a non-empty before-string, record it. */
4414 if ((start == charpos || (end == charpos && invis_p))
4415 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4416 && SCHARS (str))
4417 RECORD_OVERLAY_STRING (overlay, str, 0);
4418
4419 /* If overlay has a non-empty after-string, record it. */
4420 if ((end == charpos || (start == charpos && invis_p))
4421 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4422 && SCHARS (str))
4423 RECORD_OVERLAY_STRING (overlay, str, 1);
4424 }
4425
4426 #undef RECORD_OVERLAY_STRING
4427
4428 /* Sort entries. */
4429 if (n > 1)
4430 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4431
4432 /* Record the total number of strings to process. */
4433 it->n_overlay_strings = n;
4434
4435 /* IT->current.overlay_string_index is the number of overlay strings
4436 that have already been consumed by IT. Copy some of the
4437 remaining overlay strings to IT->overlay_strings. */
4438 i = 0;
4439 j = it->current.overlay_string_index;
4440 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4441 it->overlay_strings[i++] = entries[j++].string;
4442
4443 CHECK_IT (it);
4444 }
4445
4446
4447 /* Get the first chunk of overlay strings at IT's current buffer
4448 position, or at CHARPOS if that is > 0. Value is non-zero if at
4449 least one overlay string was found. */
4450
4451 static int
4452 get_overlay_strings (it, charpos)
4453 struct it *it;
4454 int charpos;
4455 {
4456 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4457 process. This fills IT->overlay_strings with strings, and sets
4458 IT->n_overlay_strings to the total number of strings to process.
4459 IT->pos.overlay_string_index has to be set temporarily to zero
4460 because load_overlay_strings needs this; it must be set to -1
4461 when no overlay strings are found because a zero value would
4462 indicate a position in the first overlay string. */
4463 it->current.overlay_string_index = 0;
4464 load_overlay_strings (it, charpos);
4465
4466 /* If we found overlay strings, set up IT to deliver display
4467 elements from the first one. Otherwise set up IT to deliver
4468 from current_buffer. */
4469 if (it->n_overlay_strings)
4470 {
4471 /* Make sure we know settings in current_buffer, so that we can
4472 restore meaningful values when we're done with the overlay
4473 strings. */
4474 compute_stop_pos (it);
4475 xassert (it->face_id >= 0);
4476
4477 /* Save IT's settings. They are restored after all overlay
4478 strings have been processed. */
4479 xassert (it->sp == 0);
4480 push_it (it);
4481
4482 /* Set up IT to deliver display elements from the first overlay
4483 string. */
4484 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4485 it->string = it->overlay_strings[0];
4486 it->stop_charpos = 0;
4487 xassert (STRINGP (it->string));
4488 it->end_charpos = SCHARS (it->string);
4489 it->multibyte_p = STRING_MULTIBYTE (it->string);
4490 it->method = GET_FROM_STRING;
4491 }
4492 else
4493 {
4494 it->string = Qnil;
4495 it->current.overlay_string_index = -1;
4496 it->method = GET_FROM_BUFFER;
4497 }
4498
4499 CHECK_IT (it);
4500
4501 /* Value is non-zero if we found at least one overlay string. */
4502 return STRINGP (it->string);
4503 }
4504
4505
4506 \f
4507 /***********************************************************************
4508 Saving and restoring state
4509 ***********************************************************************/
4510
4511 /* Save current settings of IT on IT->stack. Called, for example,
4512 before setting up IT for an overlay string, to be able to restore
4513 IT's settings to what they were after the overlay string has been
4514 processed. */
4515
4516 static void
4517 push_it (it)
4518 struct it *it;
4519 {
4520 struct iterator_stack_entry *p;
4521
4522 xassert (it->sp < 2);
4523 p = it->stack + it->sp;
4524
4525 p->stop_charpos = it->stop_charpos;
4526 xassert (it->face_id >= 0);
4527 p->face_id = it->face_id;
4528 p->string = it->string;
4529 p->pos = it->current;
4530 p->end_charpos = it->end_charpos;
4531 p->string_nchars = it->string_nchars;
4532 p->area = it->area;
4533 p->multibyte_p = it->multibyte_p;
4534 p->slice = it->slice;
4535 p->space_width = it->space_width;
4536 p->font_height = it->font_height;
4537 p->voffset = it->voffset;
4538 p->string_from_display_prop_p = it->string_from_display_prop_p;
4539 p->display_ellipsis_p = 0;
4540 ++it->sp;
4541 }
4542
4543
4544 /* Restore IT's settings from IT->stack. Called, for example, when no
4545 more overlay strings must be processed, and we return to delivering
4546 display elements from a buffer, or when the end of a string from a
4547 `display' property is reached and we return to delivering display
4548 elements from an overlay string, or from a buffer. */
4549
4550 static void
4551 pop_it (it)
4552 struct it *it;
4553 {
4554 struct iterator_stack_entry *p;
4555
4556 xassert (it->sp > 0);
4557 --it->sp;
4558 p = it->stack + it->sp;
4559 it->stop_charpos = p->stop_charpos;
4560 it->face_id = p->face_id;
4561 it->string = p->string;
4562 it->current = p->pos;
4563 it->end_charpos = p->end_charpos;
4564 it->string_nchars = p->string_nchars;
4565 it->area = p->area;
4566 it->multibyte_p = p->multibyte_p;
4567 it->slice = p->slice;
4568 it->space_width = p->space_width;
4569 it->font_height = p->font_height;
4570 it->voffset = p->voffset;
4571 it->string_from_display_prop_p = p->string_from_display_prop_p;
4572 }
4573
4574
4575 \f
4576 /***********************************************************************
4577 Moving over lines
4578 ***********************************************************************/
4579
4580 /* Set IT's current position to the previous line start. */
4581
4582 static void
4583 back_to_previous_line_start (it)
4584 struct it *it;
4585 {
4586 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4587 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4588 }
4589
4590
4591 /* Move IT to the next line start.
4592
4593 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4594 we skipped over part of the text (as opposed to moving the iterator
4595 continuously over the text). Otherwise, don't change the value
4596 of *SKIPPED_P.
4597
4598 Newlines may come from buffer text, overlay strings, or strings
4599 displayed via the `display' property. That's the reason we can't
4600 simply use find_next_newline_no_quit.
4601
4602 Note that this function may not skip over invisible text that is so
4603 because of text properties and immediately follows a newline. If
4604 it would, function reseat_at_next_visible_line_start, when called
4605 from set_iterator_to_next, would effectively make invisible
4606 characters following a newline part of the wrong glyph row, which
4607 leads to wrong cursor motion. */
4608
4609 static int
4610 forward_to_next_line_start (it, skipped_p)
4611 struct it *it;
4612 int *skipped_p;
4613 {
4614 int old_selective, newline_found_p, n;
4615 const int MAX_NEWLINE_DISTANCE = 500;
4616
4617 /* If already on a newline, just consume it to avoid unintended
4618 skipping over invisible text below. */
4619 if (it->what == IT_CHARACTER
4620 && it->c == '\n'
4621 && CHARPOS (it->position) == IT_CHARPOS (*it))
4622 {
4623 set_iterator_to_next (it, 0);
4624 it->c = 0;
4625 return 1;
4626 }
4627
4628 /* Don't handle selective display in the following. It's (a)
4629 unnecessary because it's done by the caller, and (b) leads to an
4630 infinite recursion because next_element_from_ellipsis indirectly
4631 calls this function. */
4632 old_selective = it->selective;
4633 it->selective = 0;
4634
4635 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4636 from buffer text. */
4637 for (n = newline_found_p = 0;
4638 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4639 n += STRINGP (it->string) ? 0 : 1)
4640 {
4641 if (!get_next_display_element (it))
4642 return 0;
4643 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4644 set_iterator_to_next (it, 0);
4645 }
4646
4647 /* If we didn't find a newline near enough, see if we can use a
4648 short-cut. */
4649 if (!newline_found_p)
4650 {
4651 int start = IT_CHARPOS (*it);
4652 int limit = find_next_newline_no_quit (start, 1);
4653 Lisp_Object pos;
4654
4655 xassert (!STRINGP (it->string));
4656
4657 /* If there isn't any `display' property in sight, and no
4658 overlays, we can just use the position of the newline in
4659 buffer text. */
4660 if (it->stop_charpos >= limit
4661 || ((pos = Fnext_single_property_change (make_number (start),
4662 Qdisplay,
4663 Qnil, make_number (limit)),
4664 NILP (pos))
4665 && next_overlay_change (start) == ZV))
4666 {
4667 IT_CHARPOS (*it) = limit;
4668 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4669 *skipped_p = newline_found_p = 1;
4670 }
4671 else
4672 {
4673 while (get_next_display_element (it)
4674 && !newline_found_p)
4675 {
4676 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4677 set_iterator_to_next (it, 0);
4678 }
4679 }
4680 }
4681
4682 it->selective = old_selective;
4683 return newline_found_p;
4684 }
4685
4686
4687 /* Set IT's current position to the previous visible line start. Skip
4688 invisible text that is so either due to text properties or due to
4689 selective display. Caution: this does not change IT->current_x and
4690 IT->hpos. */
4691
4692 static void
4693 back_to_previous_visible_line_start (it)
4694 struct it *it;
4695 {
4696 while (IT_CHARPOS (*it) > BEGV)
4697 {
4698 back_to_previous_line_start (it);
4699 if (IT_CHARPOS (*it) <= BEGV)
4700 break;
4701
4702 /* If selective > 0, then lines indented more than that values
4703 are invisible. */
4704 if (it->selective > 0
4705 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4706 (double) it->selective)) /* iftc */
4707 continue;
4708
4709 /* Check the newline before point for invisibility. */
4710 {
4711 Lisp_Object prop;
4712 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4713 Qinvisible, it->window);
4714 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4715 continue;
4716 }
4717
4718 /* If newline has a display property that replaces the newline with something
4719 else (image or text), find start of overlay or interval and continue search
4720 from that point. */
4721 if (IT_CHARPOS (*it) > BEGV)
4722 {
4723 struct it it2 = *it;
4724 int pos;
4725 int beg, end;
4726 Lisp_Object val, overlay;
4727
4728 pos = --IT_CHARPOS (it2);
4729 --IT_BYTEPOS (it2);
4730 it2.sp = 0;
4731 if (handle_display_prop (&it2) == HANDLED_RETURN
4732 && !NILP (val = get_char_property_and_overlay
4733 (make_number (pos), Qdisplay, Qnil, &overlay))
4734 && (OVERLAYP (overlay)
4735 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
4736 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
4737 {
4738 if (beg < BEGV)
4739 beg = BEGV;
4740 IT_CHARPOS (*it) = beg;
4741 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
4742 continue;
4743 }
4744 }
4745
4746 break;
4747 }
4748
4749 xassert (IT_CHARPOS (*it) >= BEGV);
4750 xassert (IT_CHARPOS (*it) == BEGV
4751 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4752 CHECK_IT (it);
4753 }
4754
4755
4756 /* Reseat iterator IT at the previous visible line start. Skip
4757 invisible text that is so either due to text properties or due to
4758 selective display. At the end, update IT's overlay information,
4759 face information etc. */
4760
4761 void
4762 reseat_at_previous_visible_line_start (it)
4763 struct it *it;
4764 {
4765 back_to_previous_visible_line_start (it);
4766 reseat (it, it->current.pos, 1);
4767 CHECK_IT (it);
4768 }
4769
4770
4771 /* Reseat iterator IT on the next visible line start in the current
4772 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4773 preceding the line start. Skip over invisible text that is so
4774 because of selective display. Compute faces, overlays etc at the
4775 new position. Note that this function does not skip over text that
4776 is invisible because of text properties. */
4777
4778 static void
4779 reseat_at_next_visible_line_start (it, on_newline_p)
4780 struct it *it;
4781 int on_newline_p;
4782 {
4783 int newline_found_p, skipped_p = 0;
4784
4785 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4786
4787 /* Skip over lines that are invisible because they are indented
4788 more than the value of IT->selective. */
4789 if (it->selective > 0)
4790 while (IT_CHARPOS (*it) < ZV
4791 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4792 (double) it->selective)) /* iftc */
4793 {
4794 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4795 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4796 }
4797
4798 /* Position on the newline if that's what's requested. */
4799 if (on_newline_p && newline_found_p)
4800 {
4801 if (STRINGP (it->string))
4802 {
4803 if (IT_STRING_CHARPOS (*it) > 0)
4804 {
4805 --IT_STRING_CHARPOS (*it);
4806 --IT_STRING_BYTEPOS (*it);
4807 }
4808 }
4809 else if (IT_CHARPOS (*it) > BEGV)
4810 {
4811 --IT_CHARPOS (*it);
4812 --IT_BYTEPOS (*it);
4813 reseat (it, it->current.pos, 0);
4814 }
4815 }
4816 else if (skipped_p)
4817 reseat (it, it->current.pos, 0);
4818
4819 CHECK_IT (it);
4820 }
4821
4822
4823 \f
4824 /***********************************************************************
4825 Changing an iterator's position
4826 ***********************************************************************/
4827
4828 /* Change IT's current position to POS in current_buffer. If FORCE_P
4829 is non-zero, always check for text properties at the new position.
4830 Otherwise, text properties are only looked up if POS >=
4831 IT->check_charpos of a property. */
4832
4833 static void
4834 reseat (it, pos, force_p)
4835 struct it *it;
4836 struct text_pos pos;
4837 int force_p;
4838 {
4839 int original_pos = IT_CHARPOS (*it);
4840
4841 reseat_1 (it, pos, 0);
4842
4843 /* Determine where to check text properties. Avoid doing it
4844 where possible because text property lookup is very expensive. */
4845 if (force_p
4846 || CHARPOS (pos) > it->stop_charpos
4847 || CHARPOS (pos) < original_pos)
4848 handle_stop (it);
4849
4850 CHECK_IT (it);
4851 }
4852
4853
4854 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4855 IT->stop_pos to POS, also. */
4856
4857 static void
4858 reseat_1 (it, pos, set_stop_p)
4859 struct it *it;
4860 struct text_pos pos;
4861 int set_stop_p;
4862 {
4863 /* Don't call this function when scanning a C string. */
4864 xassert (it->s == NULL);
4865
4866 /* POS must be a reasonable value. */
4867 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4868
4869 it->current.pos = it->position = pos;
4870 XSETBUFFER (it->object, current_buffer);
4871 it->end_charpos = ZV;
4872 it->dpvec = NULL;
4873 it->current.dpvec_index = -1;
4874 it->current.overlay_string_index = -1;
4875 IT_STRING_CHARPOS (*it) = -1;
4876 IT_STRING_BYTEPOS (*it) = -1;
4877 it->string = Qnil;
4878 it->method = GET_FROM_BUFFER;
4879 /* RMS: I added this to fix a bug in move_it_vertically_backward
4880 where it->area continued to relate to the starting point
4881 for the backward motion. Bug report from
4882 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4883 However, I am not sure whether reseat still does the right thing
4884 in general after this change. */
4885 it->area = TEXT_AREA;
4886 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4887 it->sp = 0;
4888 it->face_before_selective_p = 0;
4889
4890 if (set_stop_p)
4891 it->stop_charpos = CHARPOS (pos);
4892 }
4893
4894
4895 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4896 If S is non-null, it is a C string to iterate over. Otherwise,
4897 STRING gives a Lisp string to iterate over.
4898
4899 If PRECISION > 0, don't return more then PRECISION number of
4900 characters from the string.
4901
4902 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4903 characters have been returned. FIELD_WIDTH < 0 means an infinite
4904 field width.
4905
4906 MULTIBYTE = 0 means disable processing of multibyte characters,
4907 MULTIBYTE > 0 means enable it,
4908 MULTIBYTE < 0 means use IT->multibyte_p.
4909
4910 IT must be initialized via a prior call to init_iterator before
4911 calling this function. */
4912
4913 static void
4914 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4915 struct it *it;
4916 unsigned char *s;
4917 Lisp_Object string;
4918 int charpos;
4919 int precision, field_width, multibyte;
4920 {
4921 /* No region in strings. */
4922 it->region_beg_charpos = it->region_end_charpos = -1;
4923
4924 /* No text property checks performed by default, but see below. */
4925 it->stop_charpos = -1;
4926
4927 /* Set iterator position and end position. */
4928 bzero (&it->current, sizeof it->current);
4929 it->current.overlay_string_index = -1;
4930 it->current.dpvec_index = -1;
4931 xassert (charpos >= 0);
4932
4933 /* If STRING is specified, use its multibyteness, otherwise use the
4934 setting of MULTIBYTE, if specified. */
4935 if (multibyte >= 0)
4936 it->multibyte_p = multibyte > 0;
4937
4938 if (s == NULL)
4939 {
4940 xassert (STRINGP (string));
4941 it->string = string;
4942 it->s = NULL;
4943 it->end_charpos = it->string_nchars = SCHARS (string);
4944 it->method = GET_FROM_STRING;
4945 it->current.string_pos = string_pos (charpos, string);
4946 }
4947 else
4948 {
4949 it->s = s;
4950 it->string = Qnil;
4951
4952 /* Note that we use IT->current.pos, not it->current.string_pos,
4953 for displaying C strings. */
4954 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4955 if (it->multibyte_p)
4956 {
4957 it->current.pos = c_string_pos (charpos, s, 1);
4958 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4959 }
4960 else
4961 {
4962 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4963 it->end_charpos = it->string_nchars = strlen (s);
4964 }
4965
4966 it->method = GET_FROM_C_STRING;
4967 }
4968
4969 /* PRECISION > 0 means don't return more than PRECISION characters
4970 from the string. */
4971 if (precision > 0 && it->end_charpos - charpos > precision)
4972 it->end_charpos = it->string_nchars = charpos + precision;
4973
4974 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4975 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4976 FIELD_WIDTH < 0 means infinite field width. This is useful for
4977 padding with `-' at the end of a mode line. */
4978 if (field_width < 0)
4979 field_width = INFINITY;
4980 if (field_width > it->end_charpos - charpos)
4981 it->end_charpos = charpos + field_width;
4982
4983 /* Use the standard display table for displaying strings. */
4984 if (DISP_TABLE_P (Vstandard_display_table))
4985 it->dp = XCHAR_TABLE (Vstandard_display_table);
4986
4987 it->stop_charpos = charpos;
4988 CHECK_IT (it);
4989 }
4990
4991
4992 \f
4993 /***********************************************************************
4994 Iteration
4995 ***********************************************************************/
4996
4997 /* Map enum it_method value to corresponding next_element_from_* function. */
4998
4999 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5000 {
5001 next_element_from_buffer,
5002 next_element_from_display_vector,
5003 next_element_from_composition,
5004 next_element_from_string,
5005 next_element_from_c_string,
5006 next_element_from_image,
5007 next_element_from_stretch
5008 };
5009
5010
5011 /* Load IT's display element fields with information about the next
5012 display element from the current position of IT. Value is zero if
5013 end of buffer (or C string) is reached. */
5014
5015 int
5016 get_next_display_element (it)
5017 struct it *it;
5018 {
5019 /* Non-zero means that we found a display element. Zero means that
5020 we hit the end of what we iterate over. Performance note: the
5021 function pointer `method' used here turns out to be faster than
5022 using a sequence of if-statements. */
5023 int success_p;
5024
5025 get_next:
5026 success_p = (*get_next_element[it->method]) (it);
5027
5028 if (it->what == IT_CHARACTER)
5029 {
5030 /* Map via display table or translate control characters.
5031 IT->c, IT->len etc. have been set to the next character by
5032 the function call above. If we have a display table, and it
5033 contains an entry for IT->c, translate it. Don't do this if
5034 IT->c itself comes from a display table, otherwise we could
5035 end up in an infinite recursion. (An alternative could be to
5036 count the recursion depth of this function and signal an
5037 error when a certain maximum depth is reached.) Is it worth
5038 it? */
5039 if (success_p && it->dpvec == NULL)
5040 {
5041 Lisp_Object dv;
5042
5043 if (it->dp
5044 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5045 VECTORP (dv)))
5046 {
5047 struct Lisp_Vector *v = XVECTOR (dv);
5048
5049 /* Return the first character from the display table
5050 entry, if not empty. If empty, don't display the
5051 current character. */
5052 if (v->size)
5053 {
5054 it->dpvec_char_len = it->len;
5055 it->dpvec = v->contents;
5056 it->dpend = v->contents + v->size;
5057 it->current.dpvec_index = 0;
5058 it->dpvec_face_id = -1;
5059 it->saved_face_id = it->face_id;
5060 it->method = GET_FROM_DISPLAY_VECTOR;
5061 it->ellipsis_p = 0;
5062 }
5063 else
5064 {
5065 set_iterator_to_next (it, 0);
5066 }
5067 goto get_next;
5068 }
5069
5070 /* Translate control characters into `\003' or `^C' form.
5071 Control characters coming from a display table entry are
5072 currently not translated because we use IT->dpvec to hold
5073 the translation. This could easily be changed but I
5074 don't believe that it is worth doing.
5075
5076 If it->multibyte_p is nonzero, eight-bit characters and
5077 non-printable multibyte characters are also translated to
5078 octal form.
5079
5080 If it->multibyte_p is zero, eight-bit characters that
5081 don't have corresponding multibyte char code are also
5082 translated to octal form. */
5083 else if ((it->c < ' '
5084 && (it->area != TEXT_AREA
5085 /* In mode line, treat \n like other crl chars. */
5086 || (it->c != '\t'
5087 && it->glyph_row && it->glyph_row->mode_line_p)
5088 || (it->c != '\n' && it->c != '\t')))
5089 || (it->multibyte_p
5090 ? ((it->c >= 127
5091 && it->len == 1)
5092 || !CHAR_PRINTABLE_P (it->c)
5093 || (!NILP (Vnobreak_char_display)
5094 && (it->c == 0x8a0 || it->c == 0x8ad
5095 || it->c == 0x920 || it->c == 0x92d
5096 || it->c == 0xe20 || it->c == 0xe2d
5097 || it->c == 0xf20 || it->c == 0xf2d)))
5098 : (it->c >= 127
5099 && (!unibyte_display_via_language_environment
5100 || it->c == unibyte_char_to_multibyte (it->c)))))
5101 {
5102 /* IT->c is a control character which must be displayed
5103 either as '\003' or as `^C' where the '\\' and '^'
5104 can be defined in the display table. Fill
5105 IT->ctl_chars with glyphs for what we have to
5106 display. Then, set IT->dpvec to these glyphs. */
5107 GLYPH g;
5108 int ctl_len;
5109 int face_id, lface_id = 0 ;
5110 GLYPH escape_glyph;
5111
5112 /* Handle control characters with ^. */
5113
5114 if (it->c < 128 && it->ctl_arrow_p)
5115 {
5116 g = '^'; /* default glyph for Control */
5117 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5118 if (it->dp
5119 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5120 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5121 {
5122 g = XINT (DISP_CTRL_GLYPH (it->dp));
5123 lface_id = FAST_GLYPH_FACE (g);
5124 }
5125 if (lface_id)
5126 {
5127 g = FAST_GLYPH_CHAR (g);
5128 face_id = merge_faces (it->f, Qt, lface_id,
5129 it->face_id);
5130 }
5131 else
5132 {
5133 /* Merge the escape-glyph face into the current face. */
5134 face_id = merge_faces (it->f, Qescape_glyph, 0,
5135 it->face_id);
5136 }
5137
5138 XSETINT (it->ctl_chars[0], g);
5139 g = it->c ^ 0100;
5140 XSETINT (it->ctl_chars[1], g);
5141 ctl_len = 2;
5142 goto display_control;
5143 }
5144
5145 /* Handle non-break space in the mode where it only gets
5146 highlighting. */
5147
5148 if (EQ (Vnobreak_char_display, Qt)
5149 && (it->c == 0x8a0 || it->c == 0x920
5150 || it->c == 0xe20 || it->c == 0xf20))
5151 {
5152 /* Merge the no-break-space face into the current face. */
5153 face_id = merge_faces (it->f, Qnobreak_space, 0,
5154 it->face_id);
5155
5156 g = it->c = ' ';
5157 XSETINT (it->ctl_chars[0], g);
5158 ctl_len = 1;
5159 goto display_control;
5160 }
5161
5162 /* Handle sequences that start with the "escape glyph". */
5163
5164 /* the default escape glyph is \. */
5165 escape_glyph = '\\';
5166
5167 if (it->dp
5168 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5169 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5170 {
5171 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5172 lface_id = FAST_GLYPH_FACE (escape_glyph);
5173 }
5174 if (lface_id)
5175 {
5176 /* The display table specified a face.
5177 Merge it into face_id and also into escape_glyph. */
5178 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5179 face_id = merge_faces (it->f, Qt, lface_id,
5180 it->face_id);
5181 }
5182 else
5183 {
5184 /* Merge the escape-glyph face into the current face. */
5185 face_id = merge_faces (it->f, Qescape_glyph, 0,
5186 it->face_id);
5187 }
5188
5189 /* Handle soft hyphens in the mode where they only get
5190 highlighting. */
5191
5192 if (EQ (Vnobreak_char_display, Qt)
5193 && (it->c == 0x8ad || it->c == 0x92d
5194 || it->c == 0xe2d || it->c == 0xf2d))
5195 {
5196 g = it->c = '-';
5197 XSETINT (it->ctl_chars[0], g);
5198 ctl_len = 1;
5199 goto display_control;
5200 }
5201
5202 /* Handle non-break space and soft hyphen
5203 with the escape glyph. */
5204
5205 if (it->c == 0x8a0 || it->c == 0x8ad
5206 || it->c == 0x920 || it->c == 0x92d
5207 || it->c == 0xe20 || it->c == 0xe2d
5208 || it->c == 0xf20 || it->c == 0xf2d)
5209 {
5210 XSETINT (it->ctl_chars[0], escape_glyph);
5211 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
5212 XSETINT (it->ctl_chars[1], g);
5213 ctl_len = 2;
5214 goto display_control;
5215 }
5216
5217 {
5218 unsigned char str[MAX_MULTIBYTE_LENGTH];
5219 int len;
5220 int i;
5221
5222 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5223 if (SINGLE_BYTE_CHAR_P (it->c))
5224 str[0] = it->c, len = 1;
5225 else
5226 {
5227 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5228 if (len < 0)
5229 {
5230 /* It's an invalid character, which shouldn't
5231 happen actually, but due to bugs it may
5232 happen. Let's print the char as is, there's
5233 not much meaningful we can do with it. */
5234 str[0] = it->c;
5235 str[1] = it->c >> 8;
5236 str[2] = it->c >> 16;
5237 str[3] = it->c >> 24;
5238 len = 4;
5239 }
5240 }
5241
5242 for (i = 0; i < len; i++)
5243 {
5244 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5245 /* Insert three more glyphs into IT->ctl_chars for
5246 the octal display of the character. */
5247 g = ((str[i] >> 6) & 7) + '0';
5248 XSETINT (it->ctl_chars[i * 4 + 1], g);
5249 g = ((str[i] >> 3) & 7) + '0';
5250 XSETINT (it->ctl_chars[i * 4 + 2], g);
5251 g = (str[i] & 7) + '0';
5252 XSETINT (it->ctl_chars[i * 4 + 3], g);
5253 }
5254 ctl_len = len * 4;
5255 }
5256
5257 display_control:
5258 /* Set up IT->dpvec and return first character from it. */
5259 it->dpvec_char_len = it->len;
5260 it->dpvec = it->ctl_chars;
5261 it->dpend = it->dpvec + ctl_len;
5262 it->current.dpvec_index = 0;
5263 it->dpvec_face_id = face_id;
5264 it->saved_face_id = it->face_id;
5265 it->method = GET_FROM_DISPLAY_VECTOR;
5266 it->ellipsis_p = 0;
5267 goto get_next;
5268 }
5269 }
5270
5271 /* Adjust face id for a multibyte character. There are no
5272 multibyte character in unibyte text. */
5273 if (it->multibyte_p
5274 && success_p
5275 && FRAME_WINDOW_P (it->f))
5276 {
5277 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5278 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5279 }
5280 }
5281
5282 /* Is this character the last one of a run of characters with
5283 box? If yes, set IT->end_of_box_run_p to 1. */
5284 if (it->face_box_p
5285 && it->s == NULL)
5286 {
5287 int face_id;
5288 struct face *face;
5289
5290 it->end_of_box_run_p
5291 = ((face_id = face_after_it_pos (it),
5292 face_id != it->face_id)
5293 && (face = FACE_FROM_ID (it->f, face_id),
5294 face->box == FACE_NO_BOX));
5295 }
5296
5297 /* Value is 0 if end of buffer or string reached. */
5298 return success_p;
5299 }
5300
5301
5302 /* Move IT to the next display element.
5303
5304 RESEAT_P non-zero means if called on a newline in buffer text,
5305 skip to the next visible line start.
5306
5307 Functions get_next_display_element and set_iterator_to_next are
5308 separate because I find this arrangement easier to handle than a
5309 get_next_display_element function that also increments IT's
5310 position. The way it is we can first look at an iterator's current
5311 display element, decide whether it fits on a line, and if it does,
5312 increment the iterator position. The other way around we probably
5313 would either need a flag indicating whether the iterator has to be
5314 incremented the next time, or we would have to implement a
5315 decrement position function which would not be easy to write. */
5316
5317 void
5318 set_iterator_to_next (it, reseat_p)
5319 struct it *it;
5320 int reseat_p;
5321 {
5322 /* Reset flags indicating start and end of a sequence of characters
5323 with box. Reset them at the start of this function because
5324 moving the iterator to a new position might set them. */
5325 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5326
5327 switch (it->method)
5328 {
5329 case GET_FROM_BUFFER:
5330 /* The current display element of IT is a character from
5331 current_buffer. Advance in the buffer, and maybe skip over
5332 invisible lines that are so because of selective display. */
5333 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5334 reseat_at_next_visible_line_start (it, 0);
5335 else
5336 {
5337 xassert (it->len != 0);
5338 IT_BYTEPOS (*it) += it->len;
5339 IT_CHARPOS (*it) += 1;
5340 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5341 }
5342 break;
5343
5344 case GET_FROM_COMPOSITION:
5345 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5346 if (STRINGP (it->string))
5347 {
5348 IT_STRING_BYTEPOS (*it) += it->len;
5349 IT_STRING_CHARPOS (*it) += it->cmp_len;
5350 it->method = GET_FROM_STRING;
5351 goto consider_string_end;
5352 }
5353 else
5354 {
5355 IT_BYTEPOS (*it) += it->len;
5356 IT_CHARPOS (*it) += it->cmp_len;
5357 it->method = GET_FROM_BUFFER;
5358 }
5359 break;
5360
5361 case GET_FROM_C_STRING:
5362 /* Current display element of IT is from a C string. */
5363 IT_BYTEPOS (*it) += it->len;
5364 IT_CHARPOS (*it) += 1;
5365 break;
5366
5367 case GET_FROM_DISPLAY_VECTOR:
5368 /* Current display element of IT is from a display table entry.
5369 Advance in the display table definition. Reset it to null if
5370 end reached, and continue with characters from buffers/
5371 strings. */
5372 ++it->current.dpvec_index;
5373
5374 /* Restore face of the iterator to what they were before the
5375 display vector entry (these entries may contain faces). */
5376 it->face_id = it->saved_face_id;
5377
5378 if (it->dpvec + it->current.dpvec_index == it->dpend)
5379 {
5380 if (it->s)
5381 it->method = GET_FROM_C_STRING;
5382 else if (STRINGP (it->string))
5383 it->method = GET_FROM_STRING;
5384 else
5385 it->method = GET_FROM_BUFFER;
5386
5387 it->dpvec = NULL;
5388 it->current.dpvec_index = -1;
5389
5390 /* Skip over characters which were displayed via IT->dpvec. */
5391 if (it->dpvec_char_len < 0)
5392 reseat_at_next_visible_line_start (it, 1);
5393 else if (it->dpvec_char_len > 0)
5394 {
5395 it->len = it->dpvec_char_len;
5396 set_iterator_to_next (it, reseat_p);
5397 }
5398
5399 /* Recheck faces after display vector */
5400 it->stop_charpos = IT_CHARPOS (*it);
5401 }
5402 break;
5403
5404 case GET_FROM_STRING:
5405 /* Current display element is a character from a Lisp string. */
5406 xassert (it->s == NULL && STRINGP (it->string));
5407 IT_STRING_BYTEPOS (*it) += it->len;
5408 IT_STRING_CHARPOS (*it) += 1;
5409
5410 consider_string_end:
5411
5412 if (it->current.overlay_string_index >= 0)
5413 {
5414 /* IT->string is an overlay string. Advance to the
5415 next, if there is one. */
5416 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5417 next_overlay_string (it);
5418 }
5419 else
5420 {
5421 /* IT->string is not an overlay string. If we reached
5422 its end, and there is something on IT->stack, proceed
5423 with what is on the stack. This can be either another
5424 string, this time an overlay string, or a buffer. */
5425 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5426 && it->sp > 0)
5427 {
5428 pop_it (it);
5429 if (STRINGP (it->string))
5430 goto consider_string_end;
5431 it->method = GET_FROM_BUFFER;
5432 }
5433 }
5434 break;
5435
5436 case GET_FROM_IMAGE:
5437 case GET_FROM_STRETCH:
5438 /* The position etc with which we have to proceed are on
5439 the stack. The position may be at the end of a string,
5440 if the `display' property takes up the whole string. */
5441 xassert (it->sp > 0);
5442 pop_it (it);
5443 it->image_id = 0;
5444 if (STRINGP (it->string))
5445 {
5446 it->method = GET_FROM_STRING;
5447 goto consider_string_end;
5448 }
5449 it->method = GET_FROM_BUFFER;
5450 break;
5451
5452 default:
5453 /* There are no other methods defined, so this should be a bug. */
5454 abort ();
5455 }
5456
5457 xassert (it->method != GET_FROM_STRING
5458 || (STRINGP (it->string)
5459 && IT_STRING_CHARPOS (*it) >= 0));
5460 }
5461
5462 /* Load IT's display element fields with information about the next
5463 display element which comes from a display table entry or from the
5464 result of translating a control character to one of the forms `^C'
5465 or `\003'.
5466
5467 IT->dpvec holds the glyphs to return as characters.
5468 IT->saved_face_id holds the face id before the display vector--
5469 it is restored into IT->face_idin set_iterator_to_next. */
5470
5471 static int
5472 next_element_from_display_vector (it)
5473 struct it *it;
5474 {
5475 /* Precondition. */
5476 xassert (it->dpvec && it->current.dpvec_index >= 0);
5477
5478 it->face_id = it->saved_face_id;
5479
5480 if (INTEGERP (*it->dpvec)
5481 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5482 {
5483 GLYPH g;
5484
5485 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5486 it->c = FAST_GLYPH_CHAR (g);
5487 it->len = CHAR_BYTES (it->c);
5488
5489 /* The entry may contain a face id to use. Such a face id is
5490 the id of a Lisp face, not a realized face. A face id of
5491 zero means no face is specified. */
5492 if (it->dpvec_face_id >= 0)
5493 it->face_id = it->dpvec_face_id;
5494 else
5495 {
5496 int lface_id = FAST_GLYPH_FACE (g);
5497 if (lface_id > 0)
5498 it->face_id = merge_faces (it->f, Qt, lface_id,
5499 it->saved_face_id);
5500 }
5501 }
5502 else
5503 /* Display table entry is invalid. Return a space. */
5504 it->c = ' ', it->len = 1;
5505
5506 /* Don't change position and object of the iterator here. They are
5507 still the values of the character that had this display table
5508 entry or was translated, and that's what we want. */
5509 it->what = IT_CHARACTER;
5510 return 1;
5511 }
5512
5513
5514 /* Load IT with the next display element from Lisp string IT->string.
5515 IT->current.string_pos is the current position within the string.
5516 If IT->current.overlay_string_index >= 0, the Lisp string is an
5517 overlay string. */
5518
5519 static int
5520 next_element_from_string (it)
5521 struct it *it;
5522 {
5523 struct text_pos position;
5524
5525 xassert (STRINGP (it->string));
5526 xassert (IT_STRING_CHARPOS (*it) >= 0);
5527 position = it->current.string_pos;
5528
5529 /* Time to check for invisible text? */
5530 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5531 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5532 {
5533 handle_stop (it);
5534
5535 /* Since a handler may have changed IT->method, we must
5536 recurse here. */
5537 return get_next_display_element (it);
5538 }
5539
5540 if (it->current.overlay_string_index >= 0)
5541 {
5542 /* Get the next character from an overlay string. In overlay
5543 strings, There is no field width or padding with spaces to
5544 do. */
5545 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5546 {
5547 it->what = IT_EOB;
5548 return 0;
5549 }
5550 else if (STRING_MULTIBYTE (it->string))
5551 {
5552 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5553 const unsigned char *s = (SDATA (it->string)
5554 + IT_STRING_BYTEPOS (*it));
5555 it->c = string_char_and_length (s, remaining, &it->len);
5556 }
5557 else
5558 {
5559 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5560 it->len = 1;
5561 }
5562 }
5563 else
5564 {
5565 /* Get the next character from a Lisp string that is not an
5566 overlay string. Such strings come from the mode line, for
5567 example. We may have to pad with spaces, or truncate the
5568 string. See also next_element_from_c_string. */
5569 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5570 {
5571 it->what = IT_EOB;
5572 return 0;
5573 }
5574 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5575 {
5576 /* Pad with spaces. */
5577 it->c = ' ', it->len = 1;
5578 CHARPOS (position) = BYTEPOS (position) = -1;
5579 }
5580 else if (STRING_MULTIBYTE (it->string))
5581 {
5582 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5583 const unsigned char *s = (SDATA (it->string)
5584 + IT_STRING_BYTEPOS (*it));
5585 it->c = string_char_and_length (s, maxlen, &it->len);
5586 }
5587 else
5588 {
5589 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5590 it->len = 1;
5591 }
5592 }
5593
5594 /* Record what we have and where it came from. Note that we store a
5595 buffer position in IT->position although it could arguably be a
5596 string position. */
5597 it->what = IT_CHARACTER;
5598 it->object = it->string;
5599 it->position = position;
5600 return 1;
5601 }
5602
5603
5604 /* Load IT with next display element from C string IT->s.
5605 IT->string_nchars is the maximum number of characters to return
5606 from the string. IT->end_charpos may be greater than
5607 IT->string_nchars when this function is called, in which case we
5608 may have to return padding spaces. Value is zero if end of string
5609 reached, including padding spaces. */
5610
5611 static int
5612 next_element_from_c_string (it)
5613 struct it *it;
5614 {
5615 int success_p = 1;
5616
5617 xassert (it->s);
5618 it->what = IT_CHARACTER;
5619 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5620 it->object = Qnil;
5621
5622 /* IT's position can be greater IT->string_nchars in case a field
5623 width or precision has been specified when the iterator was
5624 initialized. */
5625 if (IT_CHARPOS (*it) >= it->end_charpos)
5626 {
5627 /* End of the game. */
5628 it->what = IT_EOB;
5629 success_p = 0;
5630 }
5631 else if (IT_CHARPOS (*it) >= it->string_nchars)
5632 {
5633 /* Pad with spaces. */
5634 it->c = ' ', it->len = 1;
5635 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5636 }
5637 else if (it->multibyte_p)
5638 {
5639 /* Implementation note: The calls to strlen apparently aren't a
5640 performance problem because there is no noticeable performance
5641 difference between Emacs running in unibyte or multibyte mode. */
5642 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5643 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5644 maxlen, &it->len);
5645 }
5646 else
5647 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5648
5649 return success_p;
5650 }
5651
5652
5653 /* Set up IT to return characters from an ellipsis, if appropriate.
5654 The definition of the ellipsis glyphs may come from a display table
5655 entry. This function Fills IT with the first glyph from the
5656 ellipsis if an ellipsis is to be displayed. */
5657
5658 static int
5659 next_element_from_ellipsis (it)
5660 struct it *it;
5661 {
5662 if (it->selective_display_ellipsis_p)
5663 setup_for_ellipsis (it, it->len);
5664 else
5665 {
5666 /* The face at the current position may be different from the
5667 face we find after the invisible text. Remember what it
5668 was in IT->saved_face_id, and signal that it's there by
5669 setting face_before_selective_p. */
5670 it->saved_face_id = it->face_id;
5671 it->method = GET_FROM_BUFFER;
5672 reseat_at_next_visible_line_start (it, 1);
5673 it->face_before_selective_p = 1;
5674 }
5675
5676 return get_next_display_element (it);
5677 }
5678
5679
5680 /* Deliver an image display element. The iterator IT is already
5681 filled with image information (done in handle_display_prop). Value
5682 is always 1. */
5683
5684
5685 static int
5686 next_element_from_image (it)
5687 struct it *it;
5688 {
5689 it->what = IT_IMAGE;
5690 return 1;
5691 }
5692
5693
5694 /* Fill iterator IT with next display element from a stretch glyph
5695 property. IT->object is the value of the text property. Value is
5696 always 1. */
5697
5698 static int
5699 next_element_from_stretch (it)
5700 struct it *it;
5701 {
5702 it->what = IT_STRETCH;
5703 return 1;
5704 }
5705
5706
5707 /* Load IT with the next display element from current_buffer. Value
5708 is zero if end of buffer reached. IT->stop_charpos is the next
5709 position at which to stop and check for text properties or buffer
5710 end. */
5711
5712 static int
5713 next_element_from_buffer (it)
5714 struct it *it;
5715 {
5716 int success_p = 1;
5717
5718 /* Check this assumption, otherwise, we would never enter the
5719 if-statement, below. */
5720 xassert (IT_CHARPOS (*it) >= BEGV
5721 && IT_CHARPOS (*it) <= it->stop_charpos);
5722
5723 if (IT_CHARPOS (*it) >= it->stop_charpos)
5724 {
5725 if (IT_CHARPOS (*it) >= it->end_charpos)
5726 {
5727 int overlay_strings_follow_p;
5728
5729 /* End of the game, except when overlay strings follow that
5730 haven't been returned yet. */
5731 if (it->overlay_strings_at_end_processed_p)
5732 overlay_strings_follow_p = 0;
5733 else
5734 {
5735 it->overlay_strings_at_end_processed_p = 1;
5736 overlay_strings_follow_p = get_overlay_strings (it, 0);
5737 }
5738
5739 if (overlay_strings_follow_p)
5740 success_p = get_next_display_element (it);
5741 else
5742 {
5743 it->what = IT_EOB;
5744 it->position = it->current.pos;
5745 success_p = 0;
5746 }
5747 }
5748 else
5749 {
5750 handle_stop (it);
5751 return get_next_display_element (it);
5752 }
5753 }
5754 else
5755 {
5756 /* No face changes, overlays etc. in sight, so just return a
5757 character from current_buffer. */
5758 unsigned char *p;
5759
5760 /* Maybe run the redisplay end trigger hook. Performance note:
5761 This doesn't seem to cost measurable time. */
5762 if (it->redisplay_end_trigger_charpos
5763 && it->glyph_row
5764 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5765 run_redisplay_end_trigger_hook (it);
5766
5767 /* Get the next character, maybe multibyte. */
5768 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5769 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5770 {
5771 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5772 - IT_BYTEPOS (*it));
5773 it->c = string_char_and_length (p, maxlen, &it->len);
5774 }
5775 else
5776 it->c = *p, it->len = 1;
5777
5778 /* Record what we have and where it came from. */
5779 it->what = IT_CHARACTER;;
5780 it->object = it->w->buffer;
5781 it->position = it->current.pos;
5782
5783 /* Normally we return the character found above, except when we
5784 really want to return an ellipsis for selective display. */
5785 if (it->selective)
5786 {
5787 if (it->c == '\n')
5788 {
5789 /* A value of selective > 0 means hide lines indented more
5790 than that number of columns. */
5791 if (it->selective > 0
5792 && IT_CHARPOS (*it) + 1 < ZV
5793 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5794 IT_BYTEPOS (*it) + 1,
5795 (double) it->selective)) /* iftc */
5796 {
5797 success_p = next_element_from_ellipsis (it);
5798 it->dpvec_char_len = -1;
5799 }
5800 }
5801 else if (it->c == '\r' && it->selective == -1)
5802 {
5803 /* A value of selective == -1 means that everything from the
5804 CR to the end of the line is invisible, with maybe an
5805 ellipsis displayed for it. */
5806 success_p = next_element_from_ellipsis (it);
5807 it->dpvec_char_len = -1;
5808 }
5809 }
5810 }
5811
5812 /* Value is zero if end of buffer reached. */
5813 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5814 return success_p;
5815 }
5816
5817
5818 /* Run the redisplay end trigger hook for IT. */
5819
5820 static void
5821 run_redisplay_end_trigger_hook (it)
5822 struct it *it;
5823 {
5824 Lisp_Object args[3];
5825
5826 /* IT->glyph_row should be non-null, i.e. we should be actually
5827 displaying something, or otherwise we should not run the hook. */
5828 xassert (it->glyph_row);
5829
5830 /* Set up hook arguments. */
5831 args[0] = Qredisplay_end_trigger_functions;
5832 args[1] = it->window;
5833 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5834 it->redisplay_end_trigger_charpos = 0;
5835
5836 /* Since we are *trying* to run these functions, don't try to run
5837 them again, even if they get an error. */
5838 it->w->redisplay_end_trigger = Qnil;
5839 Frun_hook_with_args (3, args);
5840
5841 /* Notice if it changed the face of the character we are on. */
5842 handle_face_prop (it);
5843 }
5844
5845
5846 /* Deliver a composition display element. The iterator IT is already
5847 filled with composition information (done in
5848 handle_composition_prop). Value is always 1. */
5849
5850 static int
5851 next_element_from_composition (it)
5852 struct it *it;
5853 {
5854 it->what = IT_COMPOSITION;
5855 it->position = (STRINGP (it->string)
5856 ? it->current.string_pos
5857 : it->current.pos);
5858 return 1;
5859 }
5860
5861
5862 \f
5863 /***********************************************************************
5864 Moving an iterator without producing glyphs
5865 ***********************************************************************/
5866
5867 /* Check if iterator is at a position corresponding to a valid buffer
5868 position after some move_it_ call. */
5869
5870 #define IT_POS_VALID_AFTER_MOVE_P(it) \
5871 ((it)->method == GET_FROM_STRING \
5872 ? IT_STRING_CHARPOS (*it) == 0 \
5873 : 1)
5874
5875
5876 /* Move iterator IT to a specified buffer or X position within one
5877 line on the display without producing glyphs.
5878
5879 OP should be a bit mask including some or all of these bits:
5880 MOVE_TO_X: Stop on reaching x-position TO_X.
5881 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5882 Regardless of OP's value, stop in reaching the end of the display line.
5883
5884 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5885 This means, in particular, that TO_X includes window's horizontal
5886 scroll amount.
5887
5888 The return value has several possible values that
5889 say what condition caused the scan to stop:
5890
5891 MOVE_POS_MATCH_OR_ZV
5892 - when TO_POS or ZV was reached.
5893
5894 MOVE_X_REACHED
5895 -when TO_X was reached before TO_POS or ZV were reached.
5896
5897 MOVE_LINE_CONTINUED
5898 - when we reached the end of the display area and the line must
5899 be continued.
5900
5901 MOVE_LINE_TRUNCATED
5902 - when we reached the end of the display area and the line is
5903 truncated.
5904
5905 MOVE_NEWLINE_OR_CR
5906 - when we stopped at a line end, i.e. a newline or a CR and selective
5907 display is on. */
5908
5909 static enum move_it_result
5910 move_it_in_display_line_to (it, to_charpos, to_x, op)
5911 struct it *it;
5912 int to_charpos, to_x, op;
5913 {
5914 enum move_it_result result = MOVE_UNDEFINED;
5915 struct glyph_row *saved_glyph_row;
5916
5917 /* Don't produce glyphs in produce_glyphs. */
5918 saved_glyph_row = it->glyph_row;
5919 it->glyph_row = NULL;
5920
5921 #define BUFFER_POS_REACHED_P() \
5922 ((op & MOVE_TO_POS) != 0 \
5923 && BUFFERP (it->object) \
5924 && IT_CHARPOS (*it) >= to_charpos \
5925 && (it->method == GET_FROM_BUFFER \
5926 || (it->method == GET_FROM_DISPLAY_VECTOR \
5927 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
5928
5929
5930 while (1)
5931 {
5932 int x, i, ascent = 0, descent = 0;
5933
5934 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
5935 if ((op & MOVE_TO_POS) != 0
5936 && BUFFERP (it->object)
5937 && it->method == GET_FROM_BUFFER
5938 && IT_CHARPOS (*it) > to_charpos)
5939 {
5940 result = MOVE_POS_MATCH_OR_ZV;
5941 break;
5942 }
5943
5944 /* Stop when ZV reached.
5945 We used to stop here when TO_CHARPOS reached as well, but that is
5946 too soon if this glyph does not fit on this line. So we handle it
5947 explicitly below. */
5948 if (!get_next_display_element (it)
5949 || (it->truncate_lines_p
5950 && BUFFER_POS_REACHED_P ()))
5951 {
5952 result = MOVE_POS_MATCH_OR_ZV;
5953 break;
5954 }
5955
5956 /* The call to produce_glyphs will get the metrics of the
5957 display element IT is loaded with. We record in x the
5958 x-position before this display element in case it does not
5959 fit on the line. */
5960 x = it->current_x;
5961
5962 /* Remember the line height so far in case the next element doesn't
5963 fit on the line. */
5964 if (!it->truncate_lines_p)
5965 {
5966 ascent = it->max_ascent;
5967 descent = it->max_descent;
5968 }
5969
5970 PRODUCE_GLYPHS (it);
5971
5972 if (it->area != TEXT_AREA)
5973 {
5974 set_iterator_to_next (it, 1);
5975 continue;
5976 }
5977
5978 /* The number of glyphs we get back in IT->nglyphs will normally
5979 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5980 character on a terminal frame, or (iii) a line end. For the
5981 second case, IT->nglyphs - 1 padding glyphs will be present
5982 (on X frames, there is only one glyph produced for a
5983 composite character.
5984
5985 The behavior implemented below means, for continuation lines,
5986 that as many spaces of a TAB as fit on the current line are
5987 displayed there. For terminal frames, as many glyphs of a
5988 multi-glyph character are displayed in the current line, too.
5989 This is what the old redisplay code did, and we keep it that
5990 way. Under X, the whole shape of a complex character must
5991 fit on the line or it will be completely displayed in the
5992 next line.
5993
5994 Note that both for tabs and padding glyphs, all glyphs have
5995 the same width. */
5996 if (it->nglyphs)
5997 {
5998 /* More than one glyph or glyph doesn't fit on line. All
5999 glyphs have the same width. */
6000 int single_glyph_width = it->pixel_width / it->nglyphs;
6001 int new_x;
6002
6003 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6004 {
6005 new_x = x + single_glyph_width;
6006
6007 /* We want to leave anything reaching TO_X to the caller. */
6008 if ((op & MOVE_TO_X) && new_x > to_x)
6009 {
6010 if (BUFFER_POS_REACHED_P ())
6011 goto buffer_pos_reached;
6012 it->current_x = x;
6013 result = MOVE_X_REACHED;
6014 break;
6015 }
6016 else if (/* Lines are continued. */
6017 !it->truncate_lines_p
6018 && (/* And glyph doesn't fit on the line. */
6019 new_x > it->last_visible_x
6020 /* Or it fits exactly and we're on a window
6021 system frame. */
6022 || (new_x == it->last_visible_x
6023 && FRAME_WINDOW_P (it->f))))
6024 {
6025 if (/* IT->hpos == 0 means the very first glyph
6026 doesn't fit on the line, e.g. a wide image. */
6027 it->hpos == 0
6028 || (new_x == it->last_visible_x
6029 && FRAME_WINDOW_P (it->f)))
6030 {
6031 ++it->hpos;
6032 it->current_x = new_x;
6033 if (i == it->nglyphs - 1)
6034 {
6035 set_iterator_to_next (it, 1);
6036 #ifdef HAVE_WINDOW_SYSTEM
6037 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6038 {
6039 if (!get_next_display_element (it))
6040 {
6041 result = MOVE_POS_MATCH_OR_ZV;
6042 break;
6043 }
6044 if (BUFFER_POS_REACHED_P ())
6045 {
6046 if (ITERATOR_AT_END_OF_LINE_P (it))
6047 result = MOVE_POS_MATCH_OR_ZV;
6048 else
6049 result = MOVE_LINE_CONTINUED;
6050 break;
6051 }
6052 if (ITERATOR_AT_END_OF_LINE_P (it))
6053 {
6054 result = MOVE_NEWLINE_OR_CR;
6055 break;
6056 }
6057 }
6058 #endif /* HAVE_WINDOW_SYSTEM */
6059 }
6060 }
6061 else
6062 {
6063 it->current_x = x;
6064 it->max_ascent = ascent;
6065 it->max_descent = descent;
6066 }
6067
6068 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6069 IT_CHARPOS (*it)));
6070 result = MOVE_LINE_CONTINUED;
6071 break;
6072 }
6073 else if (BUFFER_POS_REACHED_P ())
6074 goto buffer_pos_reached;
6075 else if (new_x > it->first_visible_x)
6076 {
6077 /* Glyph is visible. Increment number of glyphs that
6078 would be displayed. */
6079 ++it->hpos;
6080 }
6081 else
6082 {
6083 /* Glyph is completely off the left margin of the display
6084 area. Nothing to do. */
6085 }
6086 }
6087
6088 if (result != MOVE_UNDEFINED)
6089 break;
6090 }
6091 else if (BUFFER_POS_REACHED_P ())
6092 {
6093 buffer_pos_reached:
6094 it->current_x = x;
6095 it->max_ascent = ascent;
6096 it->max_descent = descent;
6097 result = MOVE_POS_MATCH_OR_ZV;
6098 break;
6099 }
6100 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6101 {
6102 /* Stop when TO_X specified and reached. This check is
6103 necessary here because of lines consisting of a line end,
6104 only. The line end will not produce any glyphs and we
6105 would never get MOVE_X_REACHED. */
6106 xassert (it->nglyphs == 0);
6107 result = MOVE_X_REACHED;
6108 break;
6109 }
6110
6111 /* Is this a line end? If yes, we're done. */
6112 if (ITERATOR_AT_END_OF_LINE_P (it))
6113 {
6114 result = MOVE_NEWLINE_OR_CR;
6115 break;
6116 }
6117
6118 /* The current display element has been consumed. Advance
6119 to the next. */
6120 set_iterator_to_next (it, 1);
6121
6122 /* Stop if lines are truncated and IT's current x-position is
6123 past the right edge of the window now. */
6124 if (it->truncate_lines_p
6125 && it->current_x >= it->last_visible_x)
6126 {
6127 #ifdef HAVE_WINDOW_SYSTEM
6128 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6129 {
6130 if (!get_next_display_element (it)
6131 || BUFFER_POS_REACHED_P ())
6132 {
6133 result = MOVE_POS_MATCH_OR_ZV;
6134 break;
6135 }
6136 if (ITERATOR_AT_END_OF_LINE_P (it))
6137 {
6138 result = MOVE_NEWLINE_OR_CR;
6139 break;
6140 }
6141 }
6142 #endif /* HAVE_WINDOW_SYSTEM */
6143 result = MOVE_LINE_TRUNCATED;
6144 break;
6145 }
6146 }
6147
6148 #undef BUFFER_POS_REACHED_P
6149
6150 /* Restore the iterator settings altered at the beginning of this
6151 function. */
6152 it->glyph_row = saved_glyph_row;
6153 return result;
6154 }
6155
6156
6157 /* Move IT forward until it satisfies one or more of the criteria in
6158 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6159
6160 OP is a bit-mask that specifies where to stop, and in particular,
6161 which of those four position arguments makes a difference. See the
6162 description of enum move_operation_enum.
6163
6164 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6165 screen line, this function will set IT to the next position >
6166 TO_CHARPOS. */
6167
6168 void
6169 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6170 struct it *it;
6171 int to_charpos, to_x, to_y, to_vpos;
6172 int op;
6173 {
6174 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6175 int line_height;
6176 int reached = 0;
6177
6178 for (;;)
6179 {
6180 if (op & MOVE_TO_VPOS)
6181 {
6182 /* If no TO_CHARPOS and no TO_X specified, stop at the
6183 start of the line TO_VPOS. */
6184 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6185 {
6186 if (it->vpos == to_vpos)
6187 {
6188 reached = 1;
6189 break;
6190 }
6191 else
6192 skip = move_it_in_display_line_to (it, -1, -1, 0);
6193 }
6194 else
6195 {
6196 /* TO_VPOS >= 0 means stop at TO_X in the line at
6197 TO_VPOS, or at TO_POS, whichever comes first. */
6198 if (it->vpos == to_vpos)
6199 {
6200 reached = 2;
6201 break;
6202 }
6203
6204 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6205
6206 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6207 {
6208 reached = 3;
6209 break;
6210 }
6211 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6212 {
6213 /* We have reached TO_X but not in the line we want. */
6214 skip = move_it_in_display_line_to (it, to_charpos,
6215 -1, MOVE_TO_POS);
6216 if (skip == MOVE_POS_MATCH_OR_ZV)
6217 {
6218 reached = 4;
6219 break;
6220 }
6221 }
6222 }
6223 }
6224 else if (op & MOVE_TO_Y)
6225 {
6226 struct it it_backup;
6227
6228 /* TO_Y specified means stop at TO_X in the line containing
6229 TO_Y---or at TO_CHARPOS if this is reached first. The
6230 problem is that we can't really tell whether the line
6231 contains TO_Y before we have completely scanned it, and
6232 this may skip past TO_X. What we do is to first scan to
6233 TO_X.
6234
6235 If TO_X is not specified, use a TO_X of zero. The reason
6236 is to make the outcome of this function more predictable.
6237 If we didn't use TO_X == 0, we would stop at the end of
6238 the line which is probably not what a caller would expect
6239 to happen. */
6240 skip = move_it_in_display_line_to (it, to_charpos,
6241 ((op & MOVE_TO_X)
6242 ? to_x : 0),
6243 (MOVE_TO_X
6244 | (op & MOVE_TO_POS)));
6245
6246 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6247 if (skip == MOVE_POS_MATCH_OR_ZV)
6248 {
6249 reached = 5;
6250 break;
6251 }
6252
6253 /* If TO_X was reached, we would like to know whether TO_Y
6254 is in the line. This can only be said if we know the
6255 total line height which requires us to scan the rest of
6256 the line. */
6257 if (skip == MOVE_X_REACHED)
6258 {
6259 it_backup = *it;
6260 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6261 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6262 op & MOVE_TO_POS);
6263 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6264 }
6265
6266 /* Now, decide whether TO_Y is in this line. */
6267 line_height = it->max_ascent + it->max_descent;
6268 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6269
6270 if (to_y >= it->current_y
6271 && to_y < it->current_y + line_height)
6272 {
6273 if (skip == MOVE_X_REACHED)
6274 /* If TO_Y is in this line and TO_X was reached above,
6275 we scanned too far. We have to restore IT's settings
6276 to the ones before skipping. */
6277 *it = it_backup;
6278 reached = 6;
6279 }
6280 else if (skip == MOVE_X_REACHED)
6281 {
6282 skip = skip2;
6283 if (skip == MOVE_POS_MATCH_OR_ZV)
6284 reached = 7;
6285 }
6286
6287 if (reached)
6288 break;
6289 }
6290 else
6291 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6292
6293 switch (skip)
6294 {
6295 case MOVE_POS_MATCH_OR_ZV:
6296 reached = 8;
6297 goto out;
6298
6299 case MOVE_NEWLINE_OR_CR:
6300 set_iterator_to_next (it, 1);
6301 it->continuation_lines_width = 0;
6302 break;
6303
6304 case MOVE_LINE_TRUNCATED:
6305 it->continuation_lines_width = 0;
6306 reseat_at_next_visible_line_start (it, 0);
6307 if ((op & MOVE_TO_POS) != 0
6308 && IT_CHARPOS (*it) > to_charpos)
6309 {
6310 reached = 9;
6311 goto out;
6312 }
6313 break;
6314
6315 case MOVE_LINE_CONTINUED:
6316 it->continuation_lines_width += it->current_x;
6317 break;
6318
6319 default:
6320 abort ();
6321 }
6322
6323 /* Reset/increment for the next run. */
6324 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6325 it->current_x = it->hpos = 0;
6326 it->current_y += it->max_ascent + it->max_descent;
6327 ++it->vpos;
6328 last_height = it->max_ascent + it->max_descent;
6329 last_max_ascent = it->max_ascent;
6330 it->max_ascent = it->max_descent = 0;
6331 }
6332
6333 out:
6334
6335 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6336 }
6337
6338
6339 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6340
6341 If DY > 0, move IT backward at least that many pixels. DY = 0
6342 means move IT backward to the preceding line start or BEGV. This
6343 function may move over more than DY pixels if IT->current_y - DY
6344 ends up in the middle of a line; in this case IT->current_y will be
6345 set to the top of the line moved to. */
6346
6347 void
6348 move_it_vertically_backward (it, dy)
6349 struct it *it;
6350 int dy;
6351 {
6352 int nlines, h;
6353 struct it it2, it3;
6354 int start_pos;
6355
6356 move_further_back:
6357 xassert (dy >= 0);
6358
6359 start_pos = IT_CHARPOS (*it);
6360
6361 /* Estimate how many newlines we must move back. */
6362 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6363
6364 /* Set the iterator's position that many lines back. */
6365 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6366 back_to_previous_visible_line_start (it);
6367
6368 /* Reseat the iterator here. When moving backward, we don't want
6369 reseat to skip forward over invisible text, set up the iterator
6370 to deliver from overlay strings at the new position etc. So,
6371 use reseat_1 here. */
6372 reseat_1 (it, it->current.pos, 1);
6373
6374 /* We are now surely at a line start. */
6375 it->current_x = it->hpos = 0;
6376 it->continuation_lines_width = 0;
6377
6378 /* Move forward and see what y-distance we moved. First move to the
6379 start of the next line so that we get its height. We need this
6380 height to be able to tell whether we reached the specified
6381 y-distance. */
6382 it2 = *it;
6383 it2.max_ascent = it2.max_descent = 0;
6384 do
6385 {
6386 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6387 MOVE_TO_POS | MOVE_TO_VPOS);
6388 }
6389 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
6390 xassert (IT_CHARPOS (*it) >= BEGV);
6391 it3 = it2;
6392
6393 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6394 xassert (IT_CHARPOS (*it) >= BEGV);
6395 /* H is the actual vertical distance from the position in *IT
6396 and the starting position. */
6397 h = it2.current_y - it->current_y;
6398 /* NLINES is the distance in number of lines. */
6399 nlines = it2.vpos - it->vpos;
6400
6401 /* Correct IT's y and vpos position
6402 so that they are relative to the starting point. */
6403 it->vpos -= nlines;
6404 it->current_y -= h;
6405
6406 if (dy == 0)
6407 {
6408 /* DY == 0 means move to the start of the screen line. The
6409 value of nlines is > 0 if continuation lines were involved. */
6410 if (nlines > 0)
6411 move_it_by_lines (it, nlines, 1);
6412 #if 0
6413 /* I think this assert is bogus if buffer contains
6414 invisible text or images. KFS. */
6415 xassert (IT_CHARPOS (*it) <= start_pos);
6416 #endif
6417 }
6418 else
6419 {
6420 /* The y-position we try to reach, relative to *IT.
6421 Note that H has been subtracted in front of the if-statement. */
6422 int target_y = it->current_y + h - dy;
6423 int y0 = it3.current_y;
6424 int y1 = line_bottom_y (&it3);
6425 int line_height = y1 - y0;
6426
6427 /* If we did not reach target_y, try to move further backward if
6428 we can. If we moved too far backward, try to move forward. */
6429 if (target_y < it->current_y
6430 /* This is heuristic. In a window that's 3 lines high, with
6431 a line height of 13 pixels each, recentering with point
6432 on the bottom line will try to move -39/2 = 19 pixels
6433 backward. Try to avoid moving into the first line. */
6434 && (it->current_y - target_y
6435 > min (window_box_height (it->w), line_height * 2 / 3))
6436 && IT_CHARPOS (*it) > BEGV)
6437 {
6438 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6439 target_y - it->current_y));
6440 dy = it->current_y - target_y;
6441 goto move_further_back;
6442 }
6443 else if (target_y >= it->current_y + line_height
6444 && IT_CHARPOS (*it) < ZV)
6445 {
6446 /* Should move forward by at least one line, maybe more.
6447
6448 Note: Calling move_it_by_lines can be expensive on
6449 terminal frames, where compute_motion is used (via
6450 vmotion) to do the job, when there are very long lines
6451 and truncate-lines is nil. That's the reason for
6452 treating terminal frames specially here. */
6453
6454 if (!FRAME_WINDOW_P (it->f))
6455 move_it_vertically (it, target_y - (it->current_y + line_height));
6456 else
6457 {
6458 do
6459 {
6460 move_it_by_lines (it, 1, 1);
6461 }
6462 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6463 }
6464
6465 #if 0
6466 /* I think this assert is bogus if buffer contains
6467 invisible text or images. KFS. */
6468 xassert (IT_CHARPOS (*it) >= BEGV);
6469 #endif
6470 }
6471 }
6472 }
6473
6474
6475 /* Move IT by a specified amount of pixel lines DY. DY negative means
6476 move backwards. DY = 0 means move to start of screen line. At the
6477 end, IT will be on the start of a screen line. */
6478
6479 void
6480 move_it_vertically (it, dy)
6481 struct it *it;
6482 int dy;
6483 {
6484 if (dy <= 0)
6485 move_it_vertically_backward (it, -dy);
6486 else
6487 {
6488 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6489 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6490 MOVE_TO_POS | MOVE_TO_Y);
6491 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6492
6493 /* If buffer ends in ZV without a newline, move to the start of
6494 the line to satisfy the post-condition. */
6495 if (IT_CHARPOS (*it) == ZV
6496 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6497 move_it_by_lines (it, 0, 0);
6498 }
6499 }
6500
6501
6502 /* Move iterator IT past the end of the text line it is in. */
6503
6504 void
6505 move_it_past_eol (it)
6506 struct it *it;
6507 {
6508 enum move_it_result rc;
6509
6510 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6511 if (rc == MOVE_NEWLINE_OR_CR)
6512 set_iterator_to_next (it, 0);
6513 }
6514
6515
6516 #if 0 /* Currently not used. */
6517
6518 /* Return non-zero if some text between buffer positions START_CHARPOS
6519 and END_CHARPOS is invisible. IT->window is the window for text
6520 property lookup. */
6521
6522 static int
6523 invisible_text_between_p (it, start_charpos, end_charpos)
6524 struct it *it;
6525 int start_charpos, end_charpos;
6526 {
6527 Lisp_Object prop, limit;
6528 int invisible_found_p;
6529
6530 xassert (it != NULL && start_charpos <= end_charpos);
6531
6532 /* Is text at START invisible? */
6533 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6534 it->window);
6535 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6536 invisible_found_p = 1;
6537 else
6538 {
6539 limit = Fnext_single_char_property_change (make_number (start_charpos),
6540 Qinvisible, Qnil,
6541 make_number (end_charpos));
6542 invisible_found_p = XFASTINT (limit) < end_charpos;
6543 }
6544
6545 return invisible_found_p;
6546 }
6547
6548 #endif /* 0 */
6549
6550
6551 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6552 negative means move up. DVPOS == 0 means move to the start of the
6553 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6554 NEED_Y_P is zero, IT->current_y will be left unchanged.
6555
6556 Further optimization ideas: If we would know that IT->f doesn't use
6557 a face with proportional font, we could be faster for
6558 truncate-lines nil. */
6559
6560 void
6561 move_it_by_lines (it, dvpos, need_y_p)
6562 struct it *it;
6563 int dvpos, need_y_p;
6564 {
6565 struct position pos;
6566
6567 if (!FRAME_WINDOW_P (it->f))
6568 {
6569 struct text_pos textpos;
6570
6571 /* We can use vmotion on frames without proportional fonts. */
6572 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6573 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6574 reseat (it, textpos, 1);
6575 it->vpos += pos.vpos;
6576 it->current_y += pos.vpos;
6577 }
6578 else if (dvpos == 0)
6579 {
6580 /* DVPOS == 0 means move to the start of the screen line. */
6581 move_it_vertically_backward (it, 0);
6582 xassert (it->current_x == 0 && it->hpos == 0);
6583 /* Let next call to line_bottom_y calculate real line height */
6584 last_height = 0;
6585 }
6586 else if (dvpos > 0)
6587 {
6588 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6589 if (!IT_POS_VALID_AFTER_MOVE_P (it))
6590 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
6591 }
6592 else
6593 {
6594 struct it it2;
6595 int start_charpos, i;
6596
6597 /* Start at the beginning of the screen line containing IT's
6598 position. This may actually move vertically backwards,
6599 in case of overlays, so adjust dvpos accordingly. */
6600 dvpos += it->vpos;
6601 move_it_vertically_backward (it, 0);
6602 dvpos -= it->vpos;
6603
6604 /* Go back -DVPOS visible lines and reseat the iterator there. */
6605 start_charpos = IT_CHARPOS (*it);
6606 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
6607 back_to_previous_visible_line_start (it);
6608 reseat (it, it->current.pos, 1);
6609
6610 /* Move further back if we end up in a string or an image. */
6611 while (!IT_POS_VALID_AFTER_MOVE_P (it))
6612 {
6613 /* First try to move to start of display line. */
6614 dvpos += it->vpos;
6615 move_it_vertically_backward (it, 0);
6616 dvpos -= it->vpos;
6617 if (IT_POS_VALID_AFTER_MOVE_P (it))
6618 break;
6619 /* If start of line is still in string or image,
6620 move further back. */
6621 back_to_previous_visible_line_start (it);
6622 reseat (it, it->current.pos, 1);
6623 dvpos--;
6624 }
6625
6626 it->current_x = it->hpos = 0;
6627
6628 /* Above call may have moved too far if continuation lines
6629 are involved. Scan forward and see if it did. */
6630 it2 = *it;
6631 it2.vpos = it2.current_y = 0;
6632 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6633 it->vpos -= it2.vpos;
6634 it->current_y -= it2.current_y;
6635 it->current_x = it->hpos = 0;
6636
6637 /* If we moved too far back, move IT some lines forward. */
6638 if (it2.vpos > -dvpos)
6639 {
6640 int delta = it2.vpos + dvpos;
6641 it2 = *it;
6642 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6643 /* Move back again if we got too far ahead. */
6644 if (IT_CHARPOS (*it) >= start_charpos)
6645 *it = it2;
6646 }
6647 }
6648 }
6649
6650 /* Return 1 if IT points into the middle of a display vector. */
6651
6652 int
6653 in_display_vector_p (it)
6654 struct it *it;
6655 {
6656 return (it->method == GET_FROM_DISPLAY_VECTOR
6657 && it->current.dpvec_index > 0
6658 && it->dpvec + it->current.dpvec_index != it->dpend);
6659 }
6660
6661 \f
6662 /***********************************************************************
6663 Messages
6664 ***********************************************************************/
6665
6666
6667 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6668 to *Messages*. */
6669
6670 void
6671 add_to_log (format, arg1, arg2)
6672 char *format;
6673 Lisp_Object arg1, arg2;
6674 {
6675 Lisp_Object args[3];
6676 Lisp_Object msg, fmt;
6677 char *buffer;
6678 int len;
6679 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6680 USE_SAFE_ALLOCA;
6681
6682 /* Do nothing if called asynchronously. Inserting text into
6683 a buffer may call after-change-functions and alike and
6684 that would means running Lisp asynchronously. */
6685 if (handling_signal)
6686 return;
6687
6688 fmt = msg = Qnil;
6689 GCPRO4 (fmt, msg, arg1, arg2);
6690
6691 args[0] = fmt = build_string (format);
6692 args[1] = arg1;
6693 args[2] = arg2;
6694 msg = Fformat (3, args);
6695
6696 len = SBYTES (msg) + 1;
6697 SAFE_ALLOCA (buffer, char *, len);
6698 bcopy (SDATA (msg), buffer, len);
6699
6700 message_dolog (buffer, len - 1, 1, 0);
6701 SAFE_FREE ();
6702
6703 UNGCPRO;
6704 }
6705
6706
6707 /* Output a newline in the *Messages* buffer if "needs" one. */
6708
6709 void
6710 message_log_maybe_newline ()
6711 {
6712 if (message_log_need_newline)
6713 message_dolog ("", 0, 1, 0);
6714 }
6715
6716
6717 /* Add a string M of length NBYTES to the message log, optionally
6718 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6719 nonzero, means interpret the contents of M as multibyte. This
6720 function calls low-level routines in order to bypass text property
6721 hooks, etc. which might not be safe to run. */
6722
6723 void
6724 message_dolog (m, nbytes, nlflag, multibyte)
6725 const char *m;
6726 int nbytes, nlflag, multibyte;
6727 {
6728 if (!NILP (Vmemory_full))
6729 return;
6730
6731 if (!NILP (Vmessage_log_max))
6732 {
6733 struct buffer *oldbuf;
6734 Lisp_Object oldpoint, oldbegv, oldzv;
6735 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6736 int point_at_end = 0;
6737 int zv_at_end = 0;
6738 Lisp_Object old_deactivate_mark, tem;
6739 struct gcpro gcpro1;
6740
6741 old_deactivate_mark = Vdeactivate_mark;
6742 oldbuf = current_buffer;
6743 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6744 current_buffer->undo_list = Qt;
6745
6746 oldpoint = message_dolog_marker1;
6747 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6748 oldbegv = message_dolog_marker2;
6749 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6750 oldzv = message_dolog_marker3;
6751 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6752 GCPRO1 (old_deactivate_mark);
6753
6754 if (PT == Z)
6755 point_at_end = 1;
6756 if (ZV == Z)
6757 zv_at_end = 1;
6758
6759 BEGV = BEG;
6760 BEGV_BYTE = BEG_BYTE;
6761 ZV = Z;
6762 ZV_BYTE = Z_BYTE;
6763 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6764
6765 /* Insert the string--maybe converting multibyte to single byte
6766 or vice versa, so that all the text fits the buffer. */
6767 if (multibyte
6768 && NILP (current_buffer->enable_multibyte_characters))
6769 {
6770 int i, c, char_bytes;
6771 unsigned char work[1];
6772
6773 /* Convert a multibyte string to single-byte
6774 for the *Message* buffer. */
6775 for (i = 0; i < nbytes; i += char_bytes)
6776 {
6777 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6778 work[0] = (SINGLE_BYTE_CHAR_P (c)
6779 ? c
6780 : multibyte_char_to_unibyte (c, Qnil));
6781 insert_1_both (work, 1, 1, 1, 0, 0);
6782 }
6783 }
6784 else if (! multibyte
6785 && ! NILP (current_buffer->enable_multibyte_characters))
6786 {
6787 int i, c, char_bytes;
6788 unsigned char *msg = (unsigned char *) m;
6789 unsigned char str[MAX_MULTIBYTE_LENGTH];
6790 /* Convert a single-byte string to multibyte
6791 for the *Message* buffer. */
6792 for (i = 0; i < nbytes; i++)
6793 {
6794 c = unibyte_char_to_multibyte (msg[i]);
6795 char_bytes = CHAR_STRING (c, str);
6796 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6797 }
6798 }
6799 else if (nbytes)
6800 insert_1 (m, nbytes, 1, 0, 0);
6801
6802 if (nlflag)
6803 {
6804 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6805 insert_1 ("\n", 1, 1, 0, 0);
6806
6807 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6808 this_bol = PT;
6809 this_bol_byte = PT_BYTE;
6810
6811 /* See if this line duplicates the previous one.
6812 If so, combine duplicates. */
6813 if (this_bol > BEG)
6814 {
6815 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6816 prev_bol = PT;
6817 prev_bol_byte = PT_BYTE;
6818
6819 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6820 this_bol, this_bol_byte);
6821 if (dup)
6822 {
6823 del_range_both (prev_bol, prev_bol_byte,
6824 this_bol, this_bol_byte, 0);
6825 if (dup > 1)
6826 {
6827 char dupstr[40];
6828 int duplen;
6829
6830 /* If you change this format, don't forget to also
6831 change message_log_check_duplicate. */
6832 sprintf (dupstr, " [%d times]", dup);
6833 duplen = strlen (dupstr);
6834 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6835 insert_1 (dupstr, duplen, 1, 0, 1);
6836 }
6837 }
6838 }
6839
6840 /* If we have more than the desired maximum number of lines
6841 in the *Messages* buffer now, delete the oldest ones.
6842 This is safe because we don't have undo in this buffer. */
6843
6844 if (NATNUMP (Vmessage_log_max))
6845 {
6846 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6847 -XFASTINT (Vmessage_log_max) - 1, 0);
6848 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6849 }
6850 }
6851 BEGV = XMARKER (oldbegv)->charpos;
6852 BEGV_BYTE = marker_byte_position (oldbegv);
6853
6854 if (zv_at_end)
6855 {
6856 ZV = Z;
6857 ZV_BYTE = Z_BYTE;
6858 }
6859 else
6860 {
6861 ZV = XMARKER (oldzv)->charpos;
6862 ZV_BYTE = marker_byte_position (oldzv);
6863 }
6864
6865 if (point_at_end)
6866 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6867 else
6868 /* We can't do Fgoto_char (oldpoint) because it will run some
6869 Lisp code. */
6870 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6871 XMARKER (oldpoint)->bytepos);
6872
6873 UNGCPRO;
6874 unchain_marker (XMARKER (oldpoint));
6875 unchain_marker (XMARKER (oldbegv));
6876 unchain_marker (XMARKER (oldzv));
6877
6878 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6879 set_buffer_internal (oldbuf);
6880 if (NILP (tem))
6881 windows_or_buffers_changed = old_windows_or_buffers_changed;
6882 message_log_need_newline = !nlflag;
6883 Vdeactivate_mark = old_deactivate_mark;
6884 }
6885 }
6886
6887
6888 /* We are at the end of the buffer after just having inserted a newline.
6889 (Note: We depend on the fact we won't be crossing the gap.)
6890 Check to see if the most recent message looks a lot like the previous one.
6891 Return 0 if different, 1 if the new one should just replace it, or a
6892 value N > 1 if we should also append " [N times]". */
6893
6894 static int
6895 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6896 int prev_bol, this_bol;
6897 int prev_bol_byte, this_bol_byte;
6898 {
6899 int i;
6900 int len = Z_BYTE - 1 - this_bol_byte;
6901 int seen_dots = 0;
6902 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6903 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6904
6905 for (i = 0; i < len; i++)
6906 {
6907 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6908 seen_dots = 1;
6909 if (p1[i] != p2[i])
6910 return seen_dots;
6911 }
6912 p1 += len;
6913 if (*p1 == '\n')
6914 return 2;
6915 if (*p1++ == ' ' && *p1++ == '[')
6916 {
6917 int n = 0;
6918 while (*p1 >= '0' && *p1 <= '9')
6919 n = n * 10 + *p1++ - '0';
6920 if (strncmp (p1, " times]\n", 8) == 0)
6921 return n+1;
6922 }
6923 return 0;
6924 }
6925 \f
6926
6927 /* Display an echo area message M with a specified length of NBYTES
6928 bytes. The string may include null characters. If M is 0, clear
6929 out any existing message, and let the mini-buffer text show
6930 through.
6931
6932 The buffer M must continue to exist until after the echo area gets
6933 cleared or some other message gets displayed there. This means do
6934 not pass text that is stored in a Lisp string; do not pass text in
6935 a buffer that was alloca'd. */
6936
6937 void
6938 message2 (m, nbytes, multibyte)
6939 const char *m;
6940 int nbytes;
6941 int multibyte;
6942 {
6943 /* First flush out any partial line written with print. */
6944 message_log_maybe_newline ();
6945 if (m)
6946 message_dolog (m, nbytes, 1, multibyte);
6947 message2_nolog (m, nbytes, multibyte);
6948 }
6949
6950
6951 /* The non-logging counterpart of message2. */
6952
6953 void
6954 message2_nolog (m, nbytes, multibyte)
6955 const char *m;
6956 int nbytes, multibyte;
6957 {
6958 struct frame *sf = SELECTED_FRAME ();
6959 message_enable_multibyte = multibyte;
6960
6961 if (noninteractive)
6962 {
6963 if (noninteractive_need_newline)
6964 putc ('\n', stderr);
6965 noninteractive_need_newline = 0;
6966 if (m)
6967 fwrite (m, nbytes, 1, stderr);
6968 if (cursor_in_echo_area == 0)
6969 fprintf (stderr, "\n");
6970 fflush (stderr);
6971 }
6972 /* A null message buffer means that the frame hasn't really been
6973 initialized yet. Error messages get reported properly by
6974 cmd_error, so this must be just an informative message; toss it. */
6975 else if (INTERACTIVE
6976 && sf->glyphs_initialized_p
6977 && FRAME_MESSAGE_BUF (sf))
6978 {
6979 Lisp_Object mini_window;
6980 struct frame *f;
6981
6982 /* Get the frame containing the mini-buffer
6983 that the selected frame is using. */
6984 mini_window = FRAME_MINIBUF_WINDOW (sf);
6985 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6986
6987 FRAME_SAMPLE_VISIBILITY (f);
6988 if (FRAME_VISIBLE_P (sf)
6989 && ! FRAME_VISIBLE_P (f))
6990 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6991
6992 if (m)
6993 {
6994 set_message (m, Qnil, nbytes, multibyte);
6995 if (minibuffer_auto_raise)
6996 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6997 }
6998 else
6999 clear_message (1, 1);
7000
7001 do_pending_window_change (0);
7002 echo_area_display (1);
7003 do_pending_window_change (0);
7004 if (FRAME_DEVICE (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7005 (*FRAME_DEVICE (f)->frame_up_to_date_hook) (f);
7006 }
7007 }
7008
7009
7010 /* Display an echo area message M with a specified length of NBYTES
7011 bytes. The string may include null characters. If M is not a
7012 string, clear out any existing message, and let the mini-buffer
7013 text show through.
7014
7015 This function cancels echoing. */
7016
7017 void
7018 message3 (m, nbytes, multibyte)
7019 Lisp_Object m;
7020 int nbytes;
7021 int multibyte;
7022 {
7023 struct gcpro gcpro1;
7024
7025 GCPRO1 (m);
7026 clear_message (1,1);
7027 cancel_echoing ();
7028
7029 /* First flush out any partial line written with print. */
7030 message_log_maybe_newline ();
7031 if (STRINGP (m))
7032 message_dolog (SDATA (m), nbytes, 1, multibyte);
7033 message3_nolog (m, nbytes, multibyte);
7034
7035 UNGCPRO;
7036 }
7037
7038
7039 /* The non-logging version of message3.
7040 This does not cancel echoing, because it is used for echoing.
7041 Perhaps we need to make a separate function for echoing
7042 and make this cancel echoing. */
7043
7044 void
7045 message3_nolog (m, nbytes, multibyte)
7046 Lisp_Object m;
7047 int nbytes, multibyte;
7048 {
7049 struct frame *sf = SELECTED_FRAME ();
7050 message_enable_multibyte = multibyte;
7051
7052 if (noninteractive)
7053 {
7054 if (noninteractive_need_newline)
7055 putc ('\n', stderr);
7056 noninteractive_need_newline = 0;
7057 if (STRINGP (m))
7058 fwrite (SDATA (m), nbytes, 1, stderr);
7059 if (cursor_in_echo_area == 0)
7060 fprintf (stderr, "\n");
7061 fflush (stderr);
7062 }
7063 /* A null message buffer means that the frame hasn't really been
7064 initialized yet. Error messages get reported properly by
7065 cmd_error, so this must be just an informative message; toss it. */
7066 else if (INTERACTIVE
7067 && sf->glyphs_initialized_p
7068 && FRAME_MESSAGE_BUF (sf))
7069 {
7070 Lisp_Object mini_window;
7071 Lisp_Object frame;
7072 struct frame *f;
7073
7074 /* Get the frame containing the mini-buffer
7075 that the selected frame is using. */
7076 mini_window = FRAME_MINIBUF_WINDOW (sf);
7077 frame = XWINDOW (mini_window)->frame;
7078 f = XFRAME (frame);
7079
7080 FRAME_SAMPLE_VISIBILITY (f);
7081 if (FRAME_VISIBLE_P (sf)
7082 && !FRAME_VISIBLE_P (f))
7083 Fmake_frame_visible (frame);
7084
7085 if (STRINGP (m) && SCHARS (m) > 0)
7086 {
7087 set_message (NULL, m, nbytes, multibyte);
7088 if (minibuffer_auto_raise)
7089 Fraise_frame (frame);
7090 /* Assume we are not echoing.
7091 (If we are, echo_now will override this.) */
7092 echo_message_buffer = Qnil;
7093 }
7094 else
7095 clear_message (1, 1);
7096
7097 do_pending_window_change (0);
7098 echo_area_display (1);
7099 do_pending_window_change (0);
7100 if (FRAME_DEVICE (f)->frame_up_to_date_hook != 0 && ! gc_in_progress)
7101 (*FRAME_DEVICE (f)->frame_up_to_date_hook) (f);
7102 }
7103 }
7104
7105
7106 /* Display a null-terminated echo area message M. If M is 0, clear
7107 out any existing message, and let the mini-buffer text show through.
7108
7109 The buffer M must continue to exist until after the echo area gets
7110 cleared or some other message gets displayed there. Do not pass
7111 text that is stored in a Lisp string. Do not pass text in a buffer
7112 that was alloca'd. */
7113
7114 void
7115 message1 (m)
7116 char *m;
7117 {
7118 message2 (m, (m ? strlen (m) : 0), 0);
7119 }
7120
7121
7122 /* The non-logging counterpart of message1. */
7123
7124 void
7125 message1_nolog (m)
7126 char *m;
7127 {
7128 message2_nolog (m, (m ? strlen (m) : 0), 0);
7129 }
7130
7131 /* Display a message M which contains a single %s
7132 which gets replaced with STRING. */
7133
7134 void
7135 message_with_string (m, string, log)
7136 char *m;
7137 Lisp_Object string;
7138 int log;
7139 {
7140 CHECK_STRING (string);
7141
7142 if (noninteractive)
7143 {
7144 if (m)
7145 {
7146 if (noninteractive_need_newline)
7147 putc ('\n', stderr);
7148 noninteractive_need_newline = 0;
7149 fprintf (stderr, m, SDATA (string));
7150 if (cursor_in_echo_area == 0)
7151 fprintf (stderr, "\n");
7152 fflush (stderr);
7153 }
7154 }
7155 else if (INTERACTIVE)
7156 {
7157 /* The frame whose minibuffer we're going to display the message on.
7158 It may be larger than the selected frame, so we need
7159 to use its buffer, not the selected frame's buffer. */
7160 Lisp_Object mini_window;
7161 struct frame *f, *sf = SELECTED_FRAME ();
7162
7163 /* Get the frame containing the minibuffer
7164 that the selected frame is using. */
7165 mini_window = FRAME_MINIBUF_WINDOW (sf);
7166 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7167
7168 /* A null message buffer means that the frame hasn't really been
7169 initialized yet. Error messages get reported properly by
7170 cmd_error, so this must be just an informative message; toss it. */
7171 if (FRAME_MESSAGE_BUF (f))
7172 {
7173 Lisp_Object args[2], message;
7174 struct gcpro gcpro1, gcpro2;
7175
7176 args[0] = build_string (m);
7177 args[1] = message = string;
7178 GCPRO2 (args[0], message);
7179 gcpro1.nvars = 2;
7180
7181 message = Fformat (2, args);
7182
7183 if (log)
7184 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7185 else
7186 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7187
7188 UNGCPRO;
7189
7190 /* Print should start at the beginning of the message
7191 buffer next time. */
7192 message_buf_print = 0;
7193 }
7194 }
7195 }
7196
7197
7198 /* Dump an informative message to the minibuf. If M is 0, clear out
7199 any existing message, and let the mini-buffer text show through. */
7200
7201 /* VARARGS 1 */
7202 void
7203 message (m, a1, a2, a3)
7204 char *m;
7205 EMACS_INT a1, a2, a3;
7206 {
7207 if (noninteractive)
7208 {
7209 if (m)
7210 {
7211 if (noninteractive_need_newline)
7212 putc ('\n', stderr);
7213 noninteractive_need_newline = 0;
7214 fprintf (stderr, m, a1, a2, a3);
7215 if (cursor_in_echo_area == 0)
7216 fprintf (stderr, "\n");
7217 fflush (stderr);
7218 }
7219 }
7220 else if (INTERACTIVE)
7221 {
7222 /* The frame whose mini-buffer we're going to display the message
7223 on. It may be larger than the selected frame, so we need to
7224 use its buffer, not the selected frame's buffer. */
7225 Lisp_Object mini_window;
7226 struct frame *f, *sf = SELECTED_FRAME ();
7227
7228 /* Get the frame containing the mini-buffer
7229 that the selected frame is using. */
7230 mini_window = FRAME_MINIBUF_WINDOW (sf);
7231 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7232
7233 /* A null message buffer means that the frame hasn't really been
7234 initialized yet. Error messages get reported properly by
7235 cmd_error, so this must be just an informative message; toss
7236 it. */
7237 if (FRAME_MESSAGE_BUF (f))
7238 {
7239 if (m)
7240 {
7241 int len;
7242 #ifdef NO_ARG_ARRAY
7243 char *a[3];
7244 a[0] = (char *) a1;
7245 a[1] = (char *) a2;
7246 a[2] = (char *) a3;
7247
7248 len = doprnt (FRAME_MESSAGE_BUF (f),
7249 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7250 #else
7251 len = doprnt (FRAME_MESSAGE_BUF (f),
7252 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7253 (char **) &a1);
7254 #endif /* NO_ARG_ARRAY */
7255
7256 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7257 }
7258 else
7259 message1 (0);
7260
7261 /* Print should start at the beginning of the message
7262 buffer next time. */
7263 message_buf_print = 0;
7264 }
7265 }
7266 }
7267
7268
7269 /* The non-logging version of message. */
7270
7271 void
7272 message_nolog (m, a1, a2, a3)
7273 char *m;
7274 EMACS_INT a1, a2, a3;
7275 {
7276 Lisp_Object old_log_max;
7277 old_log_max = Vmessage_log_max;
7278 Vmessage_log_max = Qnil;
7279 message (m, a1, a2, a3);
7280 Vmessage_log_max = old_log_max;
7281 }
7282
7283
7284 /* Display the current message in the current mini-buffer. This is
7285 only called from error handlers in process.c, and is not time
7286 critical. */
7287
7288 void
7289 update_echo_area ()
7290 {
7291 if (!NILP (echo_area_buffer[0]))
7292 {
7293 Lisp_Object string;
7294 string = Fcurrent_message ();
7295 message3 (string, SBYTES (string),
7296 !NILP (current_buffer->enable_multibyte_characters));
7297 }
7298 }
7299
7300
7301 /* Make sure echo area buffers in `echo_buffers' are live.
7302 If they aren't, make new ones. */
7303
7304 static void
7305 ensure_echo_area_buffers ()
7306 {
7307 int i;
7308
7309 for (i = 0; i < 2; ++i)
7310 if (!BUFFERP (echo_buffer[i])
7311 || NILP (XBUFFER (echo_buffer[i])->name))
7312 {
7313 char name[30];
7314 Lisp_Object old_buffer;
7315 int j;
7316
7317 old_buffer = echo_buffer[i];
7318 sprintf (name, " *Echo Area %d*", i);
7319 echo_buffer[i] = Fget_buffer_create (build_string (name));
7320 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7321
7322 for (j = 0; j < 2; ++j)
7323 if (EQ (old_buffer, echo_area_buffer[j]))
7324 echo_area_buffer[j] = echo_buffer[i];
7325 }
7326 }
7327
7328
7329 /* Call FN with args A1..A4 with either the current or last displayed
7330 echo_area_buffer as current buffer.
7331
7332 WHICH zero means use the current message buffer
7333 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7334 from echo_buffer[] and clear it.
7335
7336 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7337 suitable buffer from echo_buffer[] and clear it.
7338
7339 If WHICH < 0, set echo_area_buffer[1] to echo_area_buffer[0], so
7340 that the current message becomes the last displayed one, make
7341 choose a suitable buffer for echo_area_buffer[0], and clear it.
7342
7343 Value is what FN returns. */
7344
7345 static int
7346 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7347 struct window *w;
7348 int which;
7349 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7350 EMACS_INT a1;
7351 Lisp_Object a2;
7352 EMACS_INT a3, a4;
7353 {
7354 Lisp_Object buffer;
7355 int this_one, the_other, clear_buffer_p, rc;
7356 int count = SPECPDL_INDEX ();
7357
7358 /* If buffers aren't live, make new ones. */
7359 ensure_echo_area_buffers ();
7360
7361 clear_buffer_p = 0;
7362
7363 if (which == 0)
7364 this_one = 0, the_other = 1;
7365 else if (which > 0)
7366 this_one = 1, the_other = 0;
7367 else
7368 {
7369 this_one = 0, the_other = 1;
7370 clear_buffer_p = 1;
7371
7372 /* We need a fresh one in case the current echo buffer equals
7373 the one containing the last displayed echo area message. */
7374 if (!NILP (echo_area_buffer[this_one])
7375 && EQ (echo_area_buffer[this_one], echo_area_buffer[the_other]))
7376 echo_area_buffer[this_one] = Qnil;
7377 }
7378
7379 /* Choose a suitable buffer from echo_buffer[] is we don't
7380 have one. */
7381 if (NILP (echo_area_buffer[this_one]))
7382 {
7383 echo_area_buffer[this_one]
7384 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7385 ? echo_buffer[the_other]
7386 : echo_buffer[this_one]);
7387 clear_buffer_p = 1;
7388 }
7389
7390 buffer = echo_area_buffer[this_one];
7391
7392 /* Don't get confused by reusing the buffer used for echoing
7393 for a different purpose. */
7394 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7395 cancel_echoing ();
7396
7397 record_unwind_protect (unwind_with_echo_area_buffer,
7398 with_echo_area_buffer_unwind_data (w));
7399
7400 /* Make the echo area buffer current. Note that for display
7401 purposes, it is not necessary that the displayed window's buffer
7402 == current_buffer, except for text property lookup. So, let's
7403 only set that buffer temporarily here without doing a full
7404 Fset_window_buffer. We must also change w->pointm, though,
7405 because otherwise an assertions in unshow_buffer fails, and Emacs
7406 aborts. */
7407 set_buffer_internal_1 (XBUFFER (buffer));
7408 if (w)
7409 {
7410 w->buffer = buffer;
7411 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7412 }
7413
7414 current_buffer->undo_list = Qt;
7415 current_buffer->read_only = Qnil;
7416 specbind (Qinhibit_read_only, Qt);
7417 specbind (Qinhibit_modification_hooks, Qt);
7418
7419 if (clear_buffer_p && Z > BEG)
7420 del_range (BEG, Z);
7421
7422 xassert (BEGV >= BEG);
7423 xassert (ZV <= Z && ZV >= BEGV);
7424
7425 rc = fn (a1, a2, a3, a4);
7426
7427 xassert (BEGV >= BEG);
7428 xassert (ZV <= Z && ZV >= BEGV);
7429
7430 unbind_to (count, Qnil);
7431 return rc;
7432 }
7433
7434
7435 /* Save state that should be preserved around the call to the function
7436 FN called in with_echo_area_buffer. */
7437
7438 static Lisp_Object
7439 with_echo_area_buffer_unwind_data (w)
7440 struct window *w;
7441 {
7442 int i = 0;
7443 Lisp_Object vector;
7444
7445 /* Reduce consing by keeping one vector in
7446 Vwith_echo_area_save_vector. */
7447 vector = Vwith_echo_area_save_vector;
7448 Vwith_echo_area_save_vector = Qnil;
7449
7450 if (NILP (vector))
7451 vector = Fmake_vector (make_number (7), Qnil);
7452
7453 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7454 AREF (vector, i) = Vdeactivate_mark, ++i;
7455 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7456
7457 if (w)
7458 {
7459 XSETWINDOW (AREF (vector, i), w); ++i;
7460 AREF (vector, i) = w->buffer; ++i;
7461 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7462 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7463 }
7464 else
7465 {
7466 int end = i + 4;
7467 for (; i < end; ++i)
7468 AREF (vector, i) = Qnil;
7469 }
7470
7471 xassert (i == ASIZE (vector));
7472 return vector;
7473 }
7474
7475
7476 /* Restore global state from VECTOR which was created by
7477 with_echo_area_buffer_unwind_data. */
7478
7479 static Lisp_Object
7480 unwind_with_echo_area_buffer (vector)
7481 Lisp_Object vector;
7482 {
7483 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7484 Vdeactivate_mark = AREF (vector, 1);
7485 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7486
7487 if (WINDOWP (AREF (vector, 3)))
7488 {
7489 struct window *w;
7490 Lisp_Object buffer, charpos, bytepos;
7491
7492 w = XWINDOW (AREF (vector, 3));
7493 buffer = AREF (vector, 4);
7494 charpos = AREF (vector, 5);
7495 bytepos = AREF (vector, 6);
7496
7497 w->buffer = buffer;
7498 set_marker_both (w->pointm, buffer,
7499 XFASTINT (charpos), XFASTINT (bytepos));
7500 }
7501
7502 Vwith_echo_area_save_vector = vector;
7503 return Qnil;
7504 }
7505
7506
7507 /* Set up the echo area for use by print functions. MULTIBYTE_P
7508 non-zero means we will print multibyte. */
7509
7510 void
7511 setup_echo_area_for_printing (multibyte_p)
7512 int multibyte_p;
7513 {
7514 /* If we can't find an echo area any more, exit. */
7515 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7516 Fkill_emacs (Qnil);
7517
7518 ensure_echo_area_buffers ();
7519
7520 if (!message_buf_print)
7521 {
7522 /* A message has been output since the last time we printed.
7523 Choose a fresh echo area buffer. */
7524 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7525 echo_area_buffer[0] = echo_buffer[1];
7526 else
7527 echo_area_buffer[0] = echo_buffer[0];
7528
7529 /* Switch to that buffer and clear it. */
7530 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7531 current_buffer->truncate_lines = Qnil;
7532
7533 if (Z > BEG)
7534 {
7535 int count = SPECPDL_INDEX ();
7536 specbind (Qinhibit_read_only, Qt);
7537 /* Note that undo recording is always disabled. */
7538 del_range (BEG, Z);
7539 unbind_to (count, Qnil);
7540 }
7541 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7542
7543 /* Set up the buffer for the multibyteness we need. */
7544 if (multibyte_p
7545 != !NILP (current_buffer->enable_multibyte_characters))
7546 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7547
7548 /* Raise the frame containing the echo area. */
7549 if (minibuffer_auto_raise)
7550 {
7551 struct frame *sf = SELECTED_FRAME ();
7552 Lisp_Object mini_window;
7553 mini_window = FRAME_MINIBUF_WINDOW (sf);
7554 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7555 }
7556
7557 message_log_maybe_newline ();
7558 message_buf_print = 1;
7559 }
7560 else
7561 {
7562 if (NILP (echo_area_buffer[0]))
7563 {
7564 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7565 echo_area_buffer[0] = echo_buffer[1];
7566 else
7567 echo_area_buffer[0] = echo_buffer[0];
7568 }
7569
7570 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7571 {
7572 /* Someone switched buffers between print requests. */
7573 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7574 current_buffer->truncate_lines = Qnil;
7575 }
7576 }
7577 }
7578
7579
7580 /* Display an echo area message in window W. Value is non-zero if W's
7581 height is changed. If display_last_displayed_message_p is
7582 non-zero, display the message that was last displayed, otherwise
7583 display the current message. */
7584
7585 static int
7586 display_echo_area (w)
7587 struct window *w;
7588 {
7589 int i, no_message_p, window_height_changed_p, count;
7590
7591 /* Temporarily disable garbage collections while displaying the echo
7592 area. This is done because a GC can print a message itself.
7593 That message would modify the echo area buffer's contents while a
7594 redisplay of the buffer is going on, and seriously confuse
7595 redisplay. */
7596 count = inhibit_garbage_collection ();
7597
7598 /* If there is no message, we must call display_echo_area_1
7599 nevertheless because it resizes the window. But we will have to
7600 reset the echo_area_buffer in question to nil at the end because
7601 with_echo_area_buffer will sets it to an empty buffer. */
7602 i = display_last_displayed_message_p ? 1 : 0;
7603 no_message_p = NILP (echo_area_buffer[i]);
7604
7605 window_height_changed_p
7606 = with_echo_area_buffer (w, display_last_displayed_message_p,
7607 display_echo_area_1,
7608 (EMACS_INT) w, Qnil, 0, 0);
7609
7610 if (no_message_p)
7611 echo_area_buffer[i] = Qnil;
7612
7613 unbind_to (count, Qnil);
7614 return window_height_changed_p;
7615 }
7616
7617
7618 /* Helper for display_echo_area. Display the current buffer which
7619 contains the current echo area message in window W, a mini-window,
7620 a pointer to which is passed in A1. A2..A4 are currently not used.
7621 Change the height of W so that all of the message is displayed.
7622 Value is non-zero if height of W was changed. */
7623
7624 static int
7625 display_echo_area_1 (a1, a2, a3, a4)
7626 EMACS_INT a1;
7627 Lisp_Object a2;
7628 EMACS_INT a3, a4;
7629 {
7630 struct window *w = (struct window *) a1;
7631 Lisp_Object window;
7632 struct text_pos start;
7633 int window_height_changed_p = 0;
7634
7635 /* Do this before displaying, so that we have a large enough glyph
7636 matrix for the display. If we can't get enough space for the
7637 whole text, display the last N lines. That works by setting w->start. */
7638 window_height_changed_p = resize_mini_window (w, 0);
7639
7640 /* Use the starting position chosen by resize_mini_window. */
7641 SET_TEXT_POS_FROM_MARKER (start, w->start);
7642
7643 /* Display. */
7644 clear_glyph_matrix (w->desired_matrix);
7645 XSETWINDOW (window, w);
7646 try_window (window, start, 0);
7647
7648 return window_height_changed_p;
7649 }
7650
7651
7652 /* Resize the echo area window to exactly the size needed for the
7653 currently displayed message, if there is one. If a mini-buffer
7654 is active, don't shrink it. */
7655
7656 void
7657 resize_echo_area_exactly ()
7658 {
7659 if (BUFFERP (echo_area_buffer[0])
7660 && WINDOWP (echo_area_window))
7661 {
7662 struct window *w = XWINDOW (echo_area_window);
7663 int resized_p;
7664 Lisp_Object resize_exactly;
7665
7666 if (minibuf_level == 0)
7667 resize_exactly = Qt;
7668 else
7669 resize_exactly = Qnil;
7670
7671 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7672 (EMACS_INT) w, resize_exactly, 0, 0);
7673 if (resized_p)
7674 {
7675 ++windows_or_buffers_changed;
7676 ++update_mode_lines;
7677 redisplay_internal (0);
7678 }
7679 }
7680 }
7681
7682
7683 /* Callback function for with_echo_area_buffer, when used from
7684 resize_echo_area_exactly. A1 contains a pointer to the window to
7685 resize, EXACTLY non-nil means resize the mini-window exactly to the
7686 size of the text displayed. A3 and A4 are not used. Value is what
7687 resize_mini_window returns. */
7688
7689 static int
7690 resize_mini_window_1 (a1, exactly, a3, a4)
7691 EMACS_INT a1;
7692 Lisp_Object exactly;
7693 EMACS_INT a3, a4;
7694 {
7695 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7696 }
7697
7698
7699 /* Resize mini-window W to fit the size of its contents. EXACT:P
7700 means size the window exactly to the size needed. Otherwise, it's
7701 only enlarged until W's buffer is empty.
7702
7703 Set W->start to the right place to begin display. If the whole
7704 contents fit, start at the beginning. Otherwise, start so as
7705 to make the end of the contents appear. This is particularly
7706 important for y-or-n-p, but seems desirable generally.
7707
7708 Value is non-zero if the window height has been changed. */
7709
7710 int
7711 resize_mini_window (w, exact_p)
7712 struct window *w;
7713 int exact_p;
7714 {
7715 struct frame *f = XFRAME (w->frame);
7716 int window_height_changed_p = 0;
7717
7718 xassert (MINI_WINDOW_P (w));
7719
7720 /* By default, start display at the beginning. */
7721 set_marker_both (w->start, w->buffer,
7722 BUF_BEGV (XBUFFER (w->buffer)),
7723 BUF_BEGV_BYTE (XBUFFER (w->buffer)));
7724
7725 /* Don't resize windows while redisplaying a window; it would
7726 confuse redisplay functions when the size of the window they are
7727 displaying changes from under them. Such a resizing can happen,
7728 for instance, when which-func prints a long message while
7729 we are running fontification-functions. We're running these
7730 functions with safe_call which binds inhibit-redisplay to t. */
7731 if (!NILP (Vinhibit_redisplay))
7732 return 0;
7733
7734 /* Nil means don't try to resize. */
7735 if (NILP (Vresize_mini_windows)
7736 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7737 return 0;
7738
7739 if (!FRAME_MINIBUF_ONLY_P (f))
7740 {
7741 struct it it;
7742 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7743 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7744 int height, max_height;
7745 int unit = FRAME_LINE_HEIGHT (f);
7746 struct text_pos start;
7747 struct buffer *old_current_buffer = NULL;
7748
7749 if (current_buffer != XBUFFER (w->buffer))
7750 {
7751 old_current_buffer = current_buffer;
7752 set_buffer_internal (XBUFFER (w->buffer));
7753 }
7754
7755 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7756
7757 /* Compute the max. number of lines specified by the user. */
7758 if (FLOATP (Vmax_mini_window_height))
7759 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7760 else if (INTEGERP (Vmax_mini_window_height))
7761 max_height = XINT (Vmax_mini_window_height);
7762 else
7763 max_height = total_height / 4;
7764
7765 /* Correct that max. height if it's bogus. */
7766 max_height = max (1, max_height);
7767 max_height = min (total_height, max_height);
7768
7769 /* Find out the height of the text in the window. */
7770 if (it.truncate_lines_p)
7771 height = 1;
7772 else
7773 {
7774 last_height = 0;
7775 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7776 if (it.max_ascent == 0 && it.max_descent == 0)
7777 height = it.current_y + last_height;
7778 else
7779 height = it.current_y + it.max_ascent + it.max_descent;
7780 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7781 height = (height + unit - 1) / unit;
7782 }
7783
7784 /* Compute a suitable window start. */
7785 if (height > max_height)
7786 {
7787 height = max_height;
7788 init_iterator (&it, w, ZV, ZV_BYTE, NULL, DEFAULT_FACE_ID);
7789 move_it_vertically_backward (&it, (height - 1) * unit);
7790 start = it.current.pos;
7791 }
7792 else
7793 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7794 SET_MARKER_FROM_TEXT_POS (w->start, start);
7795
7796 if (EQ (Vresize_mini_windows, Qgrow_only))
7797 {
7798 /* Let it grow only, until we display an empty message, in which
7799 case the window shrinks again. */
7800 if (height > WINDOW_TOTAL_LINES (w))
7801 {
7802 int old_height = WINDOW_TOTAL_LINES (w);
7803 freeze_window_starts (f, 1);
7804 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7805 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7806 }
7807 else if (height < WINDOW_TOTAL_LINES (w)
7808 && (exact_p || BEGV == ZV))
7809 {
7810 int old_height = WINDOW_TOTAL_LINES (w);
7811 freeze_window_starts (f, 0);
7812 shrink_mini_window (w);
7813 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7814 }
7815 }
7816 else
7817 {
7818 /* Always resize to exact size needed. */
7819 if (height > WINDOW_TOTAL_LINES (w))
7820 {
7821 int old_height = WINDOW_TOTAL_LINES (w);
7822 freeze_window_starts (f, 1);
7823 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7824 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7825 }
7826 else if (height < WINDOW_TOTAL_LINES (w))
7827 {
7828 int old_height = WINDOW_TOTAL_LINES (w);
7829 freeze_window_starts (f, 0);
7830 shrink_mini_window (w);
7831
7832 if (height)
7833 {
7834 freeze_window_starts (f, 1);
7835 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7836 }
7837
7838 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7839 }
7840 }
7841
7842 if (old_current_buffer)
7843 set_buffer_internal (old_current_buffer);
7844 }
7845
7846 return window_height_changed_p;
7847 }
7848
7849
7850 /* Value is the current message, a string, or nil if there is no
7851 current message. */
7852
7853 Lisp_Object
7854 current_message ()
7855 {
7856 Lisp_Object msg;
7857
7858 if (NILP (echo_area_buffer[0]))
7859 msg = Qnil;
7860 else
7861 {
7862 with_echo_area_buffer (0, 0, current_message_1,
7863 (EMACS_INT) &msg, Qnil, 0, 0);
7864 if (NILP (msg))
7865 echo_area_buffer[0] = Qnil;
7866 }
7867
7868 return msg;
7869 }
7870
7871
7872 static int
7873 current_message_1 (a1, a2, a3, a4)
7874 EMACS_INT a1;
7875 Lisp_Object a2;
7876 EMACS_INT a3, a4;
7877 {
7878 Lisp_Object *msg = (Lisp_Object *) a1;
7879
7880 if (Z > BEG)
7881 *msg = make_buffer_string (BEG, Z, 1);
7882 else
7883 *msg = Qnil;
7884 return 0;
7885 }
7886
7887
7888 /* Push the current message on Vmessage_stack for later restauration
7889 by restore_message. Value is non-zero if the current message isn't
7890 empty. This is a relatively infrequent operation, so it's not
7891 worth optimizing. */
7892
7893 int
7894 push_message ()
7895 {
7896 Lisp_Object msg;
7897 msg = current_message ();
7898 Vmessage_stack = Fcons (msg, Vmessage_stack);
7899 return STRINGP (msg);
7900 }
7901
7902
7903 /* Restore message display from the top of Vmessage_stack. */
7904
7905 void
7906 restore_message ()
7907 {
7908 Lisp_Object msg;
7909
7910 xassert (CONSP (Vmessage_stack));
7911 msg = XCAR (Vmessage_stack);
7912 if (STRINGP (msg))
7913 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7914 else
7915 message3_nolog (msg, 0, 0);
7916 }
7917
7918
7919 /* Handler for record_unwind_protect calling pop_message. */
7920
7921 Lisp_Object
7922 pop_message_unwind (dummy)
7923 Lisp_Object dummy;
7924 {
7925 pop_message ();
7926 return Qnil;
7927 }
7928
7929 /* Pop the top-most entry off Vmessage_stack. */
7930
7931 void
7932 pop_message ()
7933 {
7934 xassert (CONSP (Vmessage_stack));
7935 Vmessage_stack = XCDR (Vmessage_stack);
7936 }
7937
7938
7939 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7940 exits. If the stack is not empty, we have a missing pop_message
7941 somewhere. */
7942
7943 void
7944 check_message_stack ()
7945 {
7946 if (!NILP (Vmessage_stack))
7947 abort ();
7948 }
7949
7950
7951 /* Truncate to NCHARS what will be displayed in the echo area the next
7952 time we display it---but don't redisplay it now. */
7953
7954 void
7955 truncate_echo_area (nchars)
7956 int nchars;
7957 {
7958 if (nchars == 0)
7959 echo_area_buffer[0] = Qnil;
7960 /* A null message buffer means that the frame hasn't really been
7961 initialized yet. Error messages get reported properly by
7962 cmd_error, so this must be just an informative message; toss it. */
7963 else if (!noninteractive
7964 && INTERACTIVE
7965 && !NILP (echo_area_buffer[0]))
7966 {
7967 struct frame *sf = SELECTED_FRAME ();
7968 if (FRAME_MESSAGE_BUF (sf))
7969 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7970 }
7971 }
7972
7973
7974 /* Helper function for truncate_echo_area. Truncate the current
7975 message to at most NCHARS characters. */
7976
7977 static int
7978 truncate_message_1 (nchars, a2, a3, a4)
7979 EMACS_INT nchars;
7980 Lisp_Object a2;
7981 EMACS_INT a3, a4;
7982 {
7983 if (BEG + nchars < Z)
7984 del_range (BEG + nchars, Z);
7985 if (Z == BEG)
7986 echo_area_buffer[0] = Qnil;
7987 return 0;
7988 }
7989
7990
7991 /* Set the current message to a substring of S or STRING.
7992
7993 If STRING is a Lisp string, set the message to the first NBYTES
7994 bytes from STRING. NBYTES zero means use the whole string. If
7995 STRING is multibyte, the message will be displayed multibyte.
7996
7997 If S is not null, set the message to the first LEN bytes of S. LEN
7998 zero means use the whole string. MULTIBYTE_P non-zero means S is
7999 multibyte. Display the message multibyte in that case. */
8000
8001 void
8002 set_message (s, string, nbytes, multibyte_p)
8003 const char *s;
8004 Lisp_Object string;
8005 int nbytes, multibyte_p;
8006 {
8007 message_enable_multibyte
8008 = ((s && multibyte_p)
8009 || (STRINGP (string) && STRING_MULTIBYTE (string)));
8010
8011 with_echo_area_buffer (0, -1, set_message_1,
8012 (EMACS_INT) s, string, nbytes, multibyte_p);
8013 message_buf_print = 0;
8014 help_echo_showing_p = 0;
8015 }
8016
8017
8018 /* Helper function for set_message. Arguments have the same meaning
8019 as there, with A1 corresponding to S and A2 corresponding to STRING
8020 This function is called with the echo area buffer being
8021 current. */
8022
8023 static int
8024 set_message_1 (a1, a2, nbytes, multibyte_p)
8025 EMACS_INT a1;
8026 Lisp_Object a2;
8027 EMACS_INT nbytes, multibyte_p;
8028 {
8029 const char *s = (const char *) a1;
8030 Lisp_Object string = a2;
8031
8032 /* Change multibyteness of the echo buffer appropriately. */
8033 if (message_enable_multibyte
8034 != !NILP (current_buffer->enable_multibyte_characters))
8035 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8036
8037 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8038
8039 /* Insert new message at BEG. */
8040 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8041
8042 if (STRINGP (string))
8043 {
8044 int nchars;
8045
8046 if (nbytes == 0)
8047 nbytes = SBYTES (string);
8048 nchars = string_byte_to_char (string, nbytes);
8049
8050 /* This function takes care of single/multibyte conversion. We
8051 just have to ensure that the echo area buffer has the right
8052 setting of enable_multibyte_characters. */
8053 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8054 }
8055 else if (s)
8056 {
8057 if (nbytes == 0)
8058 nbytes = strlen (s);
8059
8060 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8061 {
8062 /* Convert from multi-byte to single-byte. */
8063 int i, c, n;
8064 unsigned char work[1];
8065
8066 /* Convert a multibyte string to single-byte. */
8067 for (i = 0; i < nbytes; i += n)
8068 {
8069 c = string_char_and_length (s + i, nbytes - i, &n);
8070 work[0] = (SINGLE_BYTE_CHAR_P (c)
8071 ? c
8072 : multibyte_char_to_unibyte (c, Qnil));
8073 insert_1_both (work, 1, 1, 1, 0, 0);
8074 }
8075 }
8076 else if (!multibyte_p
8077 && !NILP (current_buffer->enable_multibyte_characters))
8078 {
8079 /* Convert from single-byte to multi-byte. */
8080 int i, c, n;
8081 const unsigned char *msg = (const unsigned char *) s;
8082 unsigned char str[MAX_MULTIBYTE_LENGTH];
8083
8084 /* Convert a single-byte string to multibyte. */
8085 for (i = 0; i < nbytes; i++)
8086 {
8087 c = unibyte_char_to_multibyte (msg[i]);
8088 n = CHAR_STRING (c, str);
8089 insert_1_both (str, 1, n, 1, 0, 0);
8090 }
8091 }
8092 else
8093 insert_1 (s, nbytes, 1, 0, 0);
8094 }
8095
8096 return 0;
8097 }
8098
8099
8100 /* Clear messages. CURRENT_P non-zero means clear the current
8101 message. LAST_DISPLAYED_P non-zero means clear the message
8102 last displayed. */
8103
8104 void
8105 clear_message (current_p, last_displayed_p)
8106 int current_p, last_displayed_p;
8107 {
8108 if (current_p)
8109 {
8110 echo_area_buffer[0] = Qnil;
8111 message_cleared_p = 1;
8112 }
8113
8114 if (last_displayed_p)
8115 echo_area_buffer[1] = Qnil;
8116
8117 message_buf_print = 0;
8118 }
8119
8120 /* Clear garbaged frames.
8121
8122 This function is used where the old redisplay called
8123 redraw_garbaged_frames which in turn called redraw_frame which in
8124 turn called clear_frame. The call to clear_frame was a source of
8125 flickering. I believe a clear_frame is not necessary. It should
8126 suffice in the new redisplay to invalidate all current matrices,
8127 and ensure a complete redisplay of all windows. */
8128
8129 static void
8130 clear_garbaged_frames ()
8131 {
8132 if (frame_garbaged)
8133 {
8134 Lisp_Object tail, frame;
8135 int changed_count = 0;
8136
8137 FOR_EACH_FRAME (tail, frame)
8138 {
8139 struct frame *f = XFRAME (frame);
8140
8141 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8142 {
8143 if (f->resized_p)
8144 {
8145 Fredraw_frame (frame);
8146 f->force_flush_display_p = 1;
8147 }
8148 clear_current_matrices (f);
8149 changed_count++;
8150 f->garbaged = 0;
8151 f->resized_p = 0;
8152 }
8153 }
8154
8155 frame_garbaged = 0;
8156 if (changed_count)
8157 ++windows_or_buffers_changed;
8158 }
8159 }
8160
8161
8162 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8163 is non-zero update selected_frame. Value is non-zero if the
8164 mini-windows height has been changed. */
8165
8166 static int
8167 echo_area_display (update_frame_p)
8168 int update_frame_p;
8169 {
8170 Lisp_Object mini_window;
8171 struct window *w;
8172 struct frame *f;
8173 int window_height_changed_p = 0;
8174 struct frame *sf = SELECTED_FRAME ();
8175
8176 mini_window = FRAME_MINIBUF_WINDOW (sf);
8177 w = XWINDOW (mini_window);
8178 f = XFRAME (WINDOW_FRAME (w));
8179
8180 /* Don't display if frame is invisible or not yet initialized. */
8181 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8182 return 0;
8183
8184 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8185 #ifndef MAC_OS8
8186 #ifdef HAVE_WINDOW_SYSTEM
8187 /* When Emacs starts, selected_frame may be the initial terminal
8188 frame. If we let this through, a message would be displayed on
8189 the terminal. */
8190 if (FRAME_INITIAL_P (XFRAME (selected_frame)))
8191 return 0;
8192 #endif /* HAVE_WINDOW_SYSTEM */
8193 #endif
8194
8195 /* Redraw garbaged frames. */
8196 if (frame_garbaged)
8197 clear_garbaged_frames ();
8198
8199 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8200 {
8201 echo_area_window = mini_window;
8202 window_height_changed_p = display_echo_area (w);
8203 w->must_be_updated_p = 1;
8204
8205 /* Update the display, unless called from redisplay_internal.
8206 Also don't update the screen during redisplay itself. The
8207 update will happen at the end of redisplay, and an update
8208 here could cause confusion. */
8209 if (update_frame_p && !redisplaying_p)
8210 {
8211 int n = 0;
8212
8213 /* If the display update has been interrupted by pending
8214 input, update mode lines in the frame. Due to the
8215 pending input, it might have been that redisplay hasn't
8216 been called, so that mode lines above the echo area are
8217 garbaged. This looks odd, so we prevent it here. */
8218 if (!display_completed)
8219 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8220
8221 if (window_height_changed_p
8222 /* Don't do this if Emacs is shutting down. Redisplay
8223 needs to run hooks. */
8224 && !NILP (Vrun_hooks))
8225 {
8226 /* Must update other windows. Likewise as in other
8227 cases, don't let this update be interrupted by
8228 pending input. */
8229 int count = SPECPDL_INDEX ();
8230 specbind (Qredisplay_dont_pause, Qt);
8231 windows_or_buffers_changed = 1;
8232 redisplay_internal (0);
8233 unbind_to (count, Qnil);
8234 }
8235 else if (FRAME_WINDOW_P (f) && n == 0)
8236 {
8237 /* Window configuration is the same as before.
8238 Can do with a display update of the echo area,
8239 unless we displayed some mode lines. */
8240 update_single_window (w, 1);
8241 FRAME_RIF (f)->flush_display (f);
8242 }
8243 else
8244 update_frame (f, 1, 1);
8245
8246 /* If cursor is in the echo area, make sure that the next
8247 redisplay displays the minibuffer, so that the cursor will
8248 be replaced with what the minibuffer wants. */
8249 if (cursor_in_echo_area)
8250 ++windows_or_buffers_changed;
8251 }
8252 }
8253 else if (!EQ (mini_window, selected_window))
8254 windows_or_buffers_changed++;
8255
8256 /* Last displayed message is now the current message. */
8257 echo_area_buffer[1] = echo_area_buffer[0];
8258 /* Inform read_char that we're not echoing. */
8259 echo_message_buffer = Qnil;
8260
8261 /* Prevent redisplay optimization in redisplay_internal by resetting
8262 this_line_start_pos. This is done because the mini-buffer now
8263 displays the message instead of its buffer text. */
8264 if (EQ (mini_window, selected_window))
8265 CHARPOS (this_line_start_pos) = 0;
8266
8267 return window_height_changed_p;
8268 }
8269
8270
8271 \f
8272 /***********************************************************************
8273 Mode Lines and Frame Titles
8274 ***********************************************************************/
8275
8276 /* A buffer for constructing non-propertized mode-line strings and
8277 frame titles in it; allocated from the heap in init_xdisp and
8278 resized as needed in store_mode_line_noprop_char. */
8279
8280 static char *mode_line_noprop_buf;
8281
8282 /* The buffer's end, and a current output position in it. */
8283
8284 static char *mode_line_noprop_buf_end;
8285 static char *mode_line_noprop_ptr;
8286
8287 #define MODE_LINE_NOPROP_LEN(start) \
8288 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8289
8290 static enum {
8291 MODE_LINE_DISPLAY = 0,
8292 MODE_LINE_TITLE,
8293 MODE_LINE_NOPROP,
8294 MODE_LINE_STRING
8295 } mode_line_target;
8296
8297 /* Alist that caches the results of :propertize.
8298 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8299 static Lisp_Object mode_line_proptrans_alist;
8300
8301 /* List of strings making up the mode-line. */
8302 static Lisp_Object mode_line_string_list;
8303
8304 /* Base face property when building propertized mode line string. */
8305 static Lisp_Object mode_line_string_face;
8306 static Lisp_Object mode_line_string_face_prop;
8307
8308
8309 /* Unwind data for mode line strings */
8310
8311 static Lisp_Object Vmode_line_unwind_vector;
8312
8313 static Lisp_Object
8314 format_mode_line_unwind_data (obuf)
8315 struct buffer *obuf;
8316 {
8317 Lisp_Object vector;
8318
8319 /* Reduce consing by keeping one vector in
8320 Vwith_echo_area_save_vector. */
8321 vector = Vmode_line_unwind_vector;
8322 Vmode_line_unwind_vector = Qnil;
8323
8324 if (NILP (vector))
8325 vector = Fmake_vector (make_number (7), Qnil);
8326
8327 AREF (vector, 0) = make_number (mode_line_target);
8328 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
8329 AREF (vector, 2) = mode_line_string_list;
8330 AREF (vector, 3) = mode_line_proptrans_alist;
8331 AREF (vector, 4) = mode_line_string_face;
8332 AREF (vector, 5) = mode_line_string_face_prop;
8333
8334 if (obuf)
8335 XSETBUFFER (AREF (vector, 6), obuf);
8336 else
8337 AREF (vector, 6) = Qnil;
8338
8339 return vector;
8340 }
8341
8342 static Lisp_Object
8343 unwind_format_mode_line (vector)
8344 Lisp_Object vector;
8345 {
8346 mode_line_target = XINT (AREF (vector, 0));
8347 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
8348 mode_line_string_list = AREF (vector, 2);
8349 mode_line_proptrans_alist = AREF (vector, 3);
8350 mode_line_string_face = AREF (vector, 4);
8351 mode_line_string_face_prop = AREF (vector, 5);
8352
8353 if (!NILP (AREF (vector, 6)))
8354 {
8355 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
8356 AREF (vector, 6) = Qnil;
8357 }
8358
8359 Vmode_line_unwind_vector = vector;
8360 return Qnil;
8361 }
8362
8363
8364 /* Store a single character C for the frame title in mode_line_noprop_buf.
8365 Re-allocate mode_line_noprop_buf if necessary. */
8366
8367 static void
8368 #ifdef PROTOTYPES
8369 store_mode_line_noprop_char (char c)
8370 #else
8371 store_mode_line_noprop_char (c)
8372 char c;
8373 #endif
8374 {
8375 /* If output position has reached the end of the allocated buffer,
8376 double the buffer's size. */
8377 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
8378 {
8379 int len = MODE_LINE_NOPROP_LEN (0);
8380 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
8381 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
8382 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
8383 mode_line_noprop_ptr = mode_line_noprop_buf + len;
8384 }
8385
8386 *mode_line_noprop_ptr++ = c;
8387 }
8388
8389
8390 /* Store part of a frame title in mode_line_noprop_buf, beginning at
8391 mode_line_noprop_ptr. STR is the string to store. Do not copy
8392 characters that yield more columns than PRECISION; PRECISION <= 0
8393 means copy the whole string. Pad with spaces until FIELD_WIDTH
8394 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8395 pad. Called from display_mode_element when it is used to build a
8396 frame title. */
8397
8398 static int
8399 store_mode_line_noprop (str, field_width, precision)
8400 const unsigned char *str;
8401 int field_width, precision;
8402 {
8403 int n = 0;
8404 int dummy, nbytes;
8405
8406 /* Copy at most PRECISION chars from STR. */
8407 nbytes = strlen (str);
8408 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8409 while (nbytes--)
8410 store_mode_line_noprop_char (*str++);
8411
8412 /* Fill up with spaces until FIELD_WIDTH reached. */
8413 while (field_width > 0
8414 && n < field_width)
8415 {
8416 store_mode_line_noprop_char (' ');
8417 ++n;
8418 }
8419
8420 return n;
8421 }
8422
8423 /***********************************************************************
8424 Frame Titles
8425 ***********************************************************************/
8426
8427 #ifdef HAVE_WINDOW_SYSTEM
8428
8429 /* Set the title of FRAME, if it has changed. The title format is
8430 Vicon_title_format if FRAME is iconified, otherwise it is
8431 frame_title_format. */
8432
8433 static void
8434 x_consider_frame_title (frame)
8435 Lisp_Object frame;
8436 {
8437 struct frame *f = XFRAME (frame);
8438
8439 if (FRAME_WINDOW_P (f)
8440 || FRAME_MINIBUF_ONLY_P (f)
8441 || f->explicit_name)
8442 {
8443 /* Do we have more than one visible frame on this X display? */
8444 Lisp_Object tail;
8445 Lisp_Object fmt;
8446 int title_start;
8447 char *title;
8448 int len;
8449 struct it it;
8450 int count = SPECPDL_INDEX ();
8451
8452 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8453 {
8454 Lisp_Object other_frame = XCAR (tail);
8455 struct frame *tf = XFRAME (other_frame);
8456
8457 if (tf != f
8458 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8459 && !FRAME_MINIBUF_ONLY_P (tf)
8460 && !EQ (other_frame, tip_frame)
8461 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8462 break;
8463 }
8464
8465 /* Set global variable indicating that multiple frames exist. */
8466 multiple_frames = CONSP (tail);
8467
8468 /* Switch to the buffer of selected window of the frame. Set up
8469 mode_line_target so that display_mode_element will output into
8470 mode_line_noprop_buf; then display the title. */
8471 record_unwind_protect (unwind_format_mode_line,
8472 format_mode_line_unwind_data (current_buffer));
8473
8474 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8475 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8476
8477 mode_line_target = MODE_LINE_TITLE;
8478 title_start = MODE_LINE_NOPROP_LEN (0);
8479 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8480 NULL, DEFAULT_FACE_ID);
8481 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8482 len = MODE_LINE_NOPROP_LEN (title_start);
8483 title = mode_line_noprop_buf + title_start;
8484 unbind_to (count, Qnil);
8485
8486 /* Set the title only if it's changed. This avoids consing in
8487 the common case where it hasn't. (If it turns out that we've
8488 already wasted too much time by walking through the list with
8489 display_mode_element, then we might need to optimize at a
8490 higher level than this.) */
8491 if (! STRINGP (f->name)
8492 || SBYTES (f->name) != len
8493 || bcmp (title, SDATA (f->name), len) != 0)
8494 x_implicitly_set_name (f, make_string (title, len), Qnil);
8495 }
8496 }
8497
8498 #endif /* not HAVE_WINDOW_SYSTEM */
8499
8500
8501
8502 \f
8503 /***********************************************************************
8504 Menu Bars
8505 ***********************************************************************/
8506
8507
8508 /* Prepare for redisplay by updating menu-bar item lists when
8509 appropriate. This can call eval. */
8510
8511 void
8512 prepare_menu_bars ()
8513 {
8514 int all_windows;
8515 struct gcpro gcpro1, gcpro2;
8516 struct frame *f;
8517 Lisp_Object tooltip_frame;
8518
8519 #ifdef HAVE_WINDOW_SYSTEM
8520 tooltip_frame = tip_frame;
8521 #else
8522 tooltip_frame = Qnil;
8523 #endif
8524
8525 /* Update all frame titles based on their buffer names, etc. We do
8526 this before the menu bars so that the buffer-menu will show the
8527 up-to-date frame titles. */
8528 #ifdef HAVE_WINDOW_SYSTEM
8529 if (windows_or_buffers_changed || update_mode_lines)
8530 {
8531 Lisp_Object tail, frame;
8532
8533 FOR_EACH_FRAME (tail, frame)
8534 {
8535 f = XFRAME (frame);
8536 if (!EQ (frame, tooltip_frame)
8537 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8538 x_consider_frame_title (frame);
8539 }
8540 }
8541 #endif /* HAVE_WINDOW_SYSTEM */
8542
8543 /* Update the menu bar item lists, if appropriate. This has to be
8544 done before any actual redisplay or generation of display lines. */
8545 all_windows = (update_mode_lines
8546 || buffer_shared > 1
8547 || windows_or_buffers_changed);
8548 if (all_windows)
8549 {
8550 Lisp_Object tail, frame;
8551 int count = SPECPDL_INDEX ();
8552
8553 record_unwind_save_match_data ();
8554
8555 FOR_EACH_FRAME (tail, frame)
8556 {
8557 f = XFRAME (frame);
8558
8559 /* Ignore tooltip frame. */
8560 if (EQ (frame, tooltip_frame))
8561 continue;
8562
8563 /* If a window on this frame changed size, report that to
8564 the user and clear the size-change flag. */
8565 if (FRAME_WINDOW_SIZES_CHANGED (f))
8566 {
8567 Lisp_Object functions;
8568
8569 /* Clear flag first in case we get an error below. */
8570 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8571 functions = Vwindow_size_change_functions;
8572 GCPRO2 (tail, functions);
8573
8574 while (CONSP (functions))
8575 {
8576 call1 (XCAR (functions), frame);
8577 functions = XCDR (functions);
8578 }
8579 UNGCPRO;
8580 }
8581
8582 GCPRO1 (tail);
8583 update_menu_bar (f, 0);
8584 #ifdef HAVE_WINDOW_SYSTEM
8585 update_tool_bar (f, 0);
8586 #endif
8587 UNGCPRO;
8588 }
8589
8590 unbind_to (count, Qnil);
8591 }
8592 else
8593 {
8594 struct frame *sf = SELECTED_FRAME ();
8595 update_menu_bar (sf, 1);
8596 #ifdef HAVE_WINDOW_SYSTEM
8597 update_tool_bar (sf, 1);
8598 #endif
8599 }
8600
8601 /* Motif needs this. See comment in xmenu.c. Turn it off when
8602 pending_menu_activation is not defined. */
8603 #ifdef USE_X_TOOLKIT
8604 pending_menu_activation = 0;
8605 #endif
8606 }
8607
8608
8609 /* Update the menu bar item list for frame F. This has to be done
8610 before we start to fill in any display lines, because it can call
8611 eval.
8612
8613 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8614
8615 static void
8616 update_menu_bar (f, save_match_data)
8617 struct frame *f;
8618 int save_match_data;
8619 {
8620 Lisp_Object window;
8621 register struct window *w;
8622
8623 /* If called recursively during a menu update, do nothing. This can
8624 happen when, for instance, an activate-menubar-hook causes a
8625 redisplay. */
8626 if (inhibit_menubar_update)
8627 return;
8628
8629 window = FRAME_SELECTED_WINDOW (f);
8630 w = XWINDOW (window);
8631
8632 #if 0 /* The if statement below this if statement used to include the
8633 condition !NILP (w->update_mode_line), rather than using
8634 update_mode_lines directly, and this if statement may have
8635 been added to make that condition work. Now the if
8636 statement below matches its comment, this isn't needed. */
8637 if (update_mode_lines)
8638 w->update_mode_line = Qt;
8639 #endif
8640
8641 if (FRAME_WINDOW_P (f)
8642 ?
8643 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8644 || defined (USE_GTK)
8645 FRAME_EXTERNAL_MENU_BAR (f)
8646 #else
8647 FRAME_MENU_BAR_LINES (f) > 0
8648 #endif
8649 : FRAME_MENU_BAR_LINES (f) > 0)
8650 {
8651 /* If the user has switched buffers or windows, we need to
8652 recompute to reflect the new bindings. But we'll
8653 recompute when update_mode_lines is set too; that means
8654 that people can use force-mode-line-update to request
8655 that the menu bar be recomputed. The adverse effect on
8656 the rest of the redisplay algorithm is about the same as
8657 windows_or_buffers_changed anyway. */
8658 if (windows_or_buffers_changed
8659 /* This used to test w->update_mode_line, but we believe
8660 there is no need to recompute the menu in that case. */
8661 || update_mode_lines
8662 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8663 < BUF_MODIFF (XBUFFER (w->buffer)))
8664 != !NILP (w->last_had_star))
8665 || ((!NILP (Vtransient_mark_mode)
8666 && !NILP (XBUFFER (w->buffer)->mark_active))
8667 != !NILP (w->region_showing)))
8668 {
8669 struct buffer *prev = current_buffer;
8670 int count = SPECPDL_INDEX ();
8671
8672 specbind (Qinhibit_menubar_update, Qt);
8673
8674 set_buffer_internal_1 (XBUFFER (w->buffer));
8675 if (save_match_data)
8676 record_unwind_save_match_data ();
8677 if (NILP (Voverriding_local_map_menu_flag))
8678 {
8679 specbind (Qoverriding_terminal_local_map, Qnil);
8680 specbind (Qoverriding_local_map, Qnil);
8681 }
8682
8683 /* Run the Lucid hook. */
8684 safe_run_hooks (Qactivate_menubar_hook);
8685
8686 /* If it has changed current-menubar from previous value,
8687 really recompute the menu-bar from the value. */
8688 if (! NILP (Vlucid_menu_bar_dirty_flag))
8689 call0 (Qrecompute_lucid_menubar);
8690
8691 safe_run_hooks (Qmenu_bar_update_hook);
8692 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8693
8694 /* Redisplay the menu bar in case we changed it. */
8695 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8696 || defined (USE_GTK)
8697 if (FRAME_WINDOW_P (f)
8698 #if defined (MAC_OS)
8699 /* All frames on Mac OS share the same menubar. So only the
8700 selected frame should be allowed to set it. */
8701 && f == SELECTED_FRAME ()
8702 #endif
8703 )
8704 set_frame_menubar (f, 0, 0);
8705 else
8706 /* On a terminal screen, the menu bar is an ordinary screen
8707 line, and this makes it get updated. */
8708 w->update_mode_line = Qt;
8709 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8710 /* In the non-toolkit version, the menu bar is an ordinary screen
8711 line, and this makes it get updated. */
8712 w->update_mode_line = Qt;
8713 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8714
8715 unbind_to (count, Qnil);
8716 set_buffer_internal_1 (prev);
8717 }
8718 }
8719 }
8720
8721
8722 \f
8723 /***********************************************************************
8724 Output Cursor
8725 ***********************************************************************/
8726
8727 #ifdef HAVE_WINDOW_SYSTEM
8728
8729 /* EXPORT:
8730 Nominal cursor position -- where to draw output.
8731 HPOS and VPOS are window relative glyph matrix coordinates.
8732 X and Y are window relative pixel coordinates. */
8733
8734 struct cursor_pos output_cursor;
8735
8736
8737 /* EXPORT:
8738 Set the global variable output_cursor to CURSOR. All cursor
8739 positions are relative to updated_window. */
8740
8741 void
8742 set_output_cursor (cursor)
8743 struct cursor_pos *cursor;
8744 {
8745 output_cursor.hpos = cursor->hpos;
8746 output_cursor.vpos = cursor->vpos;
8747 output_cursor.x = cursor->x;
8748 output_cursor.y = cursor->y;
8749 }
8750
8751
8752 /* EXPORT for RIF:
8753 Set a nominal cursor position.
8754
8755 HPOS and VPOS are column/row positions in a window glyph matrix. X
8756 and Y are window text area relative pixel positions.
8757
8758 If this is done during an update, updated_window will contain the
8759 window that is being updated and the position is the future output
8760 cursor position for that window. If updated_window is null, use
8761 selected_window and display the cursor at the given position. */
8762
8763 void
8764 x_cursor_to (vpos, hpos, y, x)
8765 int vpos, hpos, y, x;
8766 {
8767 struct window *w;
8768
8769 /* If updated_window is not set, work on selected_window. */
8770 if (updated_window)
8771 w = updated_window;
8772 else
8773 w = XWINDOW (selected_window);
8774
8775 /* Set the output cursor. */
8776 output_cursor.hpos = hpos;
8777 output_cursor.vpos = vpos;
8778 output_cursor.x = x;
8779 output_cursor.y = y;
8780
8781 /* If not called as part of an update, really display the cursor.
8782 This will also set the cursor position of W. */
8783 if (updated_window == NULL)
8784 {
8785 BLOCK_INPUT;
8786 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8787 if (FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
8788 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (SELECTED_FRAME ());
8789 UNBLOCK_INPUT;
8790 }
8791 }
8792
8793 #endif /* HAVE_WINDOW_SYSTEM */
8794
8795 \f
8796 /***********************************************************************
8797 Tool-bars
8798 ***********************************************************************/
8799
8800 #ifdef HAVE_WINDOW_SYSTEM
8801
8802 /* Where the mouse was last time we reported a mouse event. */
8803
8804 FRAME_PTR last_mouse_frame;
8805
8806 /* Tool-bar item index of the item on which a mouse button was pressed
8807 or -1. */
8808
8809 int last_tool_bar_item;
8810
8811
8812 /* Update the tool-bar item list for frame F. This has to be done
8813 before we start to fill in any display lines. Called from
8814 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8815 and restore it here. */
8816
8817 static void
8818 update_tool_bar (f, save_match_data)
8819 struct frame *f;
8820 int save_match_data;
8821 {
8822 #ifdef USE_GTK
8823 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8824 #else
8825 int do_update = WINDOWP (f->tool_bar_window)
8826 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8827 #endif
8828
8829 if (do_update)
8830 {
8831 Lisp_Object window;
8832 struct window *w;
8833
8834 window = FRAME_SELECTED_WINDOW (f);
8835 w = XWINDOW (window);
8836
8837 /* If the user has switched buffers or windows, we need to
8838 recompute to reflect the new bindings. But we'll
8839 recompute when update_mode_lines is set too; that means
8840 that people can use force-mode-line-update to request
8841 that the menu bar be recomputed. The adverse effect on
8842 the rest of the redisplay algorithm is about the same as
8843 windows_or_buffers_changed anyway. */
8844 if (windows_or_buffers_changed
8845 || !NILP (w->update_mode_line)
8846 || update_mode_lines
8847 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8848 < BUF_MODIFF (XBUFFER (w->buffer)))
8849 != !NILP (w->last_had_star))
8850 || ((!NILP (Vtransient_mark_mode)
8851 && !NILP (XBUFFER (w->buffer)->mark_active))
8852 != !NILP (w->region_showing)))
8853 {
8854 struct buffer *prev = current_buffer;
8855 int count = SPECPDL_INDEX ();
8856 Lisp_Object new_tool_bar;
8857 int new_n_tool_bar;
8858 struct gcpro gcpro1;
8859
8860 /* Set current_buffer to the buffer of the selected
8861 window of the frame, so that we get the right local
8862 keymaps. */
8863 set_buffer_internal_1 (XBUFFER (w->buffer));
8864
8865 /* Save match data, if we must. */
8866 if (save_match_data)
8867 record_unwind_save_match_data ();
8868
8869 /* Make sure that we don't accidentally use bogus keymaps. */
8870 if (NILP (Voverriding_local_map_menu_flag))
8871 {
8872 specbind (Qoverriding_terminal_local_map, Qnil);
8873 specbind (Qoverriding_local_map, Qnil);
8874 }
8875
8876 GCPRO1 (new_tool_bar);
8877
8878 /* Build desired tool-bar items from keymaps. */
8879 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8880 &new_n_tool_bar);
8881
8882 /* Redisplay the tool-bar if we changed it. */
8883 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8884 {
8885 /* Redisplay that happens asynchronously due to an expose event
8886 may access f->tool_bar_items. Make sure we update both
8887 variables within BLOCK_INPUT so no such event interrupts. */
8888 BLOCK_INPUT;
8889 f->tool_bar_items = new_tool_bar;
8890 f->n_tool_bar_items = new_n_tool_bar;
8891 w->update_mode_line = Qt;
8892 UNBLOCK_INPUT;
8893 }
8894
8895 UNGCPRO;
8896
8897 unbind_to (count, Qnil);
8898 set_buffer_internal_1 (prev);
8899 }
8900 }
8901 }
8902
8903
8904 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8905 F's desired tool-bar contents. F->tool_bar_items must have
8906 been set up previously by calling prepare_menu_bars. */
8907
8908 static void
8909 build_desired_tool_bar_string (f)
8910 struct frame *f;
8911 {
8912 int i, size, size_needed;
8913 struct gcpro gcpro1, gcpro2, gcpro3;
8914 Lisp_Object image, plist, props;
8915
8916 image = plist = props = Qnil;
8917 GCPRO3 (image, plist, props);
8918
8919 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8920 Otherwise, make a new string. */
8921
8922 /* The size of the string we might be able to reuse. */
8923 size = (STRINGP (f->desired_tool_bar_string)
8924 ? SCHARS (f->desired_tool_bar_string)
8925 : 0);
8926
8927 /* We need one space in the string for each image. */
8928 size_needed = f->n_tool_bar_items;
8929
8930 /* Reuse f->desired_tool_bar_string, if possible. */
8931 if (size < size_needed || NILP (f->desired_tool_bar_string))
8932 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8933 make_number (' '));
8934 else
8935 {
8936 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8937 Fremove_text_properties (make_number (0), make_number (size),
8938 props, f->desired_tool_bar_string);
8939 }
8940
8941 /* Put a `display' property on the string for the images to display,
8942 put a `menu_item' property on tool-bar items with a value that
8943 is the index of the item in F's tool-bar item vector. */
8944 for (i = 0; i < f->n_tool_bar_items; ++i)
8945 {
8946 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8947
8948 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8949 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8950 int hmargin, vmargin, relief, idx, end;
8951 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8952
8953 /* If image is a vector, choose the image according to the
8954 button state. */
8955 image = PROP (TOOL_BAR_ITEM_IMAGES);
8956 if (VECTORP (image))
8957 {
8958 if (enabled_p)
8959 idx = (selected_p
8960 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8961 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8962 else
8963 idx = (selected_p
8964 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8965 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8966
8967 xassert (ASIZE (image) >= idx);
8968 image = AREF (image, idx);
8969 }
8970 else
8971 idx = -1;
8972
8973 /* Ignore invalid image specifications. */
8974 if (!valid_image_p (image))
8975 continue;
8976
8977 /* Display the tool-bar button pressed, or depressed. */
8978 plist = Fcopy_sequence (XCDR (image));
8979
8980 /* Compute margin and relief to draw. */
8981 relief = (tool_bar_button_relief >= 0
8982 ? tool_bar_button_relief
8983 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8984 hmargin = vmargin = relief;
8985
8986 if (INTEGERP (Vtool_bar_button_margin)
8987 && XINT (Vtool_bar_button_margin) > 0)
8988 {
8989 hmargin += XFASTINT (Vtool_bar_button_margin);
8990 vmargin += XFASTINT (Vtool_bar_button_margin);
8991 }
8992 else if (CONSP (Vtool_bar_button_margin))
8993 {
8994 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8995 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8996 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8997
8998 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8999 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
9000 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
9001 }
9002
9003 if (auto_raise_tool_bar_buttons_p)
9004 {
9005 /* Add a `:relief' property to the image spec if the item is
9006 selected. */
9007 if (selected_p)
9008 {
9009 plist = Fplist_put (plist, QCrelief, make_number (-relief));
9010 hmargin -= relief;
9011 vmargin -= relief;
9012 }
9013 }
9014 else
9015 {
9016 /* If image is selected, display it pressed, i.e. with a
9017 negative relief. If it's not selected, display it with a
9018 raised relief. */
9019 plist = Fplist_put (plist, QCrelief,
9020 (selected_p
9021 ? make_number (-relief)
9022 : make_number (relief)));
9023 hmargin -= relief;
9024 vmargin -= relief;
9025 }
9026
9027 /* Put a margin around the image. */
9028 if (hmargin || vmargin)
9029 {
9030 if (hmargin == vmargin)
9031 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9032 else
9033 plist = Fplist_put (plist, QCmargin,
9034 Fcons (make_number (hmargin),
9035 make_number (vmargin)));
9036 }
9037
9038 /* If button is not enabled, and we don't have special images
9039 for the disabled state, make the image appear disabled by
9040 applying an appropriate algorithm to it. */
9041 if (!enabled_p && idx < 0)
9042 plist = Fplist_put (plist, QCconversion, Qdisabled);
9043
9044 /* Put a `display' text property on the string for the image to
9045 display. Put a `menu-item' property on the string that gives
9046 the start of this item's properties in the tool-bar items
9047 vector. */
9048 image = Fcons (Qimage, plist);
9049 props = list4 (Qdisplay, image,
9050 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9051
9052 /* Let the last image hide all remaining spaces in the tool bar
9053 string. The string can be longer than needed when we reuse a
9054 previous string. */
9055 if (i + 1 == f->n_tool_bar_items)
9056 end = SCHARS (f->desired_tool_bar_string);
9057 else
9058 end = i + 1;
9059 Fadd_text_properties (make_number (i), make_number (end),
9060 props, f->desired_tool_bar_string);
9061 #undef PROP
9062 }
9063
9064 UNGCPRO;
9065 }
9066
9067
9068 /* Display one line of the tool-bar of frame IT->f. */
9069
9070 static void
9071 display_tool_bar_line (it)
9072 struct it *it;
9073 {
9074 struct glyph_row *row = it->glyph_row;
9075 int max_x = it->last_visible_x;
9076 struct glyph *last;
9077
9078 prepare_desired_row (row);
9079 row->y = it->current_y;
9080
9081 /* Note that this isn't made use of if the face hasn't a box,
9082 so there's no need to check the face here. */
9083 it->start_of_box_run_p = 1;
9084
9085 while (it->current_x < max_x)
9086 {
9087 int x_before, x, n_glyphs_before, i, nglyphs;
9088
9089 /* Get the next display element. */
9090 if (!get_next_display_element (it))
9091 break;
9092
9093 /* Produce glyphs. */
9094 x_before = it->current_x;
9095 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
9096 PRODUCE_GLYPHS (it);
9097
9098 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
9099 i = 0;
9100 x = x_before;
9101 while (i < nglyphs)
9102 {
9103 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9104
9105 if (x + glyph->pixel_width > max_x)
9106 {
9107 /* Glyph doesn't fit on line. */
9108 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
9109 it->current_x = x;
9110 goto out;
9111 }
9112
9113 ++it->hpos;
9114 x += glyph->pixel_width;
9115 ++i;
9116 }
9117
9118 /* Stop at line ends. */
9119 if (ITERATOR_AT_END_OF_LINE_P (it))
9120 break;
9121
9122 set_iterator_to_next (it, 1);
9123 }
9124
9125 out:;
9126
9127 row->displays_text_p = row->used[TEXT_AREA] != 0;
9128 extend_face_to_end_of_line (it);
9129 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9130 last->right_box_line_p = 1;
9131 if (last == row->glyphs[TEXT_AREA])
9132 last->left_box_line_p = 1;
9133 compute_line_metrics (it);
9134
9135 /* If line is empty, make it occupy the rest of the tool-bar. */
9136 if (!row->displays_text_p)
9137 {
9138 row->height = row->phys_height = it->last_visible_y - row->y;
9139 row->ascent = row->phys_ascent = 0;
9140 row->extra_line_spacing = 0;
9141 }
9142
9143 row->full_width_p = 1;
9144 row->continued_p = 0;
9145 row->truncated_on_left_p = 0;
9146 row->truncated_on_right_p = 0;
9147
9148 it->current_x = it->hpos = 0;
9149 it->current_y += row->height;
9150 ++it->vpos;
9151 ++it->glyph_row;
9152 }
9153
9154
9155 /* Value is the number of screen lines needed to make all tool-bar
9156 items of frame F visible. */
9157
9158 static int
9159 tool_bar_lines_needed (f)
9160 struct frame *f;
9161 {
9162 struct window *w = XWINDOW (f->tool_bar_window);
9163 struct it it;
9164
9165 /* Initialize an iterator for iteration over
9166 F->desired_tool_bar_string in the tool-bar window of frame F. */
9167 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9168 it.first_visible_x = 0;
9169 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9170 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9171
9172 while (!ITERATOR_AT_END_P (&it))
9173 {
9174 it.glyph_row = w->desired_matrix->rows;
9175 clear_glyph_row (it.glyph_row);
9176 display_tool_bar_line (&it);
9177 }
9178
9179 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9180 }
9181
9182
9183 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
9184 0, 1, 0,
9185 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
9186 (frame)
9187 Lisp_Object frame;
9188 {
9189 struct frame *f;
9190 struct window *w;
9191 int nlines = 0;
9192
9193 if (NILP (frame))
9194 frame = selected_frame;
9195 else
9196 CHECK_FRAME (frame);
9197 f = XFRAME (frame);
9198
9199 if (WINDOWP (f->tool_bar_window)
9200 || (w = XWINDOW (f->tool_bar_window),
9201 WINDOW_TOTAL_LINES (w) > 0))
9202 {
9203 update_tool_bar (f, 1);
9204 if (f->n_tool_bar_items)
9205 {
9206 build_desired_tool_bar_string (f);
9207 nlines = tool_bar_lines_needed (f);
9208 }
9209 }
9210
9211 return make_number (nlines);
9212 }
9213
9214
9215 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9216 height should be changed. */
9217
9218 static int
9219 redisplay_tool_bar (f)
9220 struct frame *f;
9221 {
9222 struct window *w;
9223 struct it it;
9224 struct glyph_row *row;
9225 int change_height_p = 0;
9226
9227 #ifdef USE_GTK
9228 if (FRAME_EXTERNAL_TOOL_BAR (f))
9229 update_frame_tool_bar (f);
9230 return 0;
9231 #endif
9232
9233 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9234 do anything. This means you must start with tool-bar-lines
9235 non-zero to get the auto-sizing effect. Or in other words, you
9236 can turn off tool-bars by specifying tool-bar-lines zero. */
9237 if (!WINDOWP (f->tool_bar_window)
9238 || (w = XWINDOW (f->tool_bar_window),
9239 WINDOW_TOTAL_LINES (w) == 0))
9240 return 0;
9241
9242 /* Set up an iterator for the tool-bar window. */
9243 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9244 it.first_visible_x = 0;
9245 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9246 row = it.glyph_row;
9247
9248 /* Build a string that represents the contents of the tool-bar. */
9249 build_desired_tool_bar_string (f);
9250 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9251
9252 /* Display as many lines as needed to display all tool-bar items. */
9253 while (it.current_y < it.last_visible_y)
9254 display_tool_bar_line (&it);
9255
9256 /* It doesn't make much sense to try scrolling in the tool-bar
9257 window, so don't do it. */
9258 w->desired_matrix->no_scrolling_p = 1;
9259 w->must_be_updated_p = 1;
9260
9261 if (auto_resize_tool_bars_p)
9262 {
9263 int nlines;
9264
9265 /* If we couldn't display everything, change the tool-bar's
9266 height. */
9267 if (IT_STRING_CHARPOS (it) < it.end_charpos)
9268 change_height_p = 1;
9269
9270 /* If there are blank lines at the end, except for a partially
9271 visible blank line at the end that is smaller than
9272 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9273 row = it.glyph_row - 1;
9274 if (!row->displays_text_p
9275 && row->height >= FRAME_LINE_HEIGHT (f))
9276 change_height_p = 1;
9277
9278 /* If row displays tool-bar items, but is partially visible,
9279 change the tool-bar's height. */
9280 if (row->displays_text_p
9281 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
9282 change_height_p = 1;
9283
9284 /* Resize windows as needed by changing the `tool-bar-lines'
9285 frame parameter. */
9286 if (change_height_p
9287 && (nlines = tool_bar_lines_needed (f),
9288 nlines != WINDOW_TOTAL_LINES (w)))
9289 {
9290 extern Lisp_Object Qtool_bar_lines;
9291 Lisp_Object frame;
9292 int old_height = WINDOW_TOTAL_LINES (w);
9293
9294 XSETFRAME (frame, f);
9295 clear_glyph_matrix (w->desired_matrix);
9296 Fmodify_frame_parameters (frame,
9297 Fcons (Fcons (Qtool_bar_lines,
9298 make_number (nlines)),
9299 Qnil));
9300 if (WINDOW_TOTAL_LINES (w) != old_height)
9301 fonts_changed_p = 1;
9302 }
9303 }
9304
9305 return change_height_p;
9306 }
9307
9308
9309 /* Get information about the tool-bar item which is displayed in GLYPH
9310 on frame F. Return in *PROP_IDX the index where tool-bar item
9311 properties start in F->tool_bar_items. Value is zero if
9312 GLYPH doesn't display a tool-bar item. */
9313
9314 static int
9315 tool_bar_item_info (f, glyph, prop_idx)
9316 struct frame *f;
9317 struct glyph *glyph;
9318 int *prop_idx;
9319 {
9320 Lisp_Object prop;
9321 int success_p;
9322 int charpos;
9323
9324 /* This function can be called asynchronously, which means we must
9325 exclude any possibility that Fget_text_property signals an
9326 error. */
9327 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9328 charpos = max (0, charpos);
9329
9330 /* Get the text property `menu-item' at pos. The value of that
9331 property is the start index of this item's properties in
9332 F->tool_bar_items. */
9333 prop = Fget_text_property (make_number (charpos),
9334 Qmenu_item, f->current_tool_bar_string);
9335 if (INTEGERP (prop))
9336 {
9337 *prop_idx = XINT (prop);
9338 success_p = 1;
9339 }
9340 else
9341 success_p = 0;
9342
9343 return success_p;
9344 }
9345
9346 \f
9347 /* Get information about the tool-bar item at position X/Y on frame F.
9348 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9349 the current matrix of the tool-bar window of F, or NULL if not
9350 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9351 item in F->tool_bar_items. Value is
9352
9353 -1 if X/Y is not on a tool-bar item
9354 0 if X/Y is on the same item that was highlighted before.
9355 1 otherwise. */
9356
9357 static int
9358 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
9359 struct frame *f;
9360 int x, y;
9361 struct glyph **glyph;
9362 int *hpos, *vpos, *prop_idx;
9363 {
9364 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9365 struct window *w = XWINDOW (f->tool_bar_window);
9366 int area;
9367
9368 /* Find the glyph under X/Y. */
9369 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
9370 if (*glyph == NULL)
9371 return -1;
9372
9373 /* Get the start of this tool-bar item's properties in
9374 f->tool_bar_items. */
9375 if (!tool_bar_item_info (f, *glyph, prop_idx))
9376 return -1;
9377
9378 /* Is mouse on the highlighted item? */
9379 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9380 && *vpos >= dpyinfo->mouse_face_beg_row
9381 && *vpos <= dpyinfo->mouse_face_end_row
9382 && (*vpos > dpyinfo->mouse_face_beg_row
9383 || *hpos >= dpyinfo->mouse_face_beg_col)
9384 && (*vpos < dpyinfo->mouse_face_end_row
9385 || *hpos < dpyinfo->mouse_face_end_col
9386 || dpyinfo->mouse_face_past_end))
9387 return 0;
9388
9389 return 1;
9390 }
9391
9392
9393 /* EXPORT:
9394 Handle mouse button event on the tool-bar of frame F, at
9395 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9396 0 for button release. MODIFIERS is event modifiers for button
9397 release. */
9398
9399 void
9400 handle_tool_bar_click (f, x, y, down_p, modifiers)
9401 struct frame *f;
9402 int x, y, down_p;
9403 unsigned int modifiers;
9404 {
9405 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9406 struct window *w = XWINDOW (f->tool_bar_window);
9407 int hpos, vpos, prop_idx;
9408 struct glyph *glyph;
9409 Lisp_Object enabled_p;
9410
9411 /* If not on the highlighted tool-bar item, return. */
9412 frame_to_window_pixel_xy (w, &x, &y);
9413 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9414 return;
9415
9416 /* If item is disabled, do nothing. */
9417 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9418 if (NILP (enabled_p))
9419 return;
9420
9421 if (down_p)
9422 {
9423 /* Show item in pressed state. */
9424 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9425 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9426 last_tool_bar_item = prop_idx;
9427 }
9428 else
9429 {
9430 Lisp_Object key, frame;
9431 struct input_event event;
9432 EVENT_INIT (event);
9433
9434 /* Show item in released state. */
9435 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9436 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9437
9438 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9439
9440 XSETFRAME (frame, f);
9441 event.kind = TOOL_BAR_EVENT;
9442 event.frame_or_window = frame;
9443 event.arg = frame;
9444 kbd_buffer_store_event (&event);
9445
9446 event.kind = TOOL_BAR_EVENT;
9447 event.frame_or_window = frame;
9448 event.arg = key;
9449 event.modifiers = modifiers;
9450 kbd_buffer_store_event (&event);
9451 last_tool_bar_item = -1;
9452 }
9453 }
9454
9455
9456 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9457 tool-bar window-relative coordinates X/Y. Called from
9458 note_mouse_highlight. */
9459
9460 static void
9461 note_tool_bar_highlight (f, x, y)
9462 struct frame *f;
9463 int x, y;
9464 {
9465 Lisp_Object window = f->tool_bar_window;
9466 struct window *w = XWINDOW (window);
9467 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9468 int hpos, vpos;
9469 struct glyph *glyph;
9470 struct glyph_row *row;
9471 int i;
9472 Lisp_Object enabled_p;
9473 int prop_idx;
9474 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9475 int mouse_down_p, rc;
9476
9477 /* Function note_mouse_highlight is called with negative x(y
9478 values when mouse moves outside of the frame. */
9479 if (x <= 0 || y <= 0)
9480 {
9481 clear_mouse_face (dpyinfo);
9482 return;
9483 }
9484
9485 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9486 if (rc < 0)
9487 {
9488 /* Not on tool-bar item. */
9489 clear_mouse_face (dpyinfo);
9490 return;
9491 }
9492 else if (rc == 0)
9493 /* On same tool-bar item as before. */
9494 goto set_help_echo;
9495
9496 clear_mouse_face (dpyinfo);
9497
9498 /* Mouse is down, but on different tool-bar item? */
9499 mouse_down_p = (dpyinfo->grabbed
9500 && f == last_mouse_frame
9501 && FRAME_LIVE_P (f));
9502 if (mouse_down_p
9503 && last_tool_bar_item != prop_idx)
9504 return;
9505
9506 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9507 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9508
9509 /* If tool-bar item is not enabled, don't highlight it. */
9510 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9511 if (!NILP (enabled_p))
9512 {
9513 /* Compute the x-position of the glyph. In front and past the
9514 image is a space. We include this in the highlighted area. */
9515 row = MATRIX_ROW (w->current_matrix, vpos);
9516 for (i = x = 0; i < hpos; ++i)
9517 x += row->glyphs[TEXT_AREA][i].pixel_width;
9518
9519 /* Record this as the current active region. */
9520 dpyinfo->mouse_face_beg_col = hpos;
9521 dpyinfo->mouse_face_beg_row = vpos;
9522 dpyinfo->mouse_face_beg_x = x;
9523 dpyinfo->mouse_face_beg_y = row->y;
9524 dpyinfo->mouse_face_past_end = 0;
9525
9526 dpyinfo->mouse_face_end_col = hpos + 1;
9527 dpyinfo->mouse_face_end_row = vpos;
9528 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9529 dpyinfo->mouse_face_end_y = row->y;
9530 dpyinfo->mouse_face_window = window;
9531 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9532
9533 /* Display it as active. */
9534 show_mouse_face (dpyinfo, draw);
9535 dpyinfo->mouse_face_image_state = draw;
9536 }
9537
9538 set_help_echo:
9539
9540 /* Set help_echo_string to a help string to display for this tool-bar item.
9541 XTread_socket does the rest. */
9542 help_echo_object = help_echo_window = Qnil;
9543 help_echo_pos = -1;
9544 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9545 if (NILP (help_echo_string))
9546 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9547 }
9548
9549 #endif /* HAVE_WINDOW_SYSTEM */
9550
9551
9552 \f
9553 /************************************************************************
9554 Horizontal scrolling
9555 ************************************************************************/
9556
9557 static int hscroll_window_tree P_ ((Lisp_Object));
9558 static int hscroll_windows P_ ((Lisp_Object));
9559
9560 /* For all leaf windows in the window tree rooted at WINDOW, set their
9561 hscroll value so that PT is (i) visible in the window, and (ii) so
9562 that it is not within a certain margin at the window's left and
9563 right border. Value is non-zero if any window's hscroll has been
9564 changed. */
9565
9566 static int
9567 hscroll_window_tree (window)
9568 Lisp_Object window;
9569 {
9570 int hscrolled_p = 0;
9571 int hscroll_relative_p = FLOATP (Vhscroll_step);
9572 int hscroll_step_abs = 0;
9573 double hscroll_step_rel = 0;
9574
9575 if (hscroll_relative_p)
9576 {
9577 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9578 if (hscroll_step_rel < 0)
9579 {
9580 hscroll_relative_p = 0;
9581 hscroll_step_abs = 0;
9582 }
9583 }
9584 else if (INTEGERP (Vhscroll_step))
9585 {
9586 hscroll_step_abs = XINT (Vhscroll_step);
9587 if (hscroll_step_abs < 0)
9588 hscroll_step_abs = 0;
9589 }
9590 else
9591 hscroll_step_abs = 0;
9592
9593 while (WINDOWP (window))
9594 {
9595 struct window *w = XWINDOW (window);
9596
9597 if (WINDOWP (w->hchild))
9598 hscrolled_p |= hscroll_window_tree (w->hchild);
9599 else if (WINDOWP (w->vchild))
9600 hscrolled_p |= hscroll_window_tree (w->vchild);
9601 else if (w->cursor.vpos >= 0)
9602 {
9603 int h_margin;
9604 int text_area_width;
9605 struct glyph_row *current_cursor_row
9606 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9607 struct glyph_row *desired_cursor_row
9608 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9609 struct glyph_row *cursor_row
9610 = (desired_cursor_row->enabled_p
9611 ? desired_cursor_row
9612 : current_cursor_row);
9613
9614 text_area_width = window_box_width (w, TEXT_AREA);
9615
9616 /* Scroll when cursor is inside this scroll margin. */
9617 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9618
9619 if ((XFASTINT (w->hscroll)
9620 && w->cursor.x <= h_margin)
9621 || (cursor_row->enabled_p
9622 && cursor_row->truncated_on_right_p
9623 && (w->cursor.x >= text_area_width - h_margin)))
9624 {
9625 struct it it;
9626 int hscroll;
9627 struct buffer *saved_current_buffer;
9628 int pt;
9629 int wanted_x;
9630
9631 /* Find point in a display of infinite width. */
9632 saved_current_buffer = current_buffer;
9633 current_buffer = XBUFFER (w->buffer);
9634
9635 if (w == XWINDOW (selected_window))
9636 pt = BUF_PT (current_buffer);
9637 else
9638 {
9639 pt = marker_position (w->pointm);
9640 pt = max (BEGV, pt);
9641 pt = min (ZV, pt);
9642 }
9643
9644 /* Move iterator to pt starting at cursor_row->start in
9645 a line with infinite width. */
9646 init_to_row_start (&it, w, cursor_row);
9647 it.last_visible_x = INFINITY;
9648 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9649 current_buffer = saved_current_buffer;
9650
9651 /* Position cursor in window. */
9652 if (!hscroll_relative_p && hscroll_step_abs == 0)
9653 hscroll = max (0, (it.current_x
9654 - (ITERATOR_AT_END_OF_LINE_P (&it)
9655 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9656 : (text_area_width / 2))))
9657 / FRAME_COLUMN_WIDTH (it.f);
9658 else if (w->cursor.x >= text_area_width - h_margin)
9659 {
9660 if (hscroll_relative_p)
9661 wanted_x = text_area_width * (1 - hscroll_step_rel)
9662 - h_margin;
9663 else
9664 wanted_x = text_area_width
9665 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9666 - h_margin;
9667 hscroll
9668 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9669 }
9670 else
9671 {
9672 if (hscroll_relative_p)
9673 wanted_x = text_area_width * hscroll_step_rel
9674 + h_margin;
9675 else
9676 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9677 + h_margin;
9678 hscroll
9679 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9680 }
9681 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9682
9683 /* Don't call Fset_window_hscroll if value hasn't
9684 changed because it will prevent redisplay
9685 optimizations. */
9686 if (XFASTINT (w->hscroll) != hscroll)
9687 {
9688 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9689 w->hscroll = make_number (hscroll);
9690 hscrolled_p = 1;
9691 }
9692 }
9693 }
9694
9695 window = w->next;
9696 }
9697
9698 /* Value is non-zero if hscroll of any leaf window has been changed. */
9699 return hscrolled_p;
9700 }
9701
9702
9703 /* Set hscroll so that cursor is visible and not inside horizontal
9704 scroll margins for all windows in the tree rooted at WINDOW. See
9705 also hscroll_window_tree above. Value is non-zero if any window's
9706 hscroll has been changed. If it has, desired matrices on the frame
9707 of WINDOW are cleared. */
9708
9709 static int
9710 hscroll_windows (window)
9711 Lisp_Object window;
9712 {
9713 int hscrolled_p;
9714
9715 if (automatic_hscrolling_p)
9716 {
9717 hscrolled_p = hscroll_window_tree (window);
9718 if (hscrolled_p)
9719 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9720 }
9721 else
9722 hscrolled_p = 0;
9723 return hscrolled_p;
9724 }
9725
9726
9727 \f
9728 /************************************************************************
9729 Redisplay
9730 ************************************************************************/
9731
9732 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9733 to a non-zero value. This is sometimes handy to have in a debugger
9734 session. */
9735
9736 #if GLYPH_DEBUG
9737
9738 /* First and last unchanged row for try_window_id. */
9739
9740 int debug_first_unchanged_at_end_vpos;
9741 int debug_last_unchanged_at_beg_vpos;
9742
9743 /* Delta vpos and y. */
9744
9745 int debug_dvpos, debug_dy;
9746
9747 /* Delta in characters and bytes for try_window_id. */
9748
9749 int debug_delta, debug_delta_bytes;
9750
9751 /* Values of window_end_pos and window_end_vpos at the end of
9752 try_window_id. */
9753
9754 EMACS_INT debug_end_pos, debug_end_vpos;
9755
9756 /* Append a string to W->desired_matrix->method. FMT is a printf
9757 format string. A1...A9 are a supplement for a variable-length
9758 argument list. If trace_redisplay_p is non-zero also printf the
9759 resulting string to stderr. */
9760
9761 static void
9762 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9763 struct window *w;
9764 char *fmt;
9765 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9766 {
9767 char buffer[512];
9768 char *method = w->desired_matrix->method;
9769 int len = strlen (method);
9770 int size = sizeof w->desired_matrix->method;
9771 int remaining = size - len - 1;
9772
9773 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9774 if (len && remaining)
9775 {
9776 method[len] = '|';
9777 --remaining, ++len;
9778 }
9779
9780 strncpy (method + len, buffer, remaining);
9781
9782 if (trace_redisplay_p)
9783 fprintf (stderr, "%p (%s): %s\n",
9784 w,
9785 ((BUFFERP (w->buffer)
9786 && STRINGP (XBUFFER (w->buffer)->name))
9787 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9788 : "no buffer"),
9789 buffer);
9790 }
9791
9792 #endif /* GLYPH_DEBUG */
9793
9794
9795 /* Value is non-zero if all changes in window W, which displays
9796 current_buffer, are in the text between START and END. START is a
9797 buffer position, END is given as a distance from Z. Used in
9798 redisplay_internal for display optimization. */
9799
9800 static INLINE int
9801 text_outside_line_unchanged_p (w, start, end)
9802 struct window *w;
9803 int start, end;
9804 {
9805 int unchanged_p = 1;
9806
9807 /* If text or overlays have changed, see where. */
9808 if (XFASTINT (w->last_modified) < MODIFF
9809 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9810 {
9811 /* Gap in the line? */
9812 if (GPT < start || Z - GPT < end)
9813 unchanged_p = 0;
9814
9815 /* Changes start in front of the line, or end after it? */
9816 if (unchanged_p
9817 && (BEG_UNCHANGED < start - 1
9818 || END_UNCHANGED < end))
9819 unchanged_p = 0;
9820
9821 /* If selective display, can't optimize if changes start at the
9822 beginning of the line. */
9823 if (unchanged_p
9824 && INTEGERP (current_buffer->selective_display)
9825 && XINT (current_buffer->selective_display) > 0
9826 && (BEG_UNCHANGED < start || GPT <= start))
9827 unchanged_p = 0;
9828
9829 /* If there are overlays at the start or end of the line, these
9830 may have overlay strings with newlines in them. A change at
9831 START, for instance, may actually concern the display of such
9832 overlay strings as well, and they are displayed on different
9833 lines. So, quickly rule out this case. (For the future, it
9834 might be desirable to implement something more telling than
9835 just BEG/END_UNCHANGED.) */
9836 if (unchanged_p)
9837 {
9838 if (BEG + BEG_UNCHANGED == start
9839 && overlay_touches_p (start))
9840 unchanged_p = 0;
9841 if (END_UNCHANGED == end
9842 && overlay_touches_p (Z - end))
9843 unchanged_p = 0;
9844 }
9845 }
9846
9847 return unchanged_p;
9848 }
9849
9850
9851 /* Do a frame update, taking possible shortcuts into account. This is
9852 the main external entry point for redisplay.
9853
9854 If the last redisplay displayed an echo area message and that message
9855 is no longer requested, we clear the echo area or bring back the
9856 mini-buffer if that is in use. */
9857
9858 void
9859 redisplay ()
9860 {
9861 redisplay_internal (0);
9862 }
9863
9864
9865 static Lisp_Object
9866 overlay_arrow_string_or_property (var)
9867 Lisp_Object var;
9868 {
9869 Lisp_Object val;
9870
9871 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
9872 return val;
9873
9874 return Voverlay_arrow_string;
9875 }
9876
9877 /* Return 1 if there are any overlay-arrows in current_buffer. */
9878 static int
9879 overlay_arrow_in_current_buffer_p ()
9880 {
9881 Lisp_Object vlist;
9882
9883 for (vlist = Voverlay_arrow_variable_list;
9884 CONSP (vlist);
9885 vlist = XCDR (vlist))
9886 {
9887 Lisp_Object var = XCAR (vlist);
9888 Lisp_Object val;
9889
9890 if (!SYMBOLP (var))
9891 continue;
9892 val = find_symbol_value (var);
9893 if (MARKERP (val)
9894 && current_buffer == XMARKER (val)->buffer)
9895 return 1;
9896 }
9897 return 0;
9898 }
9899
9900
9901 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9902 has changed. */
9903
9904 static int
9905 overlay_arrows_changed_p ()
9906 {
9907 Lisp_Object vlist;
9908
9909 for (vlist = Voverlay_arrow_variable_list;
9910 CONSP (vlist);
9911 vlist = XCDR (vlist))
9912 {
9913 Lisp_Object var = XCAR (vlist);
9914 Lisp_Object val, pstr;
9915
9916 if (!SYMBOLP (var))
9917 continue;
9918 val = find_symbol_value (var);
9919 if (!MARKERP (val))
9920 continue;
9921 if (! EQ (COERCE_MARKER (val),
9922 Fget (var, Qlast_arrow_position))
9923 || ! (pstr = overlay_arrow_string_or_property (var),
9924 EQ (pstr, Fget (var, Qlast_arrow_string))))
9925 return 1;
9926 }
9927 return 0;
9928 }
9929
9930 /* Mark overlay arrows to be updated on next redisplay. */
9931
9932 static void
9933 update_overlay_arrows (up_to_date)
9934 int up_to_date;
9935 {
9936 Lisp_Object vlist;
9937
9938 for (vlist = Voverlay_arrow_variable_list;
9939 CONSP (vlist);
9940 vlist = XCDR (vlist))
9941 {
9942 Lisp_Object var = XCAR (vlist);
9943
9944 if (!SYMBOLP (var))
9945 continue;
9946
9947 if (up_to_date > 0)
9948 {
9949 Lisp_Object val = find_symbol_value (var);
9950 Fput (var, Qlast_arrow_position,
9951 COERCE_MARKER (val));
9952 Fput (var, Qlast_arrow_string,
9953 overlay_arrow_string_or_property (var));
9954 }
9955 else if (up_to_date < 0
9956 || !NILP (Fget (var, Qlast_arrow_position)))
9957 {
9958 Fput (var, Qlast_arrow_position, Qt);
9959 Fput (var, Qlast_arrow_string, Qt);
9960 }
9961 }
9962 }
9963
9964
9965 /* Return overlay arrow string to display at row.
9966 Return integer (bitmap number) for arrow bitmap in left fringe.
9967 Return nil if no overlay arrow. */
9968
9969 static Lisp_Object
9970 overlay_arrow_at_row (it, row)
9971 struct it *it;
9972 struct glyph_row *row;
9973 {
9974 Lisp_Object vlist;
9975
9976 for (vlist = Voverlay_arrow_variable_list;
9977 CONSP (vlist);
9978 vlist = XCDR (vlist))
9979 {
9980 Lisp_Object var = XCAR (vlist);
9981 Lisp_Object val;
9982
9983 if (!SYMBOLP (var))
9984 continue;
9985
9986 val = find_symbol_value (var);
9987
9988 if (MARKERP (val)
9989 && current_buffer == XMARKER (val)->buffer
9990 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9991 {
9992 if (FRAME_WINDOW_P (it->f)
9993 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9994 {
9995 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
9996 {
9997 int fringe_bitmap;
9998 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
9999 return make_number (fringe_bitmap);
10000 }
10001 return make_number (-1); /* Use default arrow bitmap */
10002 }
10003 return overlay_arrow_string_or_property (var);
10004 }
10005 }
10006
10007 return Qnil;
10008 }
10009
10010 /* Return 1 if point moved out of or into a composition. Otherwise
10011 return 0. PREV_BUF and PREV_PT are the last point buffer and
10012 position. BUF and PT are the current point buffer and position. */
10013
10014 int
10015 check_point_in_composition (prev_buf, prev_pt, buf, pt)
10016 struct buffer *prev_buf, *buf;
10017 int prev_pt, pt;
10018 {
10019 int start, end;
10020 Lisp_Object prop;
10021 Lisp_Object buffer;
10022
10023 XSETBUFFER (buffer, buf);
10024 /* Check a composition at the last point if point moved within the
10025 same buffer. */
10026 if (prev_buf == buf)
10027 {
10028 if (prev_pt == pt)
10029 /* Point didn't move. */
10030 return 0;
10031
10032 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10033 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10034 && COMPOSITION_VALID_P (start, end, prop)
10035 && start < prev_pt && end > prev_pt)
10036 /* The last point was within the composition. Return 1 iff
10037 point moved out of the composition. */
10038 return (pt <= start || pt >= end);
10039 }
10040
10041 /* Check a composition at the current point. */
10042 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10043 && find_composition (pt, -1, &start, &end, &prop, buffer)
10044 && COMPOSITION_VALID_P (start, end, prop)
10045 && start < pt && end > pt);
10046 }
10047
10048
10049 /* Reconsider the setting of B->clip_changed which is displayed
10050 in window W. */
10051
10052 static INLINE void
10053 reconsider_clip_changes (w, b)
10054 struct window *w;
10055 struct buffer *b;
10056 {
10057 if (b->clip_changed
10058 && !NILP (w->window_end_valid)
10059 && w->current_matrix->buffer == b
10060 && w->current_matrix->zv == BUF_ZV (b)
10061 && w->current_matrix->begv == BUF_BEGV (b))
10062 b->clip_changed = 0;
10063
10064 /* If display wasn't paused, and W is not a tool bar window, see if
10065 point has been moved into or out of a composition. In that case,
10066 we set b->clip_changed to 1 to force updating the screen. If
10067 b->clip_changed has already been set to 1, we can skip this
10068 check. */
10069 if (!b->clip_changed
10070 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
10071 {
10072 int pt;
10073
10074 if (w == XWINDOW (selected_window))
10075 pt = BUF_PT (current_buffer);
10076 else
10077 pt = marker_position (w->pointm);
10078
10079 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
10080 || pt != XINT (w->last_point))
10081 && check_point_in_composition (w->current_matrix->buffer,
10082 XINT (w->last_point),
10083 XBUFFER (w->buffer), pt))
10084 b->clip_changed = 1;
10085 }
10086 }
10087 \f
10088
10089 /* Select FRAME to forward the values of frame-local variables into C
10090 variables so that the redisplay routines can access those values
10091 directly. */
10092
10093 static void
10094 select_frame_for_redisplay (frame)
10095 Lisp_Object frame;
10096 {
10097 Lisp_Object tail, sym, val;
10098 Lisp_Object old = selected_frame;
10099
10100 xassert (FRAMEP (frame) && FRAME_LIVE_P (XFRAME (frame)));
10101
10102 selected_frame = frame;
10103
10104 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
10105 if (CONSP (XCAR (tail))
10106 && (sym = XCAR (XCAR (tail)),
10107 SYMBOLP (sym))
10108 && (sym = indirect_variable (sym),
10109 val = SYMBOL_VALUE (sym),
10110 (BUFFER_LOCAL_VALUEP (val)
10111 || SOME_BUFFER_LOCAL_VALUEP (val)))
10112 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10113 /* Use find_symbol_value rather than Fsymbol_value
10114 to avoid an error if it is void. */
10115 find_symbol_value (sym);
10116
10117 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
10118 if (CONSP (XCAR (tail))
10119 && (sym = XCAR (XCAR (tail)),
10120 SYMBOLP (sym))
10121 && (sym = indirect_variable (sym),
10122 val = SYMBOL_VALUE (sym),
10123 (BUFFER_LOCAL_VALUEP (val)
10124 || SOME_BUFFER_LOCAL_VALUEP (val)))
10125 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10126 find_symbol_value (sym);
10127 }
10128
10129
10130 #define STOP_POLLING \
10131 do { if (! polling_stopped_here) stop_polling (); \
10132 polling_stopped_here = 1; } while (0)
10133
10134 #define RESUME_POLLING \
10135 do { if (polling_stopped_here) start_polling (); \
10136 polling_stopped_here = 0; } while (0)
10137
10138
10139 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
10140 response to any user action; therefore, we should preserve the echo
10141 area. (Actually, our caller does that job.) Perhaps in the future
10142 avoid recentering windows if it is not necessary; currently that
10143 causes some problems. */
10144
10145 static void
10146 redisplay_internal (preserve_echo_area)
10147 int preserve_echo_area;
10148 {
10149 struct window *w = XWINDOW (selected_window);
10150 struct frame *f = XFRAME (w->frame);
10151 int pause;
10152 int must_finish = 0;
10153 struct text_pos tlbufpos, tlendpos;
10154 int number_of_visible_frames;
10155 int count;
10156 struct frame *sf = SELECTED_FRAME ();
10157 int polling_stopped_here = 0;
10158
10159 /* Non-zero means redisplay has to consider all windows on all
10160 frames. Zero means, only selected_window is considered. */
10161 int consider_all_windows_p;
10162
10163 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
10164
10165 /* No redisplay if running in batch mode or frame is not yet fully
10166 initialized, or redisplay is explicitly turned off by setting
10167 Vinhibit_redisplay. */
10168 if (noninteractive
10169 || !NILP (Vinhibit_redisplay)
10170 || !f->glyphs_initialized_p)
10171 return;
10172
10173 /* The flag redisplay_performed_directly_p is set by
10174 direct_output_for_insert when it already did the whole screen
10175 update necessary. */
10176 if (redisplay_performed_directly_p)
10177 {
10178 redisplay_performed_directly_p = 0;
10179 if (!hscroll_windows (selected_window))
10180 return;
10181 }
10182
10183 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
10184 if (popup_activated ())
10185 return;
10186 #endif
10187
10188 /* I don't think this happens but let's be paranoid. */
10189 if (redisplaying_p)
10190 return;
10191
10192 /* Record a function that resets redisplaying_p to its old value
10193 when we leave this function. */
10194 count = SPECPDL_INDEX ();
10195 record_unwind_protect (unwind_redisplay,
10196 Fcons (make_number (redisplaying_p), selected_frame));
10197 ++redisplaying_p;
10198 specbind (Qinhibit_free_realized_faces, Qnil);
10199
10200 {
10201 Lisp_Object tail, frame;
10202
10203 FOR_EACH_FRAME (tail, frame)
10204 {
10205 struct frame *f = XFRAME (frame);
10206 f->already_hscrolled_p = 0;
10207 }
10208 }
10209
10210 retry:
10211 pause = 0;
10212 reconsider_clip_changes (w, current_buffer);
10213
10214 /* If new fonts have been loaded that make a glyph matrix adjustment
10215 necessary, do it. */
10216 if (fonts_changed_p)
10217 {
10218 adjust_glyphs (NULL);
10219 ++windows_or_buffers_changed;
10220 fonts_changed_p = 0;
10221 }
10222
10223 /* If face_change_count is non-zero, init_iterator will free all
10224 realized faces, which includes the faces referenced from current
10225 matrices. So, we can't reuse current matrices in this case. */
10226 if (face_change_count)
10227 ++windows_or_buffers_changed;
10228
10229 if (FRAME_TERMCAP_P (sf)
10230 && FRAME_TTY (sf)->previous_terminal_frame != sf)
10231 {
10232 /* Since frames on a single ASCII terminal share the same
10233 display area, displaying a different frame means redisplay
10234 the whole thing. */
10235 windows_or_buffers_changed++;
10236 SET_FRAME_GARBAGED (sf);
10237 FRAME_TTY (sf)->previous_terminal_frame = sf;
10238 }
10239
10240 /* Set the visible flags for all frames. Do this before checking
10241 for resized or garbaged frames; they want to know if their frames
10242 are visible. See the comment in frame.h for
10243 FRAME_SAMPLE_VISIBILITY. */
10244 {
10245 Lisp_Object tail, frame;
10246
10247 number_of_visible_frames = 0;
10248
10249 FOR_EACH_FRAME (tail, frame)
10250 {
10251 struct frame *f = XFRAME (frame);
10252
10253 FRAME_SAMPLE_VISIBILITY (f);
10254 if (FRAME_VISIBLE_P (f))
10255 ++number_of_visible_frames;
10256 clear_desired_matrices (f);
10257 }
10258 }
10259
10260
10261 /* Notice any pending interrupt request to change frame size. */
10262 do_pending_window_change (1);
10263
10264 /* Clear frames marked as garbaged. */
10265 if (frame_garbaged)
10266 clear_garbaged_frames ();
10267
10268 /* Build menubar and tool-bar items. */
10269 prepare_menu_bars ();
10270
10271 if (windows_or_buffers_changed)
10272 update_mode_lines++;
10273
10274 /* Detect case that we need to write or remove a star in the mode line. */
10275 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10276 {
10277 w->update_mode_line = Qt;
10278 if (buffer_shared > 1)
10279 update_mode_lines++;
10280 }
10281
10282 /* If %c is in the mode line, update it if needed. */
10283 if (!NILP (w->column_number_displayed)
10284 /* This alternative quickly identifies a common case
10285 where no change is needed. */
10286 && !(PT == XFASTINT (w->last_point)
10287 && XFASTINT (w->last_modified) >= MODIFF
10288 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10289 && (XFASTINT (w->column_number_displayed)
10290 != (int) current_column ())) /* iftc */
10291 w->update_mode_line = Qt;
10292
10293 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10294
10295 /* The variable buffer_shared is set in redisplay_window and
10296 indicates that we redisplay a buffer in different windows. See
10297 there. */
10298 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10299 || cursor_type_changed);
10300
10301 /* If specs for an arrow have changed, do thorough redisplay
10302 to ensure we remove any arrow that should no longer exist. */
10303 if (overlay_arrows_changed_p ())
10304 consider_all_windows_p = windows_or_buffers_changed = 1;
10305
10306 /* Normally the message* functions will have already displayed and
10307 updated the echo area, but the frame may have been trashed, or
10308 the update may have been preempted, so display the echo area
10309 again here. Checking message_cleared_p captures the case that
10310 the echo area should be cleared. */
10311 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10312 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10313 || (message_cleared_p
10314 && minibuf_level == 0
10315 /* If the mini-window is currently selected, this means the
10316 echo-area doesn't show through. */
10317 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10318 {
10319 int window_height_changed_p = echo_area_display (0);
10320 must_finish = 1;
10321
10322 /* If we don't display the current message, don't clear the
10323 message_cleared_p flag, because, if we did, we wouldn't clear
10324 the echo area in the next redisplay which doesn't preserve
10325 the echo area. */
10326 if (!display_last_displayed_message_p)
10327 message_cleared_p = 0;
10328
10329 if (fonts_changed_p)
10330 goto retry;
10331 else if (window_height_changed_p)
10332 {
10333 consider_all_windows_p = 1;
10334 ++update_mode_lines;
10335 ++windows_or_buffers_changed;
10336
10337 /* If window configuration was changed, frames may have been
10338 marked garbaged. Clear them or we will experience
10339 surprises wrt scrolling. */
10340 if (frame_garbaged)
10341 clear_garbaged_frames ();
10342 }
10343 }
10344 else if (EQ (selected_window, minibuf_window)
10345 && (current_buffer->clip_changed
10346 || XFASTINT (w->last_modified) < MODIFF
10347 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10348 && resize_mini_window (w, 0))
10349 {
10350 /* Resized active mini-window to fit the size of what it is
10351 showing if its contents might have changed. */
10352 must_finish = 1;
10353 consider_all_windows_p = 1;
10354 ++windows_or_buffers_changed;
10355 ++update_mode_lines;
10356
10357 /* If window configuration was changed, frames may have been
10358 marked garbaged. Clear them or we will experience
10359 surprises wrt scrolling. */
10360 if (frame_garbaged)
10361 clear_garbaged_frames ();
10362 }
10363
10364
10365 /* If showing the region, and mark has changed, we must redisplay
10366 the whole window. The assignment to this_line_start_pos prevents
10367 the optimization directly below this if-statement. */
10368 if (((!NILP (Vtransient_mark_mode)
10369 && !NILP (XBUFFER (w->buffer)->mark_active))
10370 != !NILP (w->region_showing))
10371 || (!NILP (w->region_showing)
10372 && !EQ (w->region_showing,
10373 Fmarker_position (XBUFFER (w->buffer)->mark))))
10374 CHARPOS (this_line_start_pos) = 0;
10375
10376 /* Optimize the case that only the line containing the cursor in the
10377 selected window has changed. Variables starting with this_ are
10378 set in display_line and record information about the line
10379 containing the cursor. */
10380 tlbufpos = this_line_start_pos;
10381 tlendpos = this_line_end_pos;
10382 if (!consider_all_windows_p
10383 && CHARPOS (tlbufpos) > 0
10384 && NILP (w->update_mode_line)
10385 && !current_buffer->clip_changed
10386 && !current_buffer->prevent_redisplay_optimizations_p
10387 && FRAME_VISIBLE_P (XFRAME (w->frame))
10388 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10389 /* Make sure recorded data applies to current buffer, etc. */
10390 && this_line_buffer == current_buffer
10391 && current_buffer == XBUFFER (w->buffer)
10392 && NILP (w->force_start)
10393 && NILP (w->optional_new_start)
10394 /* Point must be on the line that we have info recorded about. */
10395 && PT >= CHARPOS (tlbufpos)
10396 && PT <= Z - CHARPOS (tlendpos)
10397 /* All text outside that line, including its final newline,
10398 must be unchanged */
10399 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10400 CHARPOS (tlendpos)))
10401 {
10402 if (CHARPOS (tlbufpos) > BEGV
10403 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10404 && (CHARPOS (tlbufpos) == ZV
10405 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10406 /* Former continuation line has disappeared by becoming empty */
10407 goto cancel;
10408 else if (XFASTINT (w->last_modified) < MODIFF
10409 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10410 || MINI_WINDOW_P (w))
10411 {
10412 /* We have to handle the case of continuation around a
10413 wide-column character (See the comment in indent.c around
10414 line 885).
10415
10416 For instance, in the following case:
10417
10418 -------- Insert --------
10419 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10420 J_I_ ==> J_I_ `^^' are cursors.
10421 ^^ ^^
10422 -------- --------
10423
10424 As we have to redraw the line above, we should goto cancel. */
10425
10426 struct it it;
10427 int line_height_before = this_line_pixel_height;
10428
10429 /* Note that start_display will handle the case that the
10430 line starting at tlbufpos is a continuation lines. */
10431 start_display (&it, w, tlbufpos);
10432
10433 /* Implementation note: It this still necessary? */
10434 if (it.current_x != this_line_start_x)
10435 goto cancel;
10436
10437 TRACE ((stderr, "trying display optimization 1\n"));
10438 w->cursor.vpos = -1;
10439 overlay_arrow_seen = 0;
10440 it.vpos = this_line_vpos;
10441 it.current_y = this_line_y;
10442 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10443 display_line (&it);
10444
10445 /* If line contains point, is not continued,
10446 and ends at same distance from eob as before, we win */
10447 if (w->cursor.vpos >= 0
10448 /* Line is not continued, otherwise this_line_start_pos
10449 would have been set to 0 in display_line. */
10450 && CHARPOS (this_line_start_pos)
10451 /* Line ends as before. */
10452 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10453 /* Line has same height as before. Otherwise other lines
10454 would have to be shifted up or down. */
10455 && this_line_pixel_height == line_height_before)
10456 {
10457 /* If this is not the window's last line, we must adjust
10458 the charstarts of the lines below. */
10459 if (it.current_y < it.last_visible_y)
10460 {
10461 struct glyph_row *row
10462 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10463 int delta, delta_bytes;
10464
10465 if (Z - CHARPOS (tlendpos) == ZV)
10466 {
10467 /* This line ends at end of (accessible part of)
10468 buffer. There is no newline to count. */
10469 delta = (Z
10470 - CHARPOS (tlendpos)
10471 - MATRIX_ROW_START_CHARPOS (row));
10472 delta_bytes = (Z_BYTE
10473 - BYTEPOS (tlendpos)
10474 - MATRIX_ROW_START_BYTEPOS (row));
10475 }
10476 else
10477 {
10478 /* This line ends in a newline. Must take
10479 account of the newline and the rest of the
10480 text that follows. */
10481 delta = (Z
10482 - CHARPOS (tlendpos)
10483 - MATRIX_ROW_START_CHARPOS (row));
10484 delta_bytes = (Z_BYTE
10485 - BYTEPOS (tlendpos)
10486 - MATRIX_ROW_START_BYTEPOS (row));
10487 }
10488
10489 increment_matrix_positions (w->current_matrix,
10490 this_line_vpos + 1,
10491 w->current_matrix->nrows,
10492 delta, delta_bytes);
10493 }
10494
10495 /* If this row displays text now but previously didn't,
10496 or vice versa, w->window_end_vpos may have to be
10497 adjusted. */
10498 if ((it.glyph_row - 1)->displays_text_p)
10499 {
10500 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10501 XSETINT (w->window_end_vpos, this_line_vpos);
10502 }
10503 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10504 && this_line_vpos > 0)
10505 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10506 w->window_end_valid = Qnil;
10507
10508 /* Update hint: No need to try to scroll in update_window. */
10509 w->desired_matrix->no_scrolling_p = 1;
10510
10511 #if GLYPH_DEBUG
10512 *w->desired_matrix->method = 0;
10513 debug_method_add (w, "optimization 1");
10514 #endif
10515 #ifdef HAVE_WINDOW_SYSTEM
10516 update_window_fringes (w, 0);
10517 #endif
10518 goto update;
10519 }
10520 else
10521 goto cancel;
10522 }
10523 else if (/* Cursor position hasn't changed. */
10524 PT == XFASTINT (w->last_point)
10525 /* Make sure the cursor was last displayed
10526 in this window. Otherwise we have to reposition it. */
10527 && 0 <= w->cursor.vpos
10528 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10529 {
10530 if (!must_finish)
10531 {
10532 do_pending_window_change (1);
10533
10534 /* We used to always goto end_of_redisplay here, but this
10535 isn't enough if we have a blinking cursor. */
10536 if (w->cursor_off_p == w->last_cursor_off_p)
10537 goto end_of_redisplay;
10538 }
10539 goto update;
10540 }
10541 /* If highlighting the region, or if the cursor is in the echo area,
10542 then we can't just move the cursor. */
10543 else if (! (!NILP (Vtransient_mark_mode)
10544 && !NILP (current_buffer->mark_active))
10545 && (EQ (selected_window, current_buffer->last_selected_window)
10546 || highlight_nonselected_windows)
10547 && NILP (w->region_showing)
10548 && NILP (Vshow_trailing_whitespace)
10549 && !cursor_in_echo_area)
10550 {
10551 struct it it;
10552 struct glyph_row *row;
10553
10554 /* Skip from tlbufpos to PT and see where it is. Note that
10555 PT may be in invisible text. If so, we will end at the
10556 next visible position. */
10557 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10558 NULL, DEFAULT_FACE_ID);
10559 it.current_x = this_line_start_x;
10560 it.current_y = this_line_y;
10561 it.vpos = this_line_vpos;
10562
10563 /* The call to move_it_to stops in front of PT, but
10564 moves over before-strings. */
10565 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10566
10567 if (it.vpos == this_line_vpos
10568 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10569 row->enabled_p))
10570 {
10571 xassert (this_line_vpos == it.vpos);
10572 xassert (this_line_y == it.current_y);
10573 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10574 #if GLYPH_DEBUG
10575 *w->desired_matrix->method = 0;
10576 debug_method_add (w, "optimization 3");
10577 #endif
10578 goto update;
10579 }
10580 else
10581 goto cancel;
10582 }
10583
10584 cancel:
10585 /* Text changed drastically or point moved off of line. */
10586 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10587 }
10588
10589 CHARPOS (this_line_start_pos) = 0;
10590 consider_all_windows_p |= buffer_shared > 1;
10591 ++clear_face_cache_count;
10592 #ifdef HAVE_WINDOW_SYSTEM
10593 ++clear_image_cache_count;
10594 #endif
10595
10596 /* Build desired matrices, and update the display. If
10597 consider_all_windows_p is non-zero, do it for all windows on all
10598 frames. Otherwise do it for selected_window, only. */
10599
10600 if (consider_all_windows_p)
10601 {
10602 Lisp_Object tail, frame;
10603 int i, n = 0, size = 50;
10604 struct frame **updated
10605 = (struct frame **) alloca (size * sizeof *updated);
10606
10607 /* Recompute # windows showing selected buffer. This will be
10608 incremented each time such a window is displayed. */
10609 buffer_shared = 0;
10610
10611 FOR_EACH_FRAME (tail, frame)
10612 {
10613 struct frame *f = XFRAME (frame);
10614
10615 if (FRAME_WINDOW_P (f) || FRAME_TERMCAP_P (f) || f == sf)
10616 {
10617 if (! EQ (frame, selected_frame))
10618 /* Select the frame, for the sake of frame-local
10619 variables. */
10620 select_frame_for_redisplay (frame);
10621
10622 /* Mark all the scroll bars to be removed; we'll redeem
10623 the ones we want when we redisplay their windows. */
10624 if (FRAME_DEVICE (f)->condemn_scroll_bars_hook)
10625 FRAME_DEVICE (f)->condemn_scroll_bars_hook (f);
10626
10627 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10628 redisplay_windows (FRAME_ROOT_WINDOW (f));
10629
10630 /* Any scroll bars which redisplay_windows should have
10631 nuked should now go away. */
10632 if (FRAME_DEVICE (f)->judge_scroll_bars_hook)
10633 FRAME_DEVICE (f)->judge_scroll_bars_hook (f);
10634
10635 /* If fonts changed, display again. */
10636 /* ??? rms: I suspect it is a mistake to jump all the way
10637 back to retry here. It should just retry this frame. */
10638 if (fonts_changed_p)
10639 goto retry;
10640
10641 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10642 {
10643 /* See if we have to hscroll. */
10644 if (!f->already_hscrolled_p)
10645 {
10646 f->already_hscrolled_p = 1;
10647 if (hscroll_windows (f->root_window))
10648 goto retry;
10649 }
10650
10651 /* Prevent various kinds of signals during display
10652 update. stdio is not robust about handling
10653 signals, which can cause an apparent I/O
10654 error. */
10655 if (interrupt_input)
10656 unrequest_sigio ();
10657 STOP_POLLING;
10658
10659 /* Update the display. */
10660 set_window_update_flags (XWINDOW (f->root_window), 1);
10661 pause |= update_frame (f, 0, 0);
10662 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10663 if (pause)
10664 break;
10665 #endif
10666
10667 if (n == size)
10668 {
10669 int nbytes = size * sizeof *updated;
10670 struct frame **p = (struct frame **) alloca (2 * nbytes);
10671 bcopy (updated, p, nbytes);
10672 size *= 2;
10673 }
10674
10675 updated[n++] = f;
10676 }
10677 }
10678 }
10679
10680 if (!pause)
10681 {
10682 /* Do the mark_window_display_accurate after all windows have
10683 been redisplayed because this call resets flags in buffers
10684 which are needed for proper redisplay. */
10685 for (i = 0; i < n; ++i)
10686 {
10687 struct frame *f = updated[i];
10688 mark_window_display_accurate (f->root_window, 1);
10689 if (FRAME_DEVICE (f)->frame_up_to_date_hook)
10690 FRAME_DEVICE (f)->frame_up_to_date_hook (f);
10691 }
10692 }
10693 }
10694 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10695 {
10696 Lisp_Object mini_window;
10697 struct frame *mini_frame;
10698
10699 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10700 /* Use list_of_error, not Qerror, so that
10701 we catch only errors and don't run the debugger. */
10702 internal_condition_case_1 (redisplay_window_1, selected_window,
10703 list_of_error,
10704 redisplay_window_error);
10705
10706 /* Compare desired and current matrices, perform output. */
10707
10708 update:
10709 /* If fonts changed, display again. */
10710 if (fonts_changed_p)
10711 goto retry;
10712
10713 /* Prevent various kinds of signals during display update.
10714 stdio is not robust about handling signals,
10715 which can cause an apparent I/O error. */
10716 if (interrupt_input)
10717 unrequest_sigio ();
10718 STOP_POLLING;
10719
10720 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10721 {
10722 if (hscroll_windows (selected_window))
10723 goto retry;
10724
10725 XWINDOW (selected_window)->must_be_updated_p = 1;
10726 pause = update_frame (sf, 0, 0);
10727 }
10728
10729 /* We may have called echo_area_display at the top of this
10730 function. If the echo area is on another frame, that may
10731 have put text on a frame other than the selected one, so the
10732 above call to update_frame would not have caught it. Catch
10733 it here. */
10734 mini_window = FRAME_MINIBUF_WINDOW (sf);
10735 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10736
10737 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10738 {
10739 XWINDOW (mini_window)->must_be_updated_p = 1;
10740 pause |= update_frame (mini_frame, 0, 0);
10741 if (!pause && hscroll_windows (mini_window))
10742 goto retry;
10743 }
10744 }
10745
10746 /* If display was paused because of pending input, make sure we do a
10747 thorough update the next time. */
10748 if (pause)
10749 {
10750 /* Prevent the optimization at the beginning of
10751 redisplay_internal that tries a single-line update of the
10752 line containing the cursor in the selected window. */
10753 CHARPOS (this_line_start_pos) = 0;
10754
10755 /* Let the overlay arrow be updated the next time. */
10756 update_overlay_arrows (0);
10757
10758 /* If we pause after scrolling, some rows in the current
10759 matrices of some windows are not valid. */
10760 if (!WINDOW_FULL_WIDTH_P (w)
10761 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10762 update_mode_lines = 1;
10763 }
10764 else
10765 {
10766 if (!consider_all_windows_p)
10767 {
10768 /* This has already been done above if
10769 consider_all_windows_p is set. */
10770 mark_window_display_accurate_1 (w, 1);
10771
10772 /* Say overlay arrows are up to date. */
10773 update_overlay_arrows (1);
10774
10775 if (FRAME_DEVICE (sf)->frame_up_to_date_hook != 0)
10776 FRAME_DEVICE (sf)->frame_up_to_date_hook (sf);
10777 }
10778
10779 update_mode_lines = 0;
10780 windows_or_buffers_changed = 0;
10781 cursor_type_changed = 0;
10782 }
10783
10784 /* Start SIGIO interrupts coming again. Having them off during the
10785 code above makes it less likely one will discard output, but not
10786 impossible, since there might be stuff in the system buffer here.
10787 But it is much hairier to try to do anything about that. */
10788 if (interrupt_input)
10789 request_sigio ();
10790 RESUME_POLLING;
10791
10792 /* If a frame has become visible which was not before, redisplay
10793 again, so that we display it. Expose events for such a frame
10794 (which it gets when becoming visible) don't call the parts of
10795 redisplay constructing glyphs, so simply exposing a frame won't
10796 display anything in this case. So, we have to display these
10797 frames here explicitly. */
10798 if (!pause)
10799 {
10800 Lisp_Object tail, frame;
10801 int new_count = 0;
10802
10803 FOR_EACH_FRAME (tail, frame)
10804 {
10805 int this_is_visible = 0;
10806
10807 if (XFRAME (frame)->visible)
10808 this_is_visible = 1;
10809 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10810 if (XFRAME (frame)->visible)
10811 this_is_visible = 1;
10812
10813 if (this_is_visible)
10814 new_count++;
10815 }
10816
10817 if (new_count != number_of_visible_frames)
10818 windows_or_buffers_changed++;
10819 }
10820
10821 /* Change frame size now if a change is pending. */
10822 do_pending_window_change (1);
10823
10824 /* If we just did a pending size change, or have additional
10825 visible frames, redisplay again. */
10826 if (windows_or_buffers_changed && !pause)
10827 goto retry;
10828
10829 /* Clear the face cache eventually. */
10830 if (consider_all_windows_p)
10831 {
10832 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10833 {
10834 clear_face_cache (0);
10835 clear_face_cache_count = 0;
10836 }
10837 #ifdef HAVE_WINDOW_SYSTEM
10838 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
10839 {
10840 Lisp_Object tail, frame;
10841 FOR_EACH_FRAME (tail, frame)
10842 {
10843 struct frame *f = XFRAME (frame);
10844 if (FRAME_WINDOW_P (f))
10845 clear_image_cache (f, 0);
10846 }
10847 clear_image_cache_count = 0;
10848 }
10849 #endif /* HAVE_WINDOW_SYSTEM */
10850 }
10851
10852 end_of_redisplay:
10853 unbind_to (count, Qnil);
10854 RESUME_POLLING;
10855 }
10856
10857
10858 /* Redisplay, but leave alone any recent echo area message unless
10859 another message has been requested in its place.
10860
10861 This is useful in situations where you need to redisplay but no
10862 user action has occurred, making it inappropriate for the message
10863 area to be cleared. See tracking_off and
10864 wait_reading_process_output for examples of these situations.
10865
10866 FROM_WHERE is an integer saying from where this function was
10867 called. This is useful for debugging. */
10868
10869 void
10870 redisplay_preserve_echo_area (from_where)
10871 int from_where;
10872 {
10873 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10874
10875 if (!NILP (echo_area_buffer[1]))
10876 {
10877 /* We have a previously displayed message, but no current
10878 message. Redisplay the previous message. */
10879 display_last_displayed_message_p = 1;
10880 redisplay_internal (1);
10881 display_last_displayed_message_p = 0;
10882 }
10883 else
10884 redisplay_internal (1);
10885
10886 if (FRAME_RIF (SELECTED_FRAME ()) != NULL
10887 && FRAME_RIF (SELECTED_FRAME ())->flush_display_optional)
10888 FRAME_RIF (SELECTED_FRAME ())->flush_display_optional (NULL);
10889 }
10890
10891
10892 /* Function registered with record_unwind_protect in
10893 redisplay_internal. Reset redisplaying_p to the value it had
10894 before redisplay_internal was called, and clear
10895 prevent_freeing_realized_faces_p. It also selects the previously
10896 selected frame, unless it has been deleted (by an X connection
10897 failure during redisplay, for example). */
10898
10899 static Lisp_Object
10900 unwind_redisplay (val)
10901 Lisp_Object val;
10902 {
10903 Lisp_Object old_redisplaying_p, old_frame;
10904
10905 old_redisplaying_p = XCAR (val);
10906 redisplaying_p = XFASTINT (old_redisplaying_p);
10907 old_frame = XCDR (val);
10908 if (! EQ (old_frame, selected_frame)
10909 && FRAME_LIVE_P (XFRAME (old_frame)))
10910 select_frame_for_redisplay (old_frame);
10911 return Qnil;
10912 }
10913
10914
10915 /* Mark the display of window W as accurate or inaccurate. If
10916 ACCURATE_P is non-zero mark display of W as accurate. If
10917 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10918 redisplay_internal is called. */
10919
10920 static void
10921 mark_window_display_accurate_1 (w, accurate_p)
10922 struct window *w;
10923 int accurate_p;
10924 {
10925 if (BUFFERP (w->buffer))
10926 {
10927 struct buffer *b = XBUFFER (w->buffer);
10928
10929 w->last_modified
10930 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10931 w->last_overlay_modified
10932 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10933 w->last_had_star
10934 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10935
10936 if (accurate_p)
10937 {
10938 b->clip_changed = 0;
10939 b->prevent_redisplay_optimizations_p = 0;
10940
10941 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10942 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10943 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10944 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10945
10946 w->current_matrix->buffer = b;
10947 w->current_matrix->begv = BUF_BEGV (b);
10948 w->current_matrix->zv = BUF_ZV (b);
10949
10950 w->last_cursor = w->cursor;
10951 w->last_cursor_off_p = w->cursor_off_p;
10952
10953 if (w == XWINDOW (selected_window))
10954 w->last_point = make_number (BUF_PT (b));
10955 else
10956 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10957 }
10958 }
10959
10960 if (accurate_p)
10961 {
10962 w->window_end_valid = w->buffer;
10963 #if 0 /* This is incorrect with variable-height lines. */
10964 xassert (XINT (w->window_end_vpos)
10965 < (WINDOW_TOTAL_LINES (w)
10966 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10967 #endif
10968 w->update_mode_line = Qnil;
10969 }
10970 }
10971
10972
10973 /* Mark the display of windows in the window tree rooted at WINDOW as
10974 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10975 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10976 be redisplayed the next time redisplay_internal is called. */
10977
10978 void
10979 mark_window_display_accurate (window, accurate_p)
10980 Lisp_Object window;
10981 int accurate_p;
10982 {
10983 struct window *w;
10984
10985 for (; !NILP (window); window = w->next)
10986 {
10987 w = XWINDOW (window);
10988 mark_window_display_accurate_1 (w, accurate_p);
10989
10990 if (!NILP (w->vchild))
10991 mark_window_display_accurate (w->vchild, accurate_p);
10992 if (!NILP (w->hchild))
10993 mark_window_display_accurate (w->hchild, accurate_p);
10994 }
10995
10996 if (accurate_p)
10997 {
10998 update_overlay_arrows (1);
10999 }
11000 else
11001 {
11002 /* Force a thorough redisplay the next time by setting
11003 last_arrow_position and last_arrow_string to t, which is
11004 unequal to any useful value of Voverlay_arrow_... */
11005 update_overlay_arrows (-1);
11006 }
11007 }
11008
11009
11010 /* Return value in display table DP (Lisp_Char_Table *) for character
11011 C. Since a display table doesn't have any parent, we don't have to
11012 follow parent. Do not call this function directly but use the
11013 macro DISP_CHAR_VECTOR. */
11014
11015 Lisp_Object
11016 disp_char_vector (dp, c)
11017 struct Lisp_Char_Table *dp;
11018 int c;
11019 {
11020 int code[4], i;
11021 Lisp_Object val;
11022
11023 if (SINGLE_BYTE_CHAR_P (c))
11024 return (dp->contents[c]);
11025
11026 SPLIT_CHAR (c, code[0], code[1], code[2]);
11027 if (code[1] < 32)
11028 code[1] = -1;
11029 else if (code[2] < 32)
11030 code[2] = -1;
11031
11032 /* Here, the possible range of code[0] (== charset ID) is
11033 128..max_charset. Since the top level char table contains data
11034 for multibyte characters after 256th element, we must increment
11035 code[0] by 128 to get a correct index. */
11036 code[0] += 128;
11037 code[3] = -1; /* anchor */
11038
11039 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
11040 {
11041 val = dp->contents[code[i]];
11042 if (!SUB_CHAR_TABLE_P (val))
11043 return (NILP (val) ? dp->defalt : val);
11044 }
11045
11046 /* Here, val is a sub char table. We return the default value of
11047 it. */
11048 return (dp->defalt);
11049 }
11050
11051
11052 \f
11053 /***********************************************************************
11054 Window Redisplay
11055 ***********************************************************************/
11056
11057 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11058
11059 static void
11060 redisplay_windows (window)
11061 Lisp_Object window;
11062 {
11063 while (!NILP (window))
11064 {
11065 struct window *w = XWINDOW (window);
11066
11067 if (!NILP (w->hchild))
11068 redisplay_windows (w->hchild);
11069 else if (!NILP (w->vchild))
11070 redisplay_windows (w->vchild);
11071 else
11072 {
11073 displayed_buffer = XBUFFER (w->buffer);
11074 /* Use list_of_error, not Qerror, so that
11075 we catch only errors and don't run the debugger. */
11076 internal_condition_case_1 (redisplay_window_0, window,
11077 list_of_error,
11078 redisplay_window_error);
11079 }
11080
11081 window = w->next;
11082 }
11083 }
11084
11085 static Lisp_Object
11086 redisplay_window_error ()
11087 {
11088 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
11089 return Qnil;
11090 }
11091
11092 static Lisp_Object
11093 redisplay_window_0 (window)
11094 Lisp_Object window;
11095 {
11096 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11097 redisplay_window (window, 0);
11098 return Qnil;
11099 }
11100
11101 static Lisp_Object
11102 redisplay_window_1 (window)
11103 Lisp_Object window;
11104 {
11105 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11106 redisplay_window (window, 1);
11107 return Qnil;
11108 }
11109 \f
11110
11111 /* Increment GLYPH until it reaches END or CONDITION fails while
11112 adding (GLYPH)->pixel_width to X. */
11113
11114 #define SKIP_GLYPHS(glyph, end, x, condition) \
11115 do \
11116 { \
11117 (x) += (glyph)->pixel_width; \
11118 ++(glyph); \
11119 } \
11120 while ((glyph) < (end) && (condition))
11121
11122
11123 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11124 DELTA is the number of bytes by which positions recorded in ROW
11125 differ from current buffer positions. */
11126
11127 void
11128 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
11129 struct window *w;
11130 struct glyph_row *row;
11131 struct glyph_matrix *matrix;
11132 int delta, delta_bytes, dy, dvpos;
11133 {
11134 struct glyph *glyph = row->glyphs[TEXT_AREA];
11135 struct glyph *end = glyph + row->used[TEXT_AREA];
11136 struct glyph *cursor = NULL;
11137 /* The first glyph that starts a sequence of glyphs from string. */
11138 struct glyph *string_start;
11139 /* The X coordinate of string_start. */
11140 int string_start_x;
11141 /* The last known character position. */
11142 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
11143 /* The last known character position before string_start. */
11144 int string_before_pos;
11145 int x = row->x;
11146 int cursor_x = x;
11147 int cursor_from_overlay_pos = 0;
11148 int pt_old = PT - delta;
11149
11150 /* Skip over glyphs not having an object at the start of the row.
11151 These are special glyphs like truncation marks on terminal
11152 frames. */
11153 if (row->displays_text_p)
11154 while (glyph < end
11155 && INTEGERP (glyph->object)
11156 && glyph->charpos < 0)
11157 {
11158 x += glyph->pixel_width;
11159 ++glyph;
11160 }
11161
11162 string_start = NULL;
11163 while (glyph < end
11164 && !INTEGERP (glyph->object)
11165 && (!BUFFERP (glyph->object)
11166 || (last_pos = glyph->charpos) < pt_old))
11167 {
11168 if (! STRINGP (glyph->object))
11169 {
11170 string_start = NULL;
11171 x += glyph->pixel_width;
11172 ++glyph;
11173 if (cursor_from_overlay_pos
11174 && last_pos > cursor_from_overlay_pos)
11175 {
11176 cursor_from_overlay_pos = 0;
11177 cursor = 0;
11178 }
11179 }
11180 else
11181 {
11182 string_before_pos = last_pos;
11183 string_start = glyph;
11184 string_start_x = x;
11185 /* Skip all glyphs from string. */
11186 do
11187 {
11188 int pos;
11189 if ((cursor == NULL || glyph > cursor)
11190 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
11191 Qcursor, (glyph)->object))
11192 && (pos = string_buffer_position (w, glyph->object,
11193 string_before_pos),
11194 (pos == 0 /* From overlay */
11195 || pos == pt_old)))
11196 {
11197 /* Estimate overlay buffer position from the buffer
11198 positions of the glyphs before and after the overlay.
11199 Add 1 to last_pos so that if point corresponds to the
11200 glyph right after the overlay, we still use a 'cursor'
11201 property found in that overlay. */
11202 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
11203 cursor = glyph;
11204 cursor_x = x;
11205 }
11206 x += glyph->pixel_width;
11207 ++glyph;
11208 }
11209 while (glyph < end && STRINGP (glyph->object));
11210 }
11211 }
11212
11213 if (cursor != NULL)
11214 {
11215 glyph = cursor;
11216 x = cursor_x;
11217 }
11218 else if (row->ends_in_ellipsis_p && glyph == end)
11219 {
11220 /* Scan back over the ellipsis glyphs, decrementing positions. */
11221 while (glyph > row->glyphs[TEXT_AREA]
11222 && (glyph - 1)->charpos == last_pos)
11223 glyph--, x -= glyph->pixel_width;
11224 /* That loop always goes one position too far,
11225 including the glyph before the ellipsis.
11226 So scan forward over that one. */
11227 x += glyph->pixel_width;
11228 glyph++;
11229 }
11230 else if (string_start
11231 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11232 {
11233 /* We may have skipped over point because the previous glyphs
11234 are from string. As there's no easy way to know the
11235 character position of the current glyph, find the correct
11236 glyph on point by scanning from string_start again. */
11237 Lisp_Object limit;
11238 Lisp_Object string;
11239 int pos;
11240
11241 limit = make_number (pt_old + 1);
11242 end = glyph;
11243 glyph = string_start;
11244 x = string_start_x;
11245 string = glyph->object;
11246 pos = string_buffer_position (w, string, string_before_pos);
11247 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11248 because we always put cursor after overlay strings. */
11249 while (pos == 0 && glyph < end)
11250 {
11251 string = glyph->object;
11252 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11253 if (glyph < end)
11254 pos = string_buffer_position (w, glyph->object, string_before_pos);
11255 }
11256
11257 while (glyph < end)
11258 {
11259 pos = XINT (Fnext_single_char_property_change
11260 (make_number (pos), Qdisplay, Qnil, limit));
11261 if (pos > pt_old)
11262 break;
11263 /* Skip glyphs from the same string. */
11264 string = glyph->object;
11265 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11266 /* Skip glyphs from an overlay. */
11267 while (glyph < end
11268 && ! string_buffer_position (w, glyph->object, pos))
11269 {
11270 string = glyph->object;
11271 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11272 }
11273 }
11274 }
11275
11276 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
11277 w->cursor.x = x;
11278 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
11279 w->cursor.y = row->y + dy;
11280
11281 if (w == XWINDOW (selected_window))
11282 {
11283 if (!row->continued_p
11284 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
11285 && row->x == 0)
11286 {
11287 this_line_buffer = XBUFFER (w->buffer);
11288
11289 CHARPOS (this_line_start_pos)
11290 = MATRIX_ROW_START_CHARPOS (row) + delta;
11291 BYTEPOS (this_line_start_pos)
11292 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
11293
11294 CHARPOS (this_line_end_pos)
11295 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
11296 BYTEPOS (this_line_end_pos)
11297 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
11298
11299 this_line_y = w->cursor.y;
11300 this_line_pixel_height = row->height;
11301 this_line_vpos = w->cursor.vpos;
11302 this_line_start_x = row->x;
11303 }
11304 else
11305 CHARPOS (this_line_start_pos) = 0;
11306 }
11307 }
11308
11309
11310 /* Run window scroll functions, if any, for WINDOW with new window
11311 start STARTP. Sets the window start of WINDOW to that position.
11312
11313 We assume that the window's buffer is really current. */
11314
11315 static INLINE struct text_pos
11316 run_window_scroll_functions (window, startp)
11317 Lisp_Object window;
11318 struct text_pos startp;
11319 {
11320 struct window *w = XWINDOW (window);
11321 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11322
11323 if (current_buffer != XBUFFER (w->buffer))
11324 abort ();
11325
11326 if (!NILP (Vwindow_scroll_functions))
11327 {
11328 run_hook_with_args_2 (Qwindow_scroll_functions, window,
11329 make_number (CHARPOS (startp)));
11330 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11331 /* In case the hook functions switch buffers. */
11332 if (current_buffer != XBUFFER (w->buffer))
11333 set_buffer_internal_1 (XBUFFER (w->buffer));
11334 }
11335
11336 return startp;
11337 }
11338
11339
11340 /* Make sure the line containing the cursor is fully visible.
11341 A value of 1 means there is nothing to be done.
11342 (Either the line is fully visible, or it cannot be made so,
11343 or we cannot tell.)
11344
11345 If FORCE_P is non-zero, return 0 even if partial visible cursor row
11346 is higher than window.
11347
11348 A value of 0 means the caller should do scrolling
11349 as if point had gone off the screen. */
11350
11351 static int
11352 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11353 struct window *w;
11354 int force_p;
11355 {
11356 struct glyph_matrix *matrix;
11357 struct glyph_row *row;
11358 int window_height;
11359
11360 if (!make_cursor_line_fully_visible_p)
11361 return 1;
11362
11363 /* It's not always possible to find the cursor, e.g, when a window
11364 is full of overlay strings. Don't do anything in that case. */
11365 if (w->cursor.vpos < 0)
11366 return 1;
11367
11368 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11369 row = MATRIX_ROW (matrix, w->cursor.vpos);
11370
11371 /* If the cursor row is not partially visible, there's nothing to do. */
11372 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
11373 return 1;
11374
11375 /* If the row the cursor is in is taller than the window's height,
11376 it's not clear what to do, so do nothing. */
11377 window_height = window_box_height (w);
11378 if (row->height >= window_height)
11379 {
11380 if (!force_p || MINI_WINDOW_P (w) || w->vscroll)
11381 return 1;
11382 }
11383 return 0;
11384
11385 #if 0
11386 /* This code used to try to scroll the window just enough to make
11387 the line visible. It returned 0 to say that the caller should
11388 allocate larger glyph matrices. */
11389
11390 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11391 {
11392 int dy = row->height - row->visible_height;
11393 w->vscroll = 0;
11394 w->cursor.y += dy;
11395 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11396 }
11397 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11398 {
11399 int dy = - (row->height - row->visible_height);
11400 w->vscroll = dy;
11401 w->cursor.y += dy;
11402 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11403 }
11404
11405 /* When we change the cursor y-position of the selected window,
11406 change this_line_y as well so that the display optimization for
11407 the cursor line of the selected window in redisplay_internal uses
11408 the correct y-position. */
11409 if (w == XWINDOW (selected_window))
11410 this_line_y = w->cursor.y;
11411
11412 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11413 redisplay with larger matrices. */
11414 if (matrix->nrows < required_matrix_height (w))
11415 {
11416 fonts_changed_p = 1;
11417 return 0;
11418 }
11419
11420 return 1;
11421 #endif /* 0 */
11422 }
11423
11424
11425 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11426 non-zero means only WINDOW is redisplayed in redisplay_internal.
11427 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11428 in redisplay_window to bring a partially visible line into view in
11429 the case that only the cursor has moved.
11430
11431 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11432 last screen line's vertical height extends past the end of the screen.
11433
11434 Value is
11435
11436 1 if scrolling succeeded
11437
11438 0 if scrolling didn't find point.
11439
11440 -1 if new fonts have been loaded so that we must interrupt
11441 redisplay, adjust glyph matrices, and try again. */
11442
11443 enum
11444 {
11445 SCROLLING_SUCCESS,
11446 SCROLLING_FAILED,
11447 SCROLLING_NEED_LARGER_MATRICES
11448 };
11449
11450 static int
11451 try_scrolling (window, just_this_one_p, scroll_conservatively,
11452 scroll_step, temp_scroll_step, last_line_misfit)
11453 Lisp_Object window;
11454 int just_this_one_p;
11455 EMACS_INT scroll_conservatively, scroll_step;
11456 int temp_scroll_step;
11457 int last_line_misfit;
11458 {
11459 struct window *w = XWINDOW (window);
11460 struct frame *f = XFRAME (w->frame);
11461 struct text_pos scroll_margin_pos;
11462 struct text_pos pos;
11463 struct text_pos startp;
11464 struct it it;
11465 Lisp_Object window_end;
11466 int this_scroll_margin;
11467 int dy = 0;
11468 int scroll_max;
11469 int rc;
11470 int amount_to_scroll = 0;
11471 Lisp_Object aggressive;
11472 int height;
11473 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11474
11475 #if GLYPH_DEBUG
11476 debug_method_add (w, "try_scrolling");
11477 #endif
11478
11479 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11480
11481 /* Compute scroll margin height in pixels. We scroll when point is
11482 within this distance from the top or bottom of the window. */
11483 if (scroll_margin > 0)
11484 {
11485 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11486 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11487 }
11488 else
11489 this_scroll_margin = 0;
11490
11491 /* Force scroll_conservatively to have a reasonable value so it doesn't
11492 cause an overflow while computing how much to scroll. */
11493 if (scroll_conservatively)
11494 scroll_conservatively = min (scroll_conservatively,
11495 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11496
11497 /* Compute how much we should try to scroll maximally to bring point
11498 into view. */
11499 if (scroll_step || scroll_conservatively || temp_scroll_step)
11500 scroll_max = max (scroll_step,
11501 max (scroll_conservatively, temp_scroll_step));
11502 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11503 || NUMBERP (current_buffer->scroll_up_aggressively))
11504 /* We're trying to scroll because of aggressive scrolling
11505 but no scroll_step is set. Choose an arbitrary one. Maybe
11506 there should be a variable for this. */
11507 scroll_max = 10;
11508 else
11509 scroll_max = 0;
11510 scroll_max *= FRAME_LINE_HEIGHT (f);
11511
11512 /* Decide whether we have to scroll down. Start at the window end
11513 and move this_scroll_margin up to find the position of the scroll
11514 margin. */
11515 window_end = Fwindow_end (window, Qt);
11516
11517 too_near_end:
11518
11519 CHARPOS (scroll_margin_pos) = XINT (window_end);
11520 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11521
11522 if (this_scroll_margin || extra_scroll_margin_lines)
11523 {
11524 start_display (&it, w, scroll_margin_pos);
11525 if (this_scroll_margin)
11526 move_it_vertically_backward (&it, this_scroll_margin);
11527 if (extra_scroll_margin_lines)
11528 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11529 scroll_margin_pos = it.current.pos;
11530 }
11531
11532 if (PT >= CHARPOS (scroll_margin_pos))
11533 {
11534 int y0;
11535
11536 /* Point is in the scroll margin at the bottom of the window, or
11537 below. Compute a new window start that makes point visible. */
11538
11539 /* Compute the distance from the scroll margin to PT.
11540 Give up if the distance is greater than scroll_max. */
11541 start_display (&it, w, scroll_margin_pos);
11542 y0 = it.current_y;
11543 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11544 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11545
11546 /* To make point visible, we have to move the window start
11547 down so that the line the cursor is in is visible, which
11548 means we have to add in the height of the cursor line. */
11549 dy = line_bottom_y (&it) - y0;
11550
11551 if (dy > scroll_max)
11552 return SCROLLING_FAILED;
11553
11554 /* Move the window start down. If scrolling conservatively,
11555 move it just enough down to make point visible. If
11556 scroll_step is set, move it down by scroll_step. */
11557 start_display (&it, w, startp);
11558
11559 if (scroll_conservatively)
11560 /* Set AMOUNT_TO_SCROLL to at least one line,
11561 and at most scroll_conservatively lines. */
11562 amount_to_scroll
11563 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11564 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11565 else if (scroll_step || temp_scroll_step)
11566 amount_to_scroll = scroll_max;
11567 else
11568 {
11569 aggressive = current_buffer->scroll_up_aggressively;
11570 height = WINDOW_BOX_TEXT_HEIGHT (w);
11571 if (NUMBERP (aggressive))
11572 {
11573 double float_amount = XFLOATINT (aggressive) * height;
11574 amount_to_scroll = float_amount;
11575 if (amount_to_scroll == 0 && float_amount > 0)
11576 amount_to_scroll = 1;
11577 }
11578 }
11579
11580 if (amount_to_scroll <= 0)
11581 return SCROLLING_FAILED;
11582
11583 /* If moving by amount_to_scroll leaves STARTP unchanged,
11584 move it down one screen line. */
11585
11586 move_it_vertically (&it, amount_to_scroll);
11587 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11588 move_it_by_lines (&it, 1, 1);
11589 startp = it.current.pos;
11590 }
11591 else
11592 {
11593 /* See if point is inside the scroll margin at the top of the
11594 window. */
11595 scroll_margin_pos = startp;
11596 if (this_scroll_margin)
11597 {
11598 start_display (&it, w, startp);
11599 move_it_vertically (&it, this_scroll_margin);
11600 scroll_margin_pos = it.current.pos;
11601 }
11602
11603 if (PT < CHARPOS (scroll_margin_pos))
11604 {
11605 /* Point is in the scroll margin at the top of the window or
11606 above what is displayed in the window. */
11607 int y0;
11608
11609 /* Compute the vertical distance from PT to the scroll
11610 margin position. Give up if distance is greater than
11611 scroll_max. */
11612 SET_TEXT_POS (pos, PT, PT_BYTE);
11613 start_display (&it, w, pos);
11614 y0 = it.current_y;
11615 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11616 it.last_visible_y, -1,
11617 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11618 dy = it.current_y - y0;
11619 if (dy > scroll_max)
11620 return SCROLLING_FAILED;
11621
11622 /* Compute new window start. */
11623 start_display (&it, w, startp);
11624
11625 if (scroll_conservatively)
11626 amount_to_scroll
11627 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11628 else if (scroll_step || temp_scroll_step)
11629 amount_to_scroll = scroll_max;
11630 else
11631 {
11632 aggressive = current_buffer->scroll_down_aggressively;
11633 height = WINDOW_BOX_TEXT_HEIGHT (w);
11634 if (NUMBERP (aggressive))
11635 {
11636 double float_amount = XFLOATINT (aggressive) * height;
11637 amount_to_scroll = float_amount;
11638 if (amount_to_scroll == 0 && float_amount > 0)
11639 amount_to_scroll = 1;
11640 }
11641 }
11642
11643 if (amount_to_scroll <= 0)
11644 return SCROLLING_FAILED;
11645
11646 move_it_vertically_backward (&it, amount_to_scroll);
11647 startp = it.current.pos;
11648 }
11649 }
11650
11651 /* Run window scroll functions. */
11652 startp = run_window_scroll_functions (window, startp);
11653
11654 /* Display the window. Give up if new fonts are loaded, or if point
11655 doesn't appear. */
11656 if (!try_window (window, startp, 0))
11657 rc = SCROLLING_NEED_LARGER_MATRICES;
11658 else if (w->cursor.vpos < 0)
11659 {
11660 clear_glyph_matrix (w->desired_matrix);
11661 rc = SCROLLING_FAILED;
11662 }
11663 else
11664 {
11665 /* Maybe forget recorded base line for line number display. */
11666 if (!just_this_one_p
11667 || current_buffer->clip_changed
11668 || BEG_UNCHANGED < CHARPOS (startp))
11669 w->base_line_number = Qnil;
11670
11671 /* If cursor ends up on a partially visible line,
11672 treat that as being off the bottom of the screen. */
11673 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
11674 {
11675 clear_glyph_matrix (w->desired_matrix);
11676 ++extra_scroll_margin_lines;
11677 goto too_near_end;
11678 }
11679 rc = SCROLLING_SUCCESS;
11680 }
11681
11682 return rc;
11683 }
11684
11685
11686 /* Compute a suitable window start for window W if display of W starts
11687 on a continuation line. Value is non-zero if a new window start
11688 was computed.
11689
11690 The new window start will be computed, based on W's width, starting
11691 from the start of the continued line. It is the start of the
11692 screen line with the minimum distance from the old start W->start. */
11693
11694 static int
11695 compute_window_start_on_continuation_line (w)
11696 struct window *w;
11697 {
11698 struct text_pos pos, start_pos;
11699 int window_start_changed_p = 0;
11700
11701 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11702
11703 /* If window start is on a continuation line... Window start may be
11704 < BEGV in case there's invisible text at the start of the
11705 buffer (M-x rmail, for example). */
11706 if (CHARPOS (start_pos) > BEGV
11707 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11708 {
11709 struct it it;
11710 struct glyph_row *row;
11711
11712 /* Handle the case that the window start is out of range. */
11713 if (CHARPOS (start_pos) < BEGV)
11714 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11715 else if (CHARPOS (start_pos) > ZV)
11716 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11717
11718 /* Find the start of the continued line. This should be fast
11719 because scan_buffer is fast (newline cache). */
11720 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11721 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11722 row, DEFAULT_FACE_ID);
11723 reseat_at_previous_visible_line_start (&it);
11724
11725 /* If the line start is "too far" away from the window start,
11726 say it takes too much time to compute a new window start. */
11727 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11728 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11729 {
11730 int min_distance, distance;
11731
11732 /* Move forward by display lines to find the new window
11733 start. If window width was enlarged, the new start can
11734 be expected to be > the old start. If window width was
11735 decreased, the new window start will be < the old start.
11736 So, we're looking for the display line start with the
11737 minimum distance from the old window start. */
11738 pos = it.current.pos;
11739 min_distance = INFINITY;
11740 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11741 distance < min_distance)
11742 {
11743 min_distance = distance;
11744 pos = it.current.pos;
11745 move_it_by_lines (&it, 1, 0);
11746 }
11747
11748 /* Set the window start there. */
11749 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11750 window_start_changed_p = 1;
11751 }
11752 }
11753
11754 return window_start_changed_p;
11755 }
11756
11757
11758 /* Try cursor movement in case text has not changed in window WINDOW,
11759 with window start STARTP. Value is
11760
11761 CURSOR_MOVEMENT_SUCCESS if successful
11762
11763 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11764
11765 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11766 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11767 we want to scroll as if scroll-step were set to 1. See the code.
11768
11769 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11770 which case we have to abort this redisplay, and adjust matrices
11771 first. */
11772
11773 enum
11774 {
11775 CURSOR_MOVEMENT_SUCCESS,
11776 CURSOR_MOVEMENT_CANNOT_BE_USED,
11777 CURSOR_MOVEMENT_MUST_SCROLL,
11778 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11779 };
11780
11781 static int
11782 try_cursor_movement (window, startp, scroll_step)
11783 Lisp_Object window;
11784 struct text_pos startp;
11785 int *scroll_step;
11786 {
11787 struct window *w = XWINDOW (window);
11788 struct frame *f = XFRAME (w->frame);
11789 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11790
11791 #if GLYPH_DEBUG
11792 if (inhibit_try_cursor_movement)
11793 return rc;
11794 #endif
11795
11796 /* Handle case where text has not changed, only point, and it has
11797 not moved off the frame. */
11798 if (/* Point may be in this window. */
11799 PT >= CHARPOS (startp)
11800 /* Selective display hasn't changed. */
11801 && !current_buffer->clip_changed
11802 /* Function force-mode-line-update is used to force a thorough
11803 redisplay. It sets either windows_or_buffers_changed or
11804 update_mode_lines. So don't take a shortcut here for these
11805 cases. */
11806 && !update_mode_lines
11807 && !windows_or_buffers_changed
11808 && !cursor_type_changed
11809 /* Can't use this case if highlighting a region. When a
11810 region exists, cursor movement has to do more than just
11811 set the cursor. */
11812 && !(!NILP (Vtransient_mark_mode)
11813 && !NILP (current_buffer->mark_active))
11814 && NILP (w->region_showing)
11815 && NILP (Vshow_trailing_whitespace)
11816 /* Right after splitting windows, last_point may be nil. */
11817 && INTEGERP (w->last_point)
11818 /* This code is not used for mini-buffer for the sake of the case
11819 of redisplaying to replace an echo area message; since in
11820 that case the mini-buffer contents per se are usually
11821 unchanged. This code is of no real use in the mini-buffer
11822 since the handling of this_line_start_pos, etc., in redisplay
11823 handles the same cases. */
11824 && !EQ (window, minibuf_window)
11825 /* When splitting windows or for new windows, it happens that
11826 redisplay is called with a nil window_end_vpos or one being
11827 larger than the window. This should really be fixed in
11828 window.c. I don't have this on my list, now, so we do
11829 approximately the same as the old redisplay code. --gerd. */
11830 && INTEGERP (w->window_end_vpos)
11831 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11832 && (FRAME_WINDOW_P (f)
11833 || !overlay_arrow_in_current_buffer_p ()))
11834 {
11835 int this_scroll_margin, top_scroll_margin;
11836 struct glyph_row *row = NULL;
11837
11838 #if GLYPH_DEBUG
11839 debug_method_add (w, "cursor movement");
11840 #endif
11841
11842 /* Scroll if point within this distance from the top or bottom
11843 of the window. This is a pixel value. */
11844 this_scroll_margin = max (0, scroll_margin);
11845 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11846 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11847
11848 top_scroll_margin = this_scroll_margin;
11849 if (WINDOW_WANTS_HEADER_LINE_P (w))
11850 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11851
11852 /* Start with the row the cursor was displayed during the last
11853 not paused redisplay. Give up if that row is not valid. */
11854 if (w->last_cursor.vpos < 0
11855 || w->last_cursor.vpos >= w->current_matrix->nrows)
11856 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11857 else
11858 {
11859 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11860 if (row->mode_line_p)
11861 ++row;
11862 if (!row->enabled_p)
11863 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11864 }
11865
11866 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11867 {
11868 int scroll_p = 0;
11869 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11870
11871 if (PT > XFASTINT (w->last_point))
11872 {
11873 /* Point has moved forward. */
11874 while (MATRIX_ROW_END_CHARPOS (row) < PT
11875 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11876 {
11877 xassert (row->enabled_p);
11878 ++row;
11879 }
11880
11881 /* The end position of a row equals the start position
11882 of the next row. If PT is there, we would rather
11883 display it in the next line. */
11884 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11885 && MATRIX_ROW_END_CHARPOS (row) == PT
11886 && !cursor_row_p (w, row))
11887 ++row;
11888
11889 /* If within the scroll margin, scroll. Note that
11890 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11891 the next line would be drawn, and that
11892 this_scroll_margin can be zero. */
11893 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11894 || PT > MATRIX_ROW_END_CHARPOS (row)
11895 /* Line is completely visible last line in window
11896 and PT is to be set in the next line. */
11897 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11898 && PT == MATRIX_ROW_END_CHARPOS (row)
11899 && !row->ends_at_zv_p
11900 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11901 scroll_p = 1;
11902 }
11903 else if (PT < XFASTINT (w->last_point))
11904 {
11905 /* Cursor has to be moved backward. Note that PT >=
11906 CHARPOS (startp) because of the outer if-statement. */
11907 while (!row->mode_line_p
11908 && (MATRIX_ROW_START_CHARPOS (row) > PT
11909 || (MATRIX_ROW_START_CHARPOS (row) == PT
11910 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
11911 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
11912 row > w->current_matrix->rows
11913 && (row-1)->ends_in_newline_from_string_p))))
11914 && (row->y > top_scroll_margin
11915 || CHARPOS (startp) == BEGV))
11916 {
11917 xassert (row->enabled_p);
11918 --row;
11919 }
11920
11921 /* Consider the following case: Window starts at BEGV,
11922 there is invisible, intangible text at BEGV, so that
11923 display starts at some point START > BEGV. It can
11924 happen that we are called with PT somewhere between
11925 BEGV and START. Try to handle that case. */
11926 if (row < w->current_matrix->rows
11927 || row->mode_line_p)
11928 {
11929 row = w->current_matrix->rows;
11930 if (row->mode_line_p)
11931 ++row;
11932 }
11933
11934 /* Due to newlines in overlay strings, we may have to
11935 skip forward over overlay strings. */
11936 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11937 && MATRIX_ROW_END_CHARPOS (row) == PT
11938 && !cursor_row_p (w, row))
11939 ++row;
11940
11941 /* If within the scroll margin, scroll. */
11942 if (row->y < top_scroll_margin
11943 && CHARPOS (startp) != BEGV)
11944 scroll_p = 1;
11945 }
11946 else
11947 {
11948 /* Cursor did not move. So don't scroll even if cursor line
11949 is partially visible, as it was so before. */
11950 rc = CURSOR_MOVEMENT_SUCCESS;
11951 }
11952
11953 if (PT < MATRIX_ROW_START_CHARPOS (row)
11954 || PT > MATRIX_ROW_END_CHARPOS (row))
11955 {
11956 /* if PT is not in the glyph row, give up. */
11957 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11958 }
11959 else if (rc != CURSOR_MOVEMENT_SUCCESS
11960 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11961 && make_cursor_line_fully_visible_p)
11962 {
11963 if (PT == MATRIX_ROW_END_CHARPOS (row)
11964 && !row->ends_at_zv_p
11965 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11966 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11967 else if (row->height > window_box_height (w))
11968 {
11969 /* If we end up in a partially visible line, let's
11970 make it fully visible, except when it's taller
11971 than the window, in which case we can't do much
11972 about it. */
11973 *scroll_step = 1;
11974 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11975 }
11976 else
11977 {
11978 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11979 if (!cursor_row_fully_visible_p (w, 0, 1))
11980 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11981 else
11982 rc = CURSOR_MOVEMENT_SUCCESS;
11983 }
11984 }
11985 else if (scroll_p)
11986 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11987 else
11988 {
11989 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11990 rc = CURSOR_MOVEMENT_SUCCESS;
11991 }
11992 }
11993 }
11994
11995 return rc;
11996 }
11997
11998 void
11999 set_vertical_scroll_bar (w)
12000 struct window *w;
12001 {
12002 int start, end, whole;
12003
12004 /* Calculate the start and end positions for the current window.
12005 At some point, it would be nice to choose between scrollbars
12006 which reflect the whole buffer size, with special markers
12007 indicating narrowing, and scrollbars which reflect only the
12008 visible region.
12009
12010 Note that mini-buffers sometimes aren't displaying any text. */
12011 if (!MINI_WINDOW_P (w)
12012 || (w == XWINDOW (minibuf_window)
12013 && NILP (echo_area_buffer[0])))
12014 {
12015 struct buffer *buf = XBUFFER (w->buffer);
12016 whole = BUF_ZV (buf) - BUF_BEGV (buf);
12017 start = marker_position (w->start) - BUF_BEGV (buf);
12018 /* I don't think this is guaranteed to be right. For the
12019 moment, we'll pretend it is. */
12020 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
12021
12022 if (end < start)
12023 end = start;
12024 if (whole < (end - start))
12025 whole = end - start;
12026 }
12027 else
12028 start = end = whole = 0;
12029
12030 /* Indicate what this scroll bar ought to be displaying now. */
12031 if (FRAME_DEVICE (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12032 (*FRAME_DEVICE (XFRAME (w->frame))->set_vertical_scroll_bar_hook)
12033 (w, end - start, whole, start);
12034 }
12035
12036
12037 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
12038 selected_window is redisplayed.
12039
12040 We can return without actually redisplaying the window if
12041 fonts_changed_p is nonzero. In that case, redisplay_internal will
12042 retry. */
12043
12044 static void
12045 redisplay_window (window, just_this_one_p)
12046 Lisp_Object window;
12047 int just_this_one_p;
12048 {
12049 struct window *w = XWINDOW (window);
12050 struct frame *f = XFRAME (w->frame);
12051 struct buffer *buffer = XBUFFER (w->buffer);
12052 struct buffer *old = current_buffer;
12053 struct text_pos lpoint, opoint, startp;
12054 int update_mode_line;
12055 int tem;
12056 struct it it;
12057 /* Record it now because it's overwritten. */
12058 int current_matrix_up_to_date_p = 0;
12059 int used_current_matrix_p = 0;
12060 /* This is less strict than current_matrix_up_to_date_p.
12061 It indictes that the buffer contents and narrowing are unchanged. */
12062 int buffer_unchanged_p = 0;
12063 int temp_scroll_step = 0;
12064 int count = SPECPDL_INDEX ();
12065 int rc;
12066 int centering_position = -1;
12067 int last_line_misfit = 0;
12068
12069 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12070 opoint = lpoint;
12071
12072 /* W must be a leaf window here. */
12073 xassert (!NILP (w->buffer));
12074 #if GLYPH_DEBUG
12075 *w->desired_matrix->method = 0;
12076 #endif
12077
12078 specbind (Qinhibit_point_motion_hooks, Qt);
12079
12080 reconsider_clip_changes (w, buffer);
12081
12082 /* Has the mode line to be updated? */
12083 update_mode_line = (!NILP (w->update_mode_line)
12084 || update_mode_lines
12085 || buffer->clip_changed
12086 || buffer->prevent_redisplay_optimizations_p);
12087
12088 if (MINI_WINDOW_P (w))
12089 {
12090 if (w == XWINDOW (echo_area_window)
12091 && !NILP (echo_area_buffer[0]))
12092 {
12093 if (update_mode_line)
12094 /* We may have to update a tty frame's menu bar or a
12095 tool-bar. Example `M-x C-h C-h C-g'. */
12096 goto finish_menu_bars;
12097 else
12098 /* We've already displayed the echo area glyphs in this window. */
12099 goto finish_scroll_bars;
12100 }
12101 else if ((w != XWINDOW (minibuf_window)
12102 || minibuf_level == 0)
12103 /* When buffer is nonempty, redisplay window normally. */
12104 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
12105 /* Quail displays non-mini buffers in minibuffer window.
12106 In that case, redisplay the window normally. */
12107 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
12108 {
12109 /* W is a mini-buffer window, but it's not active, so clear
12110 it. */
12111 int yb = window_text_bottom_y (w);
12112 struct glyph_row *row;
12113 int y;
12114
12115 for (y = 0, row = w->desired_matrix->rows;
12116 y < yb;
12117 y += row->height, ++row)
12118 blank_row (w, row, y);
12119 goto finish_scroll_bars;
12120 }
12121
12122 clear_glyph_matrix (w->desired_matrix);
12123 }
12124
12125 /* Otherwise set up data on this window; select its buffer and point
12126 value. */
12127 /* Really select the buffer, for the sake of buffer-local
12128 variables. */
12129 set_buffer_internal_1 (XBUFFER (w->buffer));
12130 SET_TEXT_POS (opoint, PT, PT_BYTE);
12131
12132 current_matrix_up_to_date_p
12133 = (!NILP (w->window_end_valid)
12134 && !current_buffer->clip_changed
12135 && !current_buffer->prevent_redisplay_optimizations_p
12136 && XFASTINT (w->last_modified) >= MODIFF
12137 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12138
12139 buffer_unchanged_p
12140 = (!NILP (w->window_end_valid)
12141 && !current_buffer->clip_changed
12142 && XFASTINT (w->last_modified) >= MODIFF
12143 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12144
12145 /* When windows_or_buffers_changed is non-zero, we can't rely on
12146 the window end being valid, so set it to nil there. */
12147 if (windows_or_buffers_changed)
12148 {
12149 /* If window starts on a continuation line, maybe adjust the
12150 window start in case the window's width changed. */
12151 if (XMARKER (w->start)->buffer == current_buffer)
12152 compute_window_start_on_continuation_line (w);
12153
12154 w->window_end_valid = Qnil;
12155 }
12156
12157 /* Some sanity checks. */
12158 CHECK_WINDOW_END (w);
12159 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12160 abort ();
12161 if (BYTEPOS (opoint) < CHARPOS (opoint))
12162 abort ();
12163
12164 /* If %c is in mode line, update it if needed. */
12165 if (!NILP (w->column_number_displayed)
12166 /* This alternative quickly identifies a common case
12167 where no change is needed. */
12168 && !(PT == XFASTINT (w->last_point)
12169 && XFASTINT (w->last_modified) >= MODIFF
12170 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12171 && (XFASTINT (w->column_number_displayed)
12172 != (int) current_column ())) /* iftc */
12173 update_mode_line = 1;
12174
12175 /* Count number of windows showing the selected buffer. An indirect
12176 buffer counts as its base buffer. */
12177 if (!just_this_one_p)
12178 {
12179 struct buffer *current_base, *window_base;
12180 current_base = current_buffer;
12181 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
12182 if (current_base->base_buffer)
12183 current_base = current_base->base_buffer;
12184 if (window_base->base_buffer)
12185 window_base = window_base->base_buffer;
12186 if (current_base == window_base)
12187 buffer_shared++;
12188 }
12189
12190 /* Point refers normally to the selected window. For any other
12191 window, set up appropriate value. */
12192 if (!EQ (window, selected_window))
12193 {
12194 int new_pt = XMARKER (w->pointm)->charpos;
12195 int new_pt_byte = marker_byte_position (w->pointm);
12196 if (new_pt < BEGV)
12197 {
12198 new_pt = BEGV;
12199 new_pt_byte = BEGV_BYTE;
12200 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
12201 }
12202 else if (new_pt > (ZV - 1))
12203 {
12204 new_pt = ZV;
12205 new_pt_byte = ZV_BYTE;
12206 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
12207 }
12208
12209 /* We don't use SET_PT so that the point-motion hooks don't run. */
12210 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
12211 }
12212
12213 /* If any of the character widths specified in the display table
12214 have changed, invalidate the width run cache. It's true that
12215 this may be a bit late to catch such changes, but the rest of
12216 redisplay goes (non-fatally) haywire when the display table is
12217 changed, so why should we worry about doing any better? */
12218 if (current_buffer->width_run_cache)
12219 {
12220 struct Lisp_Char_Table *disptab = buffer_display_table ();
12221
12222 if (! disptab_matches_widthtab (disptab,
12223 XVECTOR (current_buffer->width_table)))
12224 {
12225 invalidate_region_cache (current_buffer,
12226 current_buffer->width_run_cache,
12227 BEG, Z);
12228 recompute_width_table (current_buffer, disptab);
12229 }
12230 }
12231
12232 /* If window-start is screwed up, choose a new one. */
12233 if (XMARKER (w->start)->buffer != current_buffer)
12234 goto recenter;
12235
12236 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12237
12238 /* If someone specified a new starting point but did not insist,
12239 check whether it can be used. */
12240 if (!NILP (w->optional_new_start)
12241 && CHARPOS (startp) >= BEGV
12242 && CHARPOS (startp) <= ZV)
12243 {
12244 w->optional_new_start = Qnil;
12245 start_display (&it, w, startp);
12246 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12247 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12248 if (IT_CHARPOS (it) == PT)
12249 w->force_start = Qt;
12250 /* IT may overshoot PT if text at PT is invisible. */
12251 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12252 w->force_start = Qt;
12253
12254
12255 }
12256
12257 /* Handle case where place to start displaying has been specified,
12258 unless the specified location is outside the accessible range. */
12259 if (!NILP (w->force_start)
12260 || w->frozen_window_start_p)
12261 {
12262 /* We set this later on if we have to adjust point. */
12263 int new_vpos = -1;
12264 int val;
12265
12266 w->force_start = Qnil;
12267 w->vscroll = 0;
12268 w->window_end_valid = Qnil;
12269
12270 /* Forget any recorded base line for line number display. */
12271 if (!buffer_unchanged_p)
12272 w->base_line_number = Qnil;
12273
12274 /* Redisplay the mode line. Select the buffer properly for that.
12275 Also, run the hook window-scroll-functions
12276 because we have scrolled. */
12277 /* Note, we do this after clearing force_start because
12278 if there's an error, it is better to forget about force_start
12279 than to get into an infinite loop calling the hook functions
12280 and having them get more errors. */
12281 if (!update_mode_line
12282 || ! NILP (Vwindow_scroll_functions))
12283 {
12284 update_mode_line = 1;
12285 w->update_mode_line = Qt;
12286 startp = run_window_scroll_functions (window, startp);
12287 }
12288
12289 w->last_modified = make_number (0);
12290 w->last_overlay_modified = make_number (0);
12291 if (CHARPOS (startp) < BEGV)
12292 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12293 else if (CHARPOS (startp) > ZV)
12294 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12295
12296 /* Redisplay, then check if cursor has been set during the
12297 redisplay. Give up if new fonts were loaded. */
12298 val = try_window (window, startp, 1);
12299 if (!val)
12300 {
12301 w->force_start = Qt;
12302 clear_glyph_matrix (w->desired_matrix);
12303 goto need_larger_matrices;
12304 }
12305 /* Point was outside the scroll margins. */
12306 if (val < 0)
12307 new_vpos = window_box_height (w) / 2;
12308
12309 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12310 {
12311 /* If point does not appear, try to move point so it does
12312 appear. The desired matrix has been built above, so we
12313 can use it here. */
12314 new_vpos = window_box_height (w) / 2;
12315 }
12316
12317 if (!cursor_row_fully_visible_p (w, 0, 0))
12318 {
12319 /* Point does appear, but on a line partly visible at end of window.
12320 Move it back to a fully-visible line. */
12321 new_vpos = window_box_height (w);
12322 }
12323
12324 /* If we need to move point for either of the above reasons,
12325 now actually do it. */
12326 if (new_vpos >= 0)
12327 {
12328 struct glyph_row *row;
12329
12330 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
12331 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
12332 ++row;
12333
12334 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
12335 MATRIX_ROW_START_BYTEPOS (row));
12336
12337 if (w != XWINDOW (selected_window))
12338 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
12339 else if (current_buffer == old)
12340 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12341
12342 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
12343
12344 /* If we are highlighting the region, then we just changed
12345 the region, so redisplay to show it. */
12346 if (!NILP (Vtransient_mark_mode)
12347 && !NILP (current_buffer->mark_active))
12348 {
12349 clear_glyph_matrix (w->desired_matrix);
12350 if (!try_window (window, startp, 0))
12351 goto need_larger_matrices;
12352 }
12353 }
12354
12355 #if GLYPH_DEBUG
12356 debug_method_add (w, "forced window start");
12357 #endif
12358 goto done;
12359 }
12360
12361 /* Handle case where text has not changed, only point, and it has
12362 not moved off the frame, and we are not retrying after hscroll.
12363 (current_matrix_up_to_date_p is nonzero when retrying.) */
12364 if (current_matrix_up_to_date_p
12365 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
12366 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
12367 {
12368 switch (rc)
12369 {
12370 case CURSOR_MOVEMENT_SUCCESS:
12371 used_current_matrix_p = 1;
12372 goto done;
12373
12374 #if 0 /* try_cursor_movement never returns this value. */
12375 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
12376 goto need_larger_matrices;
12377 #endif
12378
12379 case CURSOR_MOVEMENT_MUST_SCROLL:
12380 goto try_to_scroll;
12381
12382 default:
12383 abort ();
12384 }
12385 }
12386 /* If current starting point was originally the beginning of a line
12387 but no longer is, find a new starting point. */
12388 else if (!NILP (w->start_at_line_beg)
12389 && !(CHARPOS (startp) <= BEGV
12390 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
12391 {
12392 #if GLYPH_DEBUG
12393 debug_method_add (w, "recenter 1");
12394 #endif
12395 goto recenter;
12396 }
12397
12398 /* Try scrolling with try_window_id. Value is > 0 if update has
12399 been done, it is -1 if we know that the same window start will
12400 not work. It is 0 if unsuccessful for some other reason. */
12401 else if ((tem = try_window_id (w)) != 0)
12402 {
12403 #if GLYPH_DEBUG
12404 debug_method_add (w, "try_window_id %d", tem);
12405 #endif
12406
12407 if (fonts_changed_p)
12408 goto need_larger_matrices;
12409 if (tem > 0)
12410 goto done;
12411
12412 /* Otherwise try_window_id has returned -1 which means that we
12413 don't want the alternative below this comment to execute. */
12414 }
12415 else if (CHARPOS (startp) >= BEGV
12416 && CHARPOS (startp) <= ZV
12417 && PT >= CHARPOS (startp)
12418 && (CHARPOS (startp) < ZV
12419 /* Avoid starting at end of buffer. */
12420 || CHARPOS (startp) == BEGV
12421 || (XFASTINT (w->last_modified) >= MODIFF
12422 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12423 {
12424 #if GLYPH_DEBUG
12425 debug_method_add (w, "same window start");
12426 #endif
12427
12428 /* Try to redisplay starting at same place as before.
12429 If point has not moved off frame, accept the results. */
12430 if (!current_matrix_up_to_date_p
12431 /* Don't use try_window_reusing_current_matrix in this case
12432 because a window scroll function can have changed the
12433 buffer. */
12434 || !NILP (Vwindow_scroll_functions)
12435 || MINI_WINDOW_P (w)
12436 || !(used_current_matrix_p
12437 = try_window_reusing_current_matrix (w)))
12438 {
12439 IF_DEBUG (debug_method_add (w, "1"));
12440 if (try_window (window, startp, 1) < 0)
12441 /* -1 means we need to scroll.
12442 0 means we need new matrices, but fonts_changed_p
12443 is set in that case, so we will detect it below. */
12444 goto try_to_scroll;
12445 }
12446
12447 if (fonts_changed_p)
12448 goto need_larger_matrices;
12449
12450 if (w->cursor.vpos >= 0)
12451 {
12452 if (!just_this_one_p
12453 || current_buffer->clip_changed
12454 || BEG_UNCHANGED < CHARPOS (startp))
12455 /* Forget any recorded base line for line number display. */
12456 w->base_line_number = Qnil;
12457
12458 if (!cursor_row_fully_visible_p (w, 1, 0))
12459 {
12460 clear_glyph_matrix (w->desired_matrix);
12461 last_line_misfit = 1;
12462 }
12463 /* Drop through and scroll. */
12464 else
12465 goto done;
12466 }
12467 else
12468 clear_glyph_matrix (w->desired_matrix);
12469 }
12470
12471 try_to_scroll:
12472
12473 w->last_modified = make_number (0);
12474 w->last_overlay_modified = make_number (0);
12475
12476 /* Redisplay the mode line. Select the buffer properly for that. */
12477 if (!update_mode_line)
12478 {
12479 update_mode_line = 1;
12480 w->update_mode_line = Qt;
12481 }
12482
12483 /* Try to scroll by specified few lines. */
12484 if ((scroll_conservatively
12485 || scroll_step
12486 || temp_scroll_step
12487 || NUMBERP (current_buffer->scroll_up_aggressively)
12488 || NUMBERP (current_buffer->scroll_down_aggressively))
12489 && !current_buffer->clip_changed
12490 && CHARPOS (startp) >= BEGV
12491 && CHARPOS (startp) <= ZV)
12492 {
12493 /* The function returns -1 if new fonts were loaded, 1 if
12494 successful, 0 if not successful. */
12495 int rc = try_scrolling (window, just_this_one_p,
12496 scroll_conservatively,
12497 scroll_step,
12498 temp_scroll_step, last_line_misfit);
12499 switch (rc)
12500 {
12501 case SCROLLING_SUCCESS:
12502 goto done;
12503
12504 case SCROLLING_NEED_LARGER_MATRICES:
12505 goto need_larger_matrices;
12506
12507 case SCROLLING_FAILED:
12508 break;
12509
12510 default:
12511 abort ();
12512 }
12513 }
12514
12515 /* Finally, just choose place to start which centers point */
12516
12517 recenter:
12518 if (centering_position < 0)
12519 centering_position = window_box_height (w) / 2;
12520
12521 #if GLYPH_DEBUG
12522 debug_method_add (w, "recenter");
12523 #endif
12524
12525 /* w->vscroll = 0; */
12526
12527 /* Forget any previously recorded base line for line number display. */
12528 if (!buffer_unchanged_p)
12529 w->base_line_number = Qnil;
12530
12531 /* Move backward half the height of the window. */
12532 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12533 it.current_y = it.last_visible_y;
12534 move_it_vertically_backward (&it, centering_position);
12535 xassert (IT_CHARPOS (it) >= BEGV);
12536
12537 /* The function move_it_vertically_backward may move over more
12538 than the specified y-distance. If it->w is small, e.g. a
12539 mini-buffer window, we may end up in front of the window's
12540 display area. Start displaying at the start of the line
12541 containing PT in this case. */
12542 if (it.current_y <= 0)
12543 {
12544 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12545 move_it_vertically_backward (&it, 0);
12546 #if 0
12547 /* I think this assert is bogus if buffer contains
12548 invisible text or images. KFS. */
12549 xassert (IT_CHARPOS (it) <= PT);
12550 #endif
12551 it.current_y = 0;
12552 }
12553
12554 it.current_x = it.hpos = 0;
12555
12556 /* Set startp here explicitly in case that helps avoid an infinite loop
12557 in case the window-scroll-functions functions get errors. */
12558 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12559
12560 /* Run scroll hooks. */
12561 startp = run_window_scroll_functions (window, it.current.pos);
12562
12563 /* Redisplay the window. */
12564 if (!current_matrix_up_to_date_p
12565 || windows_or_buffers_changed
12566 || cursor_type_changed
12567 /* Don't use try_window_reusing_current_matrix in this case
12568 because it can have changed the buffer. */
12569 || !NILP (Vwindow_scroll_functions)
12570 || !just_this_one_p
12571 || MINI_WINDOW_P (w)
12572 || !(used_current_matrix_p
12573 = try_window_reusing_current_matrix (w)))
12574 try_window (window, startp, 0);
12575
12576 /* If new fonts have been loaded (due to fontsets), give up. We
12577 have to start a new redisplay since we need to re-adjust glyph
12578 matrices. */
12579 if (fonts_changed_p)
12580 goto need_larger_matrices;
12581
12582 /* If cursor did not appear assume that the middle of the window is
12583 in the first line of the window. Do it again with the next line.
12584 (Imagine a window of height 100, displaying two lines of height
12585 60. Moving back 50 from it->last_visible_y will end in the first
12586 line.) */
12587 if (w->cursor.vpos < 0)
12588 {
12589 if (!NILP (w->window_end_valid)
12590 && PT >= Z - XFASTINT (w->window_end_pos))
12591 {
12592 clear_glyph_matrix (w->desired_matrix);
12593 move_it_by_lines (&it, 1, 0);
12594 try_window (window, it.current.pos, 0);
12595 }
12596 else if (PT < IT_CHARPOS (it))
12597 {
12598 clear_glyph_matrix (w->desired_matrix);
12599 move_it_by_lines (&it, -1, 0);
12600 try_window (window, it.current.pos, 0);
12601 }
12602 else
12603 {
12604 /* Not much we can do about it. */
12605 }
12606 }
12607
12608 /* Consider the following case: Window starts at BEGV, there is
12609 invisible, intangible text at BEGV, so that display starts at
12610 some point START > BEGV. It can happen that we are called with
12611 PT somewhere between BEGV and START. Try to handle that case. */
12612 if (w->cursor.vpos < 0)
12613 {
12614 struct glyph_row *row = w->current_matrix->rows;
12615 if (row->mode_line_p)
12616 ++row;
12617 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12618 }
12619
12620 if (!cursor_row_fully_visible_p (w, 0, 0))
12621 {
12622 /* If vscroll is enabled, disable it and try again. */
12623 if (w->vscroll)
12624 {
12625 w->vscroll = 0;
12626 clear_glyph_matrix (w->desired_matrix);
12627 goto recenter;
12628 }
12629
12630 /* If centering point failed to make the whole line visible,
12631 put point at the top instead. That has to make the whole line
12632 visible, if it can be done. */
12633 if (centering_position == 0)
12634 goto done;
12635
12636 clear_glyph_matrix (w->desired_matrix);
12637 centering_position = 0;
12638 goto recenter;
12639 }
12640
12641 done:
12642
12643 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12644 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12645 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12646 ? Qt : Qnil);
12647
12648 /* Display the mode line, if we must. */
12649 if ((update_mode_line
12650 /* If window not full width, must redo its mode line
12651 if (a) the window to its side is being redone and
12652 (b) we do a frame-based redisplay. This is a consequence
12653 of how inverted lines are drawn in frame-based redisplay. */
12654 || (!just_this_one_p
12655 && !FRAME_WINDOW_P (f)
12656 && !WINDOW_FULL_WIDTH_P (w))
12657 /* Line number to display. */
12658 || INTEGERP (w->base_line_pos)
12659 /* Column number is displayed and different from the one displayed. */
12660 || (!NILP (w->column_number_displayed)
12661 && (XFASTINT (w->column_number_displayed)
12662 != (int) current_column ()))) /* iftc */
12663 /* This means that the window has a mode line. */
12664 && (WINDOW_WANTS_MODELINE_P (w)
12665 || WINDOW_WANTS_HEADER_LINE_P (w)))
12666 {
12667 display_mode_lines (w);
12668
12669 /* If mode line height has changed, arrange for a thorough
12670 immediate redisplay using the correct mode line height. */
12671 if (WINDOW_WANTS_MODELINE_P (w)
12672 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12673 {
12674 fonts_changed_p = 1;
12675 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12676 = DESIRED_MODE_LINE_HEIGHT (w);
12677 }
12678
12679 /* If top line height has changed, arrange for a thorough
12680 immediate redisplay using the correct mode line height. */
12681 if (WINDOW_WANTS_HEADER_LINE_P (w)
12682 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12683 {
12684 fonts_changed_p = 1;
12685 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12686 = DESIRED_HEADER_LINE_HEIGHT (w);
12687 }
12688
12689 if (fonts_changed_p)
12690 goto need_larger_matrices;
12691 }
12692
12693 if (!line_number_displayed
12694 && !BUFFERP (w->base_line_pos))
12695 {
12696 w->base_line_pos = Qnil;
12697 w->base_line_number = Qnil;
12698 }
12699
12700 finish_menu_bars:
12701
12702 /* When we reach a frame's selected window, redo the frame's menu bar. */
12703 if (update_mode_line
12704 && EQ (FRAME_SELECTED_WINDOW (f), window))
12705 {
12706 int redisplay_menu_p = 0;
12707 int redisplay_tool_bar_p = 0;
12708
12709 if (FRAME_WINDOW_P (f))
12710 {
12711 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12712 || defined (USE_GTK)
12713 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12714 #else
12715 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12716 #endif
12717 }
12718 else
12719 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12720
12721 if (redisplay_menu_p)
12722 display_menu_bar (w);
12723
12724 #ifdef HAVE_WINDOW_SYSTEM
12725 if (FRAME_WINDOW_P (f))
12726 {
12727 #ifdef USE_GTK
12728 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12729 #else
12730 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12731 && (FRAME_TOOL_BAR_LINES (f) > 0
12732 || auto_resize_tool_bars_p);
12733 #endif
12734
12735 if (redisplay_tool_bar_p)
12736 redisplay_tool_bar (f);
12737 }
12738 #endif
12739 }
12740
12741 #ifdef HAVE_WINDOW_SYSTEM
12742 if (FRAME_WINDOW_P (f)
12743 && update_window_fringes (w, (just_this_one_p
12744 || (!used_current_matrix_p && !overlay_arrow_seen)
12745 || w->pseudo_window_p)))
12746 {
12747 update_begin (f);
12748 BLOCK_INPUT;
12749 if (draw_window_fringes (w, 1))
12750 x_draw_vertical_border (w);
12751 UNBLOCK_INPUT;
12752 update_end (f);
12753 }
12754 #endif /* HAVE_WINDOW_SYSTEM */
12755
12756 /* We go to this label, with fonts_changed_p nonzero,
12757 if it is necessary to try again using larger glyph matrices.
12758 We have to redeem the scroll bar even in this case,
12759 because the loop in redisplay_internal expects that. */
12760 need_larger_matrices:
12761 ;
12762 finish_scroll_bars:
12763
12764 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12765 {
12766 /* Set the thumb's position and size. */
12767 set_vertical_scroll_bar (w);
12768
12769 /* Note that we actually used the scroll bar attached to this
12770 window, so it shouldn't be deleted at the end of redisplay. */
12771 if (FRAME_DEVICE (f)->redeem_scroll_bar_hook)
12772 (*FRAME_DEVICE (f)->redeem_scroll_bar_hook) (w);
12773 }
12774
12775 /* Restore current_buffer and value of point in it. */
12776 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12777 set_buffer_internal_1 (old);
12778 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12779
12780 unbind_to (count, Qnil);
12781 }
12782
12783
12784 /* Build the complete desired matrix of WINDOW with a window start
12785 buffer position POS.
12786
12787 Value is 1 if successful. It is zero if fonts were loaded during
12788 redisplay which makes re-adjusting glyph matrices necessary, and -1
12789 if point would appear in the scroll margins.
12790 (We check that only if CHECK_MARGINS is nonzero. */
12791
12792 int
12793 try_window (window, pos, check_margins)
12794 Lisp_Object window;
12795 struct text_pos pos;
12796 int check_margins;
12797 {
12798 struct window *w = XWINDOW (window);
12799 struct it it;
12800 struct glyph_row *last_text_row = NULL;
12801
12802 /* Make POS the new window start. */
12803 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12804
12805 /* Mark cursor position as unknown. No overlay arrow seen. */
12806 w->cursor.vpos = -1;
12807 overlay_arrow_seen = 0;
12808
12809 /* Initialize iterator and info to start at POS. */
12810 start_display (&it, w, pos);
12811
12812 /* Display all lines of W. */
12813 while (it.current_y < it.last_visible_y)
12814 {
12815 if (display_line (&it))
12816 last_text_row = it.glyph_row - 1;
12817 if (fonts_changed_p)
12818 return 0;
12819 }
12820
12821 /* Don't let the cursor end in the scroll margins. */
12822 if (check_margins
12823 && !MINI_WINDOW_P (w))
12824 {
12825 int this_scroll_margin, cursor_height;
12826
12827 this_scroll_margin = max (0, scroll_margin);
12828 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12829 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
12830 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
12831
12832 if ((w->cursor.y < this_scroll_margin
12833 && CHARPOS (pos) > BEGV)
12834 /* rms: considering make_cursor_line_fully_visible_p here
12835 seems to give wrong results. We don't want to recenter
12836 when the last line is partly visible, we want to allow
12837 that case to be handled in the usual way. */
12838 || (w->cursor.y + 1) > it.last_visible_y)
12839 {
12840 w->cursor.vpos = -1;
12841 clear_glyph_matrix (w->desired_matrix);
12842 return -1;
12843 }
12844 }
12845
12846 /* If bottom moved off end of frame, change mode line percentage. */
12847 if (XFASTINT (w->window_end_pos) <= 0
12848 && Z != IT_CHARPOS (it))
12849 w->update_mode_line = Qt;
12850
12851 /* Set window_end_pos to the offset of the last character displayed
12852 on the window from the end of current_buffer. Set
12853 window_end_vpos to its row number. */
12854 if (last_text_row)
12855 {
12856 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12857 w->window_end_bytepos
12858 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12859 w->window_end_pos
12860 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12861 w->window_end_vpos
12862 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12863 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12864 ->displays_text_p);
12865 }
12866 else
12867 {
12868 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12869 w->window_end_pos = make_number (Z - ZV);
12870 w->window_end_vpos = make_number (0);
12871 }
12872
12873 /* But that is not valid info until redisplay finishes. */
12874 w->window_end_valid = Qnil;
12875 return 1;
12876 }
12877
12878
12879 \f
12880 /************************************************************************
12881 Window redisplay reusing current matrix when buffer has not changed
12882 ************************************************************************/
12883
12884 /* Try redisplay of window W showing an unchanged buffer with a
12885 different window start than the last time it was displayed by
12886 reusing its current matrix. Value is non-zero if successful.
12887 W->start is the new window start. */
12888
12889 static int
12890 try_window_reusing_current_matrix (w)
12891 struct window *w;
12892 {
12893 struct frame *f = XFRAME (w->frame);
12894 struct glyph_row *row, *bottom_row;
12895 struct it it;
12896 struct run run;
12897 struct text_pos start, new_start;
12898 int nrows_scrolled, i;
12899 struct glyph_row *last_text_row;
12900 struct glyph_row *last_reused_text_row;
12901 struct glyph_row *start_row;
12902 int start_vpos, min_y, max_y;
12903
12904 #if GLYPH_DEBUG
12905 if (inhibit_try_window_reusing)
12906 return 0;
12907 #endif
12908
12909 if (/* This function doesn't handle terminal frames. */
12910 !FRAME_WINDOW_P (f)
12911 /* Don't try to reuse the display if windows have been split
12912 or such. */
12913 || windows_or_buffers_changed
12914 || cursor_type_changed)
12915 return 0;
12916
12917 /* Can't do this if region may have changed. */
12918 if ((!NILP (Vtransient_mark_mode)
12919 && !NILP (current_buffer->mark_active))
12920 || !NILP (w->region_showing)
12921 || !NILP (Vshow_trailing_whitespace))
12922 return 0;
12923
12924 /* If top-line visibility has changed, give up. */
12925 if (WINDOW_WANTS_HEADER_LINE_P (w)
12926 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12927 return 0;
12928
12929 /* Give up if old or new display is scrolled vertically. We could
12930 make this function handle this, but right now it doesn't. */
12931 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12932 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12933 return 0;
12934
12935 /* The variable new_start now holds the new window start. The old
12936 start `start' can be determined from the current matrix. */
12937 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12938 start = start_row->start.pos;
12939 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12940
12941 /* Clear the desired matrix for the display below. */
12942 clear_glyph_matrix (w->desired_matrix);
12943
12944 if (CHARPOS (new_start) <= CHARPOS (start))
12945 {
12946 int first_row_y;
12947
12948 /* Don't use this method if the display starts with an ellipsis
12949 displayed for invisible text. It's not easy to handle that case
12950 below, and it's certainly not worth the effort since this is
12951 not a frequent case. */
12952 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12953 return 0;
12954
12955 IF_DEBUG (debug_method_add (w, "twu1"));
12956
12957 /* Display up to a row that can be reused. The variable
12958 last_text_row is set to the last row displayed that displays
12959 text. Note that it.vpos == 0 if or if not there is a
12960 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12961 start_display (&it, w, new_start);
12962 first_row_y = it.current_y;
12963 w->cursor.vpos = -1;
12964 last_text_row = last_reused_text_row = NULL;
12965
12966 while (it.current_y < it.last_visible_y
12967 && !fonts_changed_p)
12968 {
12969 /* If we have reached into the characters in the START row,
12970 that means the line boundaries have changed. So we
12971 can't start copying with the row START. Maybe it will
12972 work to start copying with the following row. */
12973 while (IT_CHARPOS (it) > CHARPOS (start))
12974 {
12975 /* Advance to the next row as the "start". */
12976 start_row++;
12977 start = start_row->start.pos;
12978 /* If there are no more rows to try, or just one, give up. */
12979 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12980 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12981 || CHARPOS (start) == ZV)
12982 {
12983 clear_glyph_matrix (w->desired_matrix);
12984 return 0;
12985 }
12986
12987 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12988 }
12989 /* If we have reached alignment,
12990 we can copy the rest of the rows. */
12991 if (IT_CHARPOS (it) == CHARPOS (start))
12992 break;
12993
12994 if (display_line (&it))
12995 last_text_row = it.glyph_row - 1;
12996 }
12997
12998 /* A value of current_y < last_visible_y means that we stopped
12999 at the previous window start, which in turn means that we
13000 have at least one reusable row. */
13001 if (it.current_y < it.last_visible_y)
13002 {
13003 /* IT.vpos always starts from 0; it counts text lines. */
13004 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
13005
13006 /* Find PT if not already found in the lines displayed. */
13007 if (w->cursor.vpos < 0)
13008 {
13009 int dy = it.current_y - start_row->y;
13010
13011 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13012 row = row_containing_pos (w, PT, row, NULL, dy);
13013 if (row)
13014 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
13015 dy, nrows_scrolled);
13016 else
13017 {
13018 clear_glyph_matrix (w->desired_matrix);
13019 return 0;
13020 }
13021 }
13022
13023 /* Scroll the display. Do it before the current matrix is
13024 changed. The problem here is that update has not yet
13025 run, i.e. part of the current matrix is not up to date.
13026 scroll_run_hook will clear the cursor, and use the
13027 current matrix to get the height of the row the cursor is
13028 in. */
13029 run.current_y = start_row->y;
13030 run.desired_y = it.current_y;
13031 run.height = it.last_visible_y - it.current_y;
13032
13033 if (run.height > 0 && run.current_y != run.desired_y)
13034 {
13035 update_begin (f);
13036 FRAME_RIF (f)->update_window_begin_hook (w);
13037 FRAME_RIF (f)->clear_window_mouse_face (w);
13038 FRAME_RIF (f)->scroll_run_hook (w, &run);
13039 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13040 update_end (f);
13041 }
13042
13043 /* Shift current matrix down by nrows_scrolled lines. */
13044 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13045 rotate_matrix (w->current_matrix,
13046 start_vpos,
13047 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13048 nrows_scrolled);
13049
13050 /* Disable lines that must be updated. */
13051 for (i = 0; i < it.vpos; ++i)
13052 (start_row + i)->enabled_p = 0;
13053
13054 /* Re-compute Y positions. */
13055 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13056 max_y = it.last_visible_y;
13057 for (row = start_row + nrows_scrolled;
13058 row < bottom_row;
13059 ++row)
13060 {
13061 row->y = it.current_y;
13062 row->visible_height = row->height;
13063
13064 if (row->y < min_y)
13065 row->visible_height -= min_y - row->y;
13066 if (row->y + row->height > max_y)
13067 row->visible_height -= row->y + row->height - max_y;
13068 row->redraw_fringe_bitmaps_p = 1;
13069
13070 it.current_y += row->height;
13071
13072 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13073 last_reused_text_row = row;
13074 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
13075 break;
13076 }
13077
13078 /* Disable lines in the current matrix which are now
13079 below the window. */
13080 for (++row; row < bottom_row; ++row)
13081 row->enabled_p = 0;
13082 }
13083
13084 /* Update window_end_pos etc.; last_reused_text_row is the last
13085 reused row from the current matrix containing text, if any.
13086 The value of last_text_row is the last displayed line
13087 containing text. */
13088 if (last_reused_text_row)
13089 {
13090 w->window_end_bytepos
13091 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
13092 w->window_end_pos
13093 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
13094 w->window_end_vpos
13095 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
13096 w->current_matrix));
13097 }
13098 else if (last_text_row)
13099 {
13100 w->window_end_bytepos
13101 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13102 w->window_end_pos
13103 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13104 w->window_end_vpos
13105 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13106 }
13107 else
13108 {
13109 /* This window must be completely empty. */
13110 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13111 w->window_end_pos = make_number (Z - ZV);
13112 w->window_end_vpos = make_number (0);
13113 }
13114 w->window_end_valid = Qnil;
13115
13116 /* Update hint: don't try scrolling again in update_window. */
13117 w->desired_matrix->no_scrolling_p = 1;
13118
13119 #if GLYPH_DEBUG
13120 debug_method_add (w, "try_window_reusing_current_matrix 1");
13121 #endif
13122 return 1;
13123 }
13124 else if (CHARPOS (new_start) > CHARPOS (start))
13125 {
13126 struct glyph_row *pt_row, *row;
13127 struct glyph_row *first_reusable_row;
13128 struct glyph_row *first_row_to_display;
13129 int dy;
13130 int yb = window_text_bottom_y (w);
13131
13132 /* Find the row starting at new_start, if there is one. Don't
13133 reuse a partially visible line at the end. */
13134 first_reusable_row = start_row;
13135 while (first_reusable_row->enabled_p
13136 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
13137 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13138 < CHARPOS (new_start)))
13139 ++first_reusable_row;
13140
13141 /* Give up if there is no row to reuse. */
13142 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
13143 || !first_reusable_row->enabled_p
13144 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13145 != CHARPOS (new_start)))
13146 return 0;
13147
13148 /* We can reuse fully visible rows beginning with
13149 first_reusable_row to the end of the window. Set
13150 first_row_to_display to the first row that cannot be reused.
13151 Set pt_row to the row containing point, if there is any. */
13152 pt_row = NULL;
13153 for (first_row_to_display = first_reusable_row;
13154 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
13155 ++first_row_to_display)
13156 {
13157 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
13158 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
13159 pt_row = first_row_to_display;
13160 }
13161
13162 /* Start displaying at the start of first_row_to_display. */
13163 xassert (first_row_to_display->y < yb);
13164 init_to_row_start (&it, w, first_row_to_display);
13165
13166 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
13167 - start_vpos);
13168 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
13169 - nrows_scrolled);
13170 it.current_y = (first_row_to_display->y - first_reusable_row->y
13171 + WINDOW_HEADER_LINE_HEIGHT (w));
13172
13173 /* Display lines beginning with first_row_to_display in the
13174 desired matrix. Set last_text_row to the last row displayed
13175 that displays text. */
13176 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
13177 if (pt_row == NULL)
13178 w->cursor.vpos = -1;
13179 last_text_row = NULL;
13180 while (it.current_y < it.last_visible_y && !fonts_changed_p)
13181 if (display_line (&it))
13182 last_text_row = it.glyph_row - 1;
13183
13184 /* Give up If point isn't in a row displayed or reused. */
13185 if (w->cursor.vpos < 0)
13186 {
13187 clear_glyph_matrix (w->desired_matrix);
13188 return 0;
13189 }
13190
13191 /* If point is in a reused row, adjust y and vpos of the cursor
13192 position. */
13193 if (pt_row)
13194 {
13195 w->cursor.vpos -= nrows_scrolled;
13196 w->cursor.y -= first_reusable_row->y - start_row->y;
13197 }
13198
13199 /* Scroll the display. */
13200 run.current_y = first_reusable_row->y;
13201 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
13202 run.height = it.last_visible_y - run.current_y;
13203 dy = run.current_y - run.desired_y;
13204
13205 if (run.height)
13206 {
13207 update_begin (f);
13208 FRAME_RIF (f)->update_window_begin_hook (w);
13209 FRAME_RIF (f)->clear_window_mouse_face (w);
13210 FRAME_RIF (f)->scroll_run_hook (w, &run);
13211 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
13212 update_end (f);
13213 }
13214
13215 /* Adjust Y positions of reused rows. */
13216 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13217 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13218 max_y = it.last_visible_y;
13219 for (row = first_reusable_row; row < first_row_to_display; ++row)
13220 {
13221 row->y -= dy;
13222 row->visible_height = row->height;
13223 if (row->y < min_y)
13224 row->visible_height -= min_y - row->y;
13225 if (row->y + row->height > max_y)
13226 row->visible_height -= row->y + row->height - max_y;
13227 row->redraw_fringe_bitmaps_p = 1;
13228 }
13229
13230 /* Scroll the current matrix. */
13231 xassert (nrows_scrolled > 0);
13232 rotate_matrix (w->current_matrix,
13233 start_vpos,
13234 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13235 -nrows_scrolled);
13236
13237 /* Disable rows not reused. */
13238 for (row -= nrows_scrolled; row < bottom_row; ++row)
13239 row->enabled_p = 0;
13240
13241 /* Point may have moved to a different line, so we cannot assume that
13242 the previous cursor position is valid; locate the correct row. */
13243 if (pt_row)
13244 {
13245 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
13246 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
13247 row++)
13248 {
13249 w->cursor.vpos++;
13250 w->cursor.y = row->y;
13251 }
13252 if (row < bottom_row)
13253 {
13254 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
13255 while (glyph->charpos < PT)
13256 {
13257 w->cursor.hpos++;
13258 w->cursor.x += glyph->pixel_width;
13259 glyph++;
13260 }
13261 }
13262 }
13263
13264 /* Adjust window end. A null value of last_text_row means that
13265 the window end is in reused rows which in turn means that
13266 only its vpos can have changed. */
13267 if (last_text_row)
13268 {
13269 w->window_end_bytepos
13270 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13271 w->window_end_pos
13272 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13273 w->window_end_vpos
13274 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13275 }
13276 else
13277 {
13278 w->window_end_vpos
13279 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
13280 }
13281
13282 w->window_end_valid = Qnil;
13283 w->desired_matrix->no_scrolling_p = 1;
13284
13285 #if GLYPH_DEBUG
13286 debug_method_add (w, "try_window_reusing_current_matrix 2");
13287 #endif
13288 return 1;
13289 }
13290
13291 return 0;
13292 }
13293
13294
13295 \f
13296 /************************************************************************
13297 Window redisplay reusing current matrix when buffer has changed
13298 ************************************************************************/
13299
13300 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
13301 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
13302 int *, int *));
13303 static struct glyph_row *
13304 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
13305 struct glyph_row *));
13306
13307
13308 /* Return the last row in MATRIX displaying text. If row START is
13309 non-null, start searching with that row. IT gives the dimensions
13310 of the display. Value is null if matrix is empty; otherwise it is
13311 a pointer to the row found. */
13312
13313 static struct glyph_row *
13314 find_last_row_displaying_text (matrix, it, start)
13315 struct glyph_matrix *matrix;
13316 struct it *it;
13317 struct glyph_row *start;
13318 {
13319 struct glyph_row *row, *row_found;
13320
13321 /* Set row_found to the last row in IT->w's current matrix
13322 displaying text. The loop looks funny but think of partially
13323 visible lines. */
13324 row_found = NULL;
13325 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
13326 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13327 {
13328 xassert (row->enabled_p);
13329 row_found = row;
13330 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
13331 break;
13332 ++row;
13333 }
13334
13335 return row_found;
13336 }
13337
13338
13339 /* Return the last row in the current matrix of W that is not affected
13340 by changes at the start of current_buffer that occurred since W's
13341 current matrix was built. Value is null if no such row exists.
13342
13343 BEG_UNCHANGED us the number of characters unchanged at the start of
13344 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13345 first changed character in current_buffer. Characters at positions <
13346 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13347 when the current matrix was built. */
13348
13349 static struct glyph_row *
13350 find_last_unchanged_at_beg_row (w)
13351 struct window *w;
13352 {
13353 int first_changed_pos = BEG + BEG_UNCHANGED;
13354 struct glyph_row *row;
13355 struct glyph_row *row_found = NULL;
13356 int yb = window_text_bottom_y (w);
13357
13358 /* Find the last row displaying unchanged text. */
13359 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13360 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13361 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
13362 {
13363 if (/* If row ends before first_changed_pos, it is unchanged,
13364 except in some case. */
13365 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
13366 /* When row ends in ZV and we write at ZV it is not
13367 unchanged. */
13368 && !row->ends_at_zv_p
13369 /* When first_changed_pos is the end of a continued line,
13370 row is not unchanged because it may be no longer
13371 continued. */
13372 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
13373 && (row->continued_p
13374 || row->exact_window_width_line_p)))
13375 row_found = row;
13376
13377 /* Stop if last visible row. */
13378 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
13379 break;
13380
13381 ++row;
13382 }
13383
13384 return row_found;
13385 }
13386
13387
13388 /* Find the first glyph row in the current matrix of W that is not
13389 affected by changes at the end of current_buffer since the
13390 time W's current matrix was built.
13391
13392 Return in *DELTA the number of chars by which buffer positions in
13393 unchanged text at the end of current_buffer must be adjusted.
13394
13395 Return in *DELTA_BYTES the corresponding number of bytes.
13396
13397 Value is null if no such row exists, i.e. all rows are affected by
13398 changes. */
13399
13400 static struct glyph_row *
13401 find_first_unchanged_at_end_row (w, delta, delta_bytes)
13402 struct window *w;
13403 int *delta, *delta_bytes;
13404 {
13405 struct glyph_row *row;
13406 struct glyph_row *row_found = NULL;
13407
13408 *delta = *delta_bytes = 0;
13409
13410 /* Display must not have been paused, otherwise the current matrix
13411 is not up to date. */
13412 if (NILP (w->window_end_valid))
13413 abort ();
13414
13415 /* A value of window_end_pos >= END_UNCHANGED means that the window
13416 end is in the range of changed text. If so, there is no
13417 unchanged row at the end of W's current matrix. */
13418 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
13419 return NULL;
13420
13421 /* Set row to the last row in W's current matrix displaying text. */
13422 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13423
13424 /* If matrix is entirely empty, no unchanged row exists. */
13425 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13426 {
13427 /* The value of row is the last glyph row in the matrix having a
13428 meaningful buffer position in it. The end position of row
13429 corresponds to window_end_pos. This allows us to translate
13430 buffer positions in the current matrix to current buffer
13431 positions for characters not in changed text. */
13432 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13433 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13434 int last_unchanged_pos, last_unchanged_pos_old;
13435 struct glyph_row *first_text_row
13436 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13437
13438 *delta = Z - Z_old;
13439 *delta_bytes = Z_BYTE - Z_BYTE_old;
13440
13441 /* Set last_unchanged_pos to the buffer position of the last
13442 character in the buffer that has not been changed. Z is the
13443 index + 1 of the last character in current_buffer, i.e. by
13444 subtracting END_UNCHANGED we get the index of the last
13445 unchanged character, and we have to add BEG to get its buffer
13446 position. */
13447 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13448 last_unchanged_pos_old = last_unchanged_pos - *delta;
13449
13450 /* Search backward from ROW for a row displaying a line that
13451 starts at a minimum position >= last_unchanged_pos_old. */
13452 for (; row > first_text_row; --row)
13453 {
13454 /* This used to abort, but it can happen.
13455 It is ok to just stop the search instead here. KFS. */
13456 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13457 break;
13458
13459 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13460 row_found = row;
13461 }
13462 }
13463
13464 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13465 abort ();
13466
13467 return row_found;
13468 }
13469
13470
13471 /* Make sure that glyph rows in the current matrix of window W
13472 reference the same glyph memory as corresponding rows in the
13473 frame's frame matrix. This function is called after scrolling W's
13474 current matrix on a terminal frame in try_window_id and
13475 try_window_reusing_current_matrix. */
13476
13477 static void
13478 sync_frame_with_window_matrix_rows (w)
13479 struct window *w;
13480 {
13481 struct frame *f = XFRAME (w->frame);
13482 struct glyph_row *window_row, *window_row_end, *frame_row;
13483
13484 /* Preconditions: W must be a leaf window and full-width. Its frame
13485 must have a frame matrix. */
13486 xassert (NILP (w->hchild) && NILP (w->vchild));
13487 xassert (WINDOW_FULL_WIDTH_P (w));
13488 xassert (!FRAME_WINDOW_P (f));
13489
13490 /* If W is a full-width window, glyph pointers in W's current matrix
13491 have, by definition, to be the same as glyph pointers in the
13492 corresponding frame matrix. Note that frame matrices have no
13493 marginal areas (see build_frame_matrix). */
13494 window_row = w->current_matrix->rows;
13495 window_row_end = window_row + w->current_matrix->nrows;
13496 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13497 while (window_row < window_row_end)
13498 {
13499 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13500 struct glyph *end = window_row->glyphs[LAST_AREA];
13501
13502 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13503 frame_row->glyphs[TEXT_AREA] = start;
13504 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13505 frame_row->glyphs[LAST_AREA] = end;
13506
13507 /* Disable frame rows whose corresponding window rows have
13508 been disabled in try_window_id. */
13509 if (!window_row->enabled_p)
13510 frame_row->enabled_p = 0;
13511
13512 ++window_row, ++frame_row;
13513 }
13514 }
13515
13516
13517 /* Find the glyph row in window W containing CHARPOS. Consider all
13518 rows between START and END (not inclusive). END null means search
13519 all rows to the end of the display area of W. Value is the row
13520 containing CHARPOS or null. */
13521
13522 struct glyph_row *
13523 row_containing_pos (w, charpos, start, end, dy)
13524 struct window *w;
13525 int charpos;
13526 struct glyph_row *start, *end;
13527 int dy;
13528 {
13529 struct glyph_row *row = start;
13530 int last_y;
13531
13532 /* If we happen to start on a header-line, skip that. */
13533 if (row->mode_line_p)
13534 ++row;
13535
13536 if ((end && row >= end) || !row->enabled_p)
13537 return NULL;
13538
13539 last_y = window_text_bottom_y (w) - dy;
13540
13541 while (1)
13542 {
13543 /* Give up if we have gone too far. */
13544 if (end && row >= end)
13545 return NULL;
13546 /* This formerly returned if they were equal.
13547 I think that both quantities are of a "last plus one" type;
13548 if so, when they are equal, the row is within the screen. -- rms. */
13549 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13550 return NULL;
13551
13552 /* If it is in this row, return this row. */
13553 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13554 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13555 /* The end position of a row equals the start
13556 position of the next row. If CHARPOS is there, we
13557 would rather display it in the next line, except
13558 when this line ends in ZV. */
13559 && !row->ends_at_zv_p
13560 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13561 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13562 return row;
13563 ++row;
13564 }
13565 }
13566
13567
13568 /* Try to redisplay window W by reusing its existing display. W's
13569 current matrix must be up to date when this function is called,
13570 i.e. window_end_valid must not be nil.
13571
13572 Value is
13573
13574 1 if display has been updated
13575 0 if otherwise unsuccessful
13576 -1 if redisplay with same window start is known not to succeed
13577
13578 The following steps are performed:
13579
13580 1. Find the last row in the current matrix of W that is not
13581 affected by changes at the start of current_buffer. If no such row
13582 is found, give up.
13583
13584 2. Find the first row in W's current matrix that is not affected by
13585 changes at the end of current_buffer. Maybe there is no such row.
13586
13587 3. Display lines beginning with the row + 1 found in step 1 to the
13588 row found in step 2 or, if step 2 didn't find a row, to the end of
13589 the window.
13590
13591 4. If cursor is not known to appear on the window, give up.
13592
13593 5. If display stopped at the row found in step 2, scroll the
13594 display and current matrix as needed.
13595
13596 6. Maybe display some lines at the end of W, if we must. This can
13597 happen under various circumstances, like a partially visible line
13598 becoming fully visible, or because newly displayed lines are displayed
13599 in smaller font sizes.
13600
13601 7. Update W's window end information. */
13602
13603 static int
13604 try_window_id (w)
13605 struct window *w;
13606 {
13607 struct frame *f = XFRAME (w->frame);
13608 struct glyph_matrix *current_matrix = w->current_matrix;
13609 struct glyph_matrix *desired_matrix = w->desired_matrix;
13610 struct glyph_row *last_unchanged_at_beg_row;
13611 struct glyph_row *first_unchanged_at_end_row;
13612 struct glyph_row *row;
13613 struct glyph_row *bottom_row;
13614 int bottom_vpos;
13615 struct it it;
13616 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13617 struct text_pos start_pos;
13618 struct run run;
13619 int first_unchanged_at_end_vpos = 0;
13620 struct glyph_row *last_text_row, *last_text_row_at_end;
13621 struct text_pos start;
13622 int first_changed_charpos, last_changed_charpos;
13623
13624 #if GLYPH_DEBUG
13625 if (inhibit_try_window_id)
13626 return 0;
13627 #endif
13628
13629 /* This is handy for debugging. */
13630 #if 0
13631 #define GIVE_UP(X) \
13632 do { \
13633 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13634 return 0; \
13635 } while (0)
13636 #else
13637 #define GIVE_UP(X) return 0
13638 #endif
13639
13640 SET_TEXT_POS_FROM_MARKER (start, w->start);
13641
13642 /* Don't use this for mini-windows because these can show
13643 messages and mini-buffers, and we don't handle that here. */
13644 if (MINI_WINDOW_P (w))
13645 GIVE_UP (1);
13646
13647 /* This flag is used to prevent redisplay optimizations. */
13648 if (windows_or_buffers_changed || cursor_type_changed)
13649 GIVE_UP (2);
13650
13651 /* Verify that narrowing has not changed.
13652 Also verify that we were not told to prevent redisplay optimizations.
13653 It would be nice to further
13654 reduce the number of cases where this prevents try_window_id. */
13655 if (current_buffer->clip_changed
13656 || current_buffer->prevent_redisplay_optimizations_p)
13657 GIVE_UP (3);
13658
13659 /* Window must either use window-based redisplay or be full width. */
13660 if (!FRAME_WINDOW_P (f)
13661 && (!FRAME_LINE_INS_DEL_OK (f)
13662 || !WINDOW_FULL_WIDTH_P (w)))
13663 GIVE_UP (4);
13664
13665 /* Give up if point is not known NOT to appear in W. */
13666 if (PT < CHARPOS (start))
13667 GIVE_UP (5);
13668
13669 /* Another way to prevent redisplay optimizations. */
13670 if (XFASTINT (w->last_modified) == 0)
13671 GIVE_UP (6);
13672
13673 /* Verify that window is not hscrolled. */
13674 if (XFASTINT (w->hscroll) != 0)
13675 GIVE_UP (7);
13676
13677 /* Verify that display wasn't paused. */
13678 if (NILP (w->window_end_valid))
13679 GIVE_UP (8);
13680
13681 /* Can't use this if highlighting a region because a cursor movement
13682 will do more than just set the cursor. */
13683 if (!NILP (Vtransient_mark_mode)
13684 && !NILP (current_buffer->mark_active))
13685 GIVE_UP (9);
13686
13687 /* Likewise if highlighting trailing whitespace. */
13688 if (!NILP (Vshow_trailing_whitespace))
13689 GIVE_UP (11);
13690
13691 /* Likewise if showing a region. */
13692 if (!NILP (w->region_showing))
13693 GIVE_UP (10);
13694
13695 /* Can use this if overlay arrow position and or string have changed. */
13696 if (overlay_arrows_changed_p ())
13697 GIVE_UP (12);
13698
13699
13700 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13701 only if buffer has really changed. The reason is that the gap is
13702 initially at Z for freshly visited files. The code below would
13703 set end_unchanged to 0 in that case. */
13704 if (MODIFF > SAVE_MODIFF
13705 /* This seems to happen sometimes after saving a buffer. */
13706 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13707 {
13708 if (GPT - BEG < BEG_UNCHANGED)
13709 BEG_UNCHANGED = GPT - BEG;
13710 if (Z - GPT < END_UNCHANGED)
13711 END_UNCHANGED = Z - GPT;
13712 }
13713
13714 /* The position of the first and last character that has been changed. */
13715 first_changed_charpos = BEG + BEG_UNCHANGED;
13716 last_changed_charpos = Z - END_UNCHANGED;
13717
13718 /* If window starts after a line end, and the last change is in
13719 front of that newline, then changes don't affect the display.
13720 This case happens with stealth-fontification. Note that although
13721 the display is unchanged, glyph positions in the matrix have to
13722 be adjusted, of course. */
13723 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13724 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13725 && ((last_changed_charpos < CHARPOS (start)
13726 && CHARPOS (start) == BEGV)
13727 || (last_changed_charpos < CHARPOS (start) - 1
13728 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13729 {
13730 int Z_old, delta, Z_BYTE_old, delta_bytes;
13731 struct glyph_row *r0;
13732
13733 /* Compute how many chars/bytes have been added to or removed
13734 from the buffer. */
13735 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13736 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13737 delta = Z - Z_old;
13738 delta_bytes = Z_BYTE - Z_BYTE_old;
13739
13740 /* Give up if PT is not in the window. Note that it already has
13741 been checked at the start of try_window_id that PT is not in
13742 front of the window start. */
13743 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13744 GIVE_UP (13);
13745
13746 /* If window start is unchanged, we can reuse the whole matrix
13747 as is, after adjusting glyph positions. No need to compute
13748 the window end again, since its offset from Z hasn't changed. */
13749 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13750 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13751 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13752 /* PT must not be in a partially visible line. */
13753 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13754 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13755 {
13756 /* Adjust positions in the glyph matrix. */
13757 if (delta || delta_bytes)
13758 {
13759 struct glyph_row *r1
13760 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13761 increment_matrix_positions (w->current_matrix,
13762 MATRIX_ROW_VPOS (r0, current_matrix),
13763 MATRIX_ROW_VPOS (r1, current_matrix),
13764 delta, delta_bytes);
13765 }
13766
13767 /* Set the cursor. */
13768 row = row_containing_pos (w, PT, r0, NULL, 0);
13769 if (row)
13770 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13771 else
13772 abort ();
13773 return 1;
13774 }
13775 }
13776
13777 /* Handle the case that changes are all below what is displayed in
13778 the window, and that PT is in the window. This shortcut cannot
13779 be taken if ZV is visible in the window, and text has been added
13780 there that is visible in the window. */
13781 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13782 /* ZV is not visible in the window, or there are no
13783 changes at ZV, actually. */
13784 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13785 || first_changed_charpos == last_changed_charpos))
13786 {
13787 struct glyph_row *r0;
13788
13789 /* Give up if PT is not in the window. Note that it already has
13790 been checked at the start of try_window_id that PT is not in
13791 front of the window start. */
13792 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13793 GIVE_UP (14);
13794
13795 /* If window start is unchanged, we can reuse the whole matrix
13796 as is, without changing glyph positions since no text has
13797 been added/removed in front of the window end. */
13798 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13799 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13800 /* PT must not be in a partially visible line. */
13801 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13802 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13803 {
13804 /* We have to compute the window end anew since text
13805 can have been added/removed after it. */
13806 w->window_end_pos
13807 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13808 w->window_end_bytepos
13809 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13810
13811 /* Set the cursor. */
13812 row = row_containing_pos (w, PT, r0, NULL, 0);
13813 if (row)
13814 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13815 else
13816 abort ();
13817 return 2;
13818 }
13819 }
13820
13821 /* Give up if window start is in the changed area.
13822
13823 The condition used to read
13824
13825 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13826
13827 but why that was tested escapes me at the moment. */
13828 if (CHARPOS (start) >= first_changed_charpos
13829 && CHARPOS (start) <= last_changed_charpos)
13830 GIVE_UP (15);
13831
13832 /* Check that window start agrees with the start of the first glyph
13833 row in its current matrix. Check this after we know the window
13834 start is not in changed text, otherwise positions would not be
13835 comparable. */
13836 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13837 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13838 GIVE_UP (16);
13839
13840 /* Give up if the window ends in strings. Overlay strings
13841 at the end are difficult to handle, so don't try. */
13842 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13843 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13844 GIVE_UP (20);
13845
13846 /* Compute the position at which we have to start displaying new
13847 lines. Some of the lines at the top of the window might be
13848 reusable because they are not displaying changed text. Find the
13849 last row in W's current matrix not affected by changes at the
13850 start of current_buffer. Value is null if changes start in the
13851 first line of window. */
13852 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13853 if (last_unchanged_at_beg_row)
13854 {
13855 /* Avoid starting to display in the moddle of a character, a TAB
13856 for instance. This is easier than to set up the iterator
13857 exactly, and it's not a frequent case, so the additional
13858 effort wouldn't really pay off. */
13859 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13860 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13861 && last_unchanged_at_beg_row > w->current_matrix->rows)
13862 --last_unchanged_at_beg_row;
13863
13864 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13865 GIVE_UP (17);
13866
13867 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13868 GIVE_UP (18);
13869 start_pos = it.current.pos;
13870
13871 /* Start displaying new lines in the desired matrix at the same
13872 vpos we would use in the current matrix, i.e. below
13873 last_unchanged_at_beg_row. */
13874 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13875 current_matrix);
13876 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13877 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13878
13879 xassert (it.hpos == 0 && it.current_x == 0);
13880 }
13881 else
13882 {
13883 /* There are no reusable lines at the start of the window.
13884 Start displaying in the first text line. */
13885 start_display (&it, w, start);
13886 it.vpos = it.first_vpos;
13887 start_pos = it.current.pos;
13888 }
13889
13890 /* Find the first row that is not affected by changes at the end of
13891 the buffer. Value will be null if there is no unchanged row, in
13892 which case we must redisplay to the end of the window. delta
13893 will be set to the value by which buffer positions beginning with
13894 first_unchanged_at_end_row have to be adjusted due to text
13895 changes. */
13896 first_unchanged_at_end_row
13897 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13898 IF_DEBUG (debug_delta = delta);
13899 IF_DEBUG (debug_delta_bytes = delta_bytes);
13900
13901 /* Set stop_pos to the buffer position up to which we will have to
13902 display new lines. If first_unchanged_at_end_row != NULL, this
13903 is the buffer position of the start of the line displayed in that
13904 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13905 that we don't stop at a buffer position. */
13906 stop_pos = 0;
13907 if (first_unchanged_at_end_row)
13908 {
13909 xassert (last_unchanged_at_beg_row == NULL
13910 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13911
13912 /* If this is a continuation line, move forward to the next one
13913 that isn't. Changes in lines above affect this line.
13914 Caution: this may move first_unchanged_at_end_row to a row
13915 not displaying text. */
13916 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13917 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13918 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13919 < it.last_visible_y))
13920 ++first_unchanged_at_end_row;
13921
13922 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13923 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13924 >= it.last_visible_y))
13925 first_unchanged_at_end_row = NULL;
13926 else
13927 {
13928 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13929 + delta);
13930 first_unchanged_at_end_vpos
13931 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13932 xassert (stop_pos >= Z - END_UNCHANGED);
13933 }
13934 }
13935 else if (last_unchanged_at_beg_row == NULL)
13936 GIVE_UP (19);
13937
13938
13939 #if GLYPH_DEBUG
13940
13941 /* Either there is no unchanged row at the end, or the one we have
13942 now displays text. This is a necessary condition for the window
13943 end pos calculation at the end of this function. */
13944 xassert (first_unchanged_at_end_row == NULL
13945 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13946
13947 debug_last_unchanged_at_beg_vpos
13948 = (last_unchanged_at_beg_row
13949 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13950 : -1);
13951 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13952
13953 #endif /* GLYPH_DEBUG != 0 */
13954
13955
13956 /* Display new lines. Set last_text_row to the last new line
13957 displayed which has text on it, i.e. might end up as being the
13958 line where the window_end_vpos is. */
13959 w->cursor.vpos = -1;
13960 last_text_row = NULL;
13961 overlay_arrow_seen = 0;
13962 while (it.current_y < it.last_visible_y
13963 && !fonts_changed_p
13964 && (first_unchanged_at_end_row == NULL
13965 || IT_CHARPOS (it) < stop_pos))
13966 {
13967 if (display_line (&it))
13968 last_text_row = it.glyph_row - 1;
13969 }
13970
13971 if (fonts_changed_p)
13972 return -1;
13973
13974
13975 /* Compute differences in buffer positions, y-positions etc. for
13976 lines reused at the bottom of the window. Compute what we can
13977 scroll. */
13978 if (first_unchanged_at_end_row
13979 /* No lines reused because we displayed everything up to the
13980 bottom of the window. */
13981 && it.current_y < it.last_visible_y)
13982 {
13983 dvpos = (it.vpos
13984 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13985 current_matrix));
13986 dy = it.current_y - first_unchanged_at_end_row->y;
13987 run.current_y = first_unchanged_at_end_row->y;
13988 run.desired_y = run.current_y + dy;
13989 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13990 }
13991 else
13992 {
13993 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13994 first_unchanged_at_end_row = NULL;
13995 }
13996 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13997
13998
13999 /* Find the cursor if not already found. We have to decide whether
14000 PT will appear on this window (it sometimes doesn't, but this is
14001 not a very frequent case.) This decision has to be made before
14002 the current matrix is altered. A value of cursor.vpos < 0 means
14003 that PT is either in one of the lines beginning at
14004 first_unchanged_at_end_row or below the window. Don't care for
14005 lines that might be displayed later at the window end; as
14006 mentioned, this is not a frequent case. */
14007 if (w->cursor.vpos < 0)
14008 {
14009 /* Cursor in unchanged rows at the top? */
14010 if (PT < CHARPOS (start_pos)
14011 && last_unchanged_at_beg_row)
14012 {
14013 row = row_containing_pos (w, PT,
14014 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
14015 last_unchanged_at_beg_row + 1, 0);
14016 if (row)
14017 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
14018 }
14019
14020 /* Start from first_unchanged_at_end_row looking for PT. */
14021 else if (first_unchanged_at_end_row)
14022 {
14023 row = row_containing_pos (w, PT - delta,
14024 first_unchanged_at_end_row, NULL, 0);
14025 if (row)
14026 set_cursor_from_row (w, row, w->current_matrix, delta,
14027 delta_bytes, dy, dvpos);
14028 }
14029
14030 /* Give up if cursor was not found. */
14031 if (w->cursor.vpos < 0)
14032 {
14033 clear_glyph_matrix (w->desired_matrix);
14034 return -1;
14035 }
14036 }
14037
14038 /* Don't let the cursor end in the scroll margins. */
14039 {
14040 int this_scroll_margin, cursor_height;
14041
14042 this_scroll_margin = max (0, scroll_margin);
14043 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
14044 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
14045 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
14046
14047 if ((w->cursor.y < this_scroll_margin
14048 && CHARPOS (start) > BEGV)
14049 /* Old redisplay didn't take scroll margin into account at the bottom,
14050 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14051 || (w->cursor.y + (make_cursor_line_fully_visible_p
14052 ? cursor_height + this_scroll_margin
14053 : 1)) > it.last_visible_y)
14054 {
14055 w->cursor.vpos = -1;
14056 clear_glyph_matrix (w->desired_matrix);
14057 return -1;
14058 }
14059 }
14060
14061 /* Scroll the display. Do it before changing the current matrix so
14062 that xterm.c doesn't get confused about where the cursor glyph is
14063 found. */
14064 if (dy && run.height)
14065 {
14066 update_begin (f);
14067
14068 if (FRAME_WINDOW_P (f))
14069 {
14070 FRAME_RIF (f)->update_window_begin_hook (w);
14071 FRAME_RIF (f)->clear_window_mouse_face (w);
14072 FRAME_RIF (f)->scroll_run_hook (w, &run);
14073 FRAME_RIF (f)->update_window_end_hook (w, 0, 0);
14074 }
14075 else
14076 {
14077 /* Terminal frame. In this case, dvpos gives the number of
14078 lines to scroll by; dvpos < 0 means scroll up. */
14079 int first_unchanged_at_end_vpos
14080 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
14081 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
14082 int end = (WINDOW_TOP_EDGE_LINE (w)
14083 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
14084 + window_internal_height (w));
14085
14086 /* Perform the operation on the screen. */
14087 if (dvpos > 0)
14088 {
14089 /* Scroll last_unchanged_at_beg_row to the end of the
14090 window down dvpos lines. */
14091 set_terminal_window (f, end);
14092
14093 /* On dumb terminals delete dvpos lines at the end
14094 before inserting dvpos empty lines. */
14095 if (!FRAME_SCROLL_REGION_OK (f))
14096 ins_del_lines (f, end - dvpos, -dvpos);
14097
14098 /* Insert dvpos empty lines in front of
14099 last_unchanged_at_beg_row. */
14100 ins_del_lines (f, from, dvpos);
14101 }
14102 else if (dvpos < 0)
14103 {
14104 /* Scroll up last_unchanged_at_beg_vpos to the end of
14105 the window to last_unchanged_at_beg_vpos - |dvpos|. */
14106 set_terminal_window (f, end);
14107
14108 /* Delete dvpos lines in front of
14109 last_unchanged_at_beg_vpos. ins_del_lines will set
14110 the cursor to the given vpos and emit |dvpos| delete
14111 line sequences. */
14112 ins_del_lines (f, from + dvpos, dvpos);
14113
14114 /* On a dumb terminal insert dvpos empty lines at the
14115 end. */
14116 if (!FRAME_SCROLL_REGION_OK (f))
14117 ins_del_lines (f, end + dvpos, -dvpos);
14118 }
14119
14120 set_terminal_window (f, 0);
14121 }
14122
14123 update_end (f);
14124 }
14125
14126 /* Shift reused rows of the current matrix to the right position.
14127 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
14128 text. */
14129 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14130 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
14131 if (dvpos < 0)
14132 {
14133 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
14134 bottom_vpos, dvpos);
14135 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
14136 bottom_vpos, 0);
14137 }
14138 else if (dvpos > 0)
14139 {
14140 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
14141 bottom_vpos, dvpos);
14142 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
14143 first_unchanged_at_end_vpos + dvpos, 0);
14144 }
14145
14146 /* For frame-based redisplay, make sure that current frame and window
14147 matrix are in sync with respect to glyph memory. */
14148 if (!FRAME_WINDOW_P (f))
14149 sync_frame_with_window_matrix_rows (w);
14150
14151 /* Adjust buffer positions in reused rows. */
14152 if (delta)
14153 increment_matrix_positions (current_matrix,
14154 first_unchanged_at_end_vpos + dvpos,
14155 bottom_vpos, delta, delta_bytes);
14156
14157 /* Adjust Y positions. */
14158 if (dy)
14159 shift_glyph_matrix (w, current_matrix,
14160 first_unchanged_at_end_vpos + dvpos,
14161 bottom_vpos, dy);
14162
14163 if (first_unchanged_at_end_row)
14164 {
14165 first_unchanged_at_end_row += dvpos;
14166 if (first_unchanged_at_end_row->y >= it.last_visible_y
14167 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
14168 first_unchanged_at_end_row = NULL;
14169 }
14170
14171 /* If scrolling up, there may be some lines to display at the end of
14172 the window. */
14173 last_text_row_at_end = NULL;
14174 if (dy < 0)
14175 {
14176 /* Scrolling up can leave for example a partially visible line
14177 at the end of the window to be redisplayed. */
14178 /* Set last_row to the glyph row in the current matrix where the
14179 window end line is found. It has been moved up or down in
14180 the matrix by dvpos. */
14181 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
14182 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
14183
14184 /* If last_row is the window end line, it should display text. */
14185 xassert (last_row->displays_text_p);
14186
14187 /* If window end line was partially visible before, begin
14188 displaying at that line. Otherwise begin displaying with the
14189 line following it. */
14190 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
14191 {
14192 init_to_row_start (&it, w, last_row);
14193 it.vpos = last_vpos;
14194 it.current_y = last_row->y;
14195 }
14196 else
14197 {
14198 init_to_row_end (&it, w, last_row);
14199 it.vpos = 1 + last_vpos;
14200 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
14201 ++last_row;
14202 }
14203
14204 /* We may start in a continuation line. If so, we have to
14205 get the right continuation_lines_width and current_x. */
14206 it.continuation_lines_width = last_row->continuation_lines_width;
14207 it.hpos = it.current_x = 0;
14208
14209 /* Display the rest of the lines at the window end. */
14210 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14211 while (it.current_y < it.last_visible_y
14212 && !fonts_changed_p)
14213 {
14214 /* Is it always sure that the display agrees with lines in
14215 the current matrix? I don't think so, so we mark rows
14216 displayed invalid in the current matrix by setting their
14217 enabled_p flag to zero. */
14218 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
14219 if (display_line (&it))
14220 last_text_row_at_end = it.glyph_row - 1;
14221 }
14222 }
14223
14224 /* Update window_end_pos and window_end_vpos. */
14225 if (first_unchanged_at_end_row
14226 && !last_text_row_at_end)
14227 {
14228 /* Window end line if one of the preserved rows from the current
14229 matrix. Set row to the last row displaying text in current
14230 matrix starting at first_unchanged_at_end_row, after
14231 scrolling. */
14232 xassert (first_unchanged_at_end_row->displays_text_p);
14233 row = find_last_row_displaying_text (w->current_matrix, &it,
14234 first_unchanged_at_end_row);
14235 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
14236
14237 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14238 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14239 w->window_end_vpos
14240 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
14241 xassert (w->window_end_bytepos >= 0);
14242 IF_DEBUG (debug_method_add (w, "A"));
14243 }
14244 else if (last_text_row_at_end)
14245 {
14246 w->window_end_pos
14247 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
14248 w->window_end_bytepos
14249 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
14250 w->window_end_vpos
14251 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
14252 xassert (w->window_end_bytepos >= 0);
14253 IF_DEBUG (debug_method_add (w, "B"));
14254 }
14255 else if (last_text_row)
14256 {
14257 /* We have displayed either to the end of the window or at the
14258 end of the window, i.e. the last row with text is to be found
14259 in the desired matrix. */
14260 w->window_end_pos
14261 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14262 w->window_end_bytepos
14263 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14264 w->window_end_vpos
14265 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
14266 xassert (w->window_end_bytepos >= 0);
14267 }
14268 else if (first_unchanged_at_end_row == NULL
14269 && last_text_row == NULL
14270 && last_text_row_at_end == NULL)
14271 {
14272 /* Displayed to end of window, but no line containing text was
14273 displayed. Lines were deleted at the end of the window. */
14274 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
14275 int vpos = XFASTINT (w->window_end_vpos);
14276 struct glyph_row *current_row = current_matrix->rows + vpos;
14277 struct glyph_row *desired_row = desired_matrix->rows + vpos;
14278
14279 for (row = NULL;
14280 row == NULL && vpos >= first_vpos;
14281 --vpos, --current_row, --desired_row)
14282 {
14283 if (desired_row->enabled_p)
14284 {
14285 if (desired_row->displays_text_p)
14286 row = desired_row;
14287 }
14288 else if (current_row->displays_text_p)
14289 row = current_row;
14290 }
14291
14292 xassert (row != NULL);
14293 w->window_end_vpos = make_number (vpos + 1);
14294 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14295 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14296 xassert (w->window_end_bytepos >= 0);
14297 IF_DEBUG (debug_method_add (w, "C"));
14298 }
14299 else
14300 abort ();
14301
14302 #if 0 /* This leads to problems, for instance when the cursor is
14303 at ZV, and the cursor line displays no text. */
14304 /* Disable rows below what's displayed in the window. This makes
14305 debugging easier. */
14306 enable_glyph_matrix_rows (current_matrix,
14307 XFASTINT (w->window_end_vpos) + 1,
14308 bottom_vpos, 0);
14309 #endif
14310
14311 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
14312 debug_end_vpos = XFASTINT (w->window_end_vpos));
14313
14314 /* Record that display has not been completed. */
14315 w->window_end_valid = Qnil;
14316 w->desired_matrix->no_scrolling_p = 1;
14317 return 3;
14318
14319 #undef GIVE_UP
14320 }
14321
14322
14323 \f
14324 /***********************************************************************
14325 More debugging support
14326 ***********************************************************************/
14327
14328 #if GLYPH_DEBUG
14329
14330 void dump_glyph_row P_ ((struct glyph_row *, int, int));
14331 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
14332 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
14333
14334
14335 /* Dump the contents of glyph matrix MATRIX on stderr.
14336
14337 GLYPHS 0 means don't show glyph contents.
14338 GLYPHS 1 means show glyphs in short form
14339 GLYPHS > 1 means show glyphs in long form. */
14340
14341 void
14342 dump_glyph_matrix (matrix, glyphs)
14343 struct glyph_matrix *matrix;
14344 int glyphs;
14345 {
14346 int i;
14347 for (i = 0; i < matrix->nrows; ++i)
14348 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
14349 }
14350
14351
14352 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14353 the glyph row and area where the glyph comes from. */
14354
14355 void
14356 dump_glyph (row, glyph, area)
14357 struct glyph_row *row;
14358 struct glyph *glyph;
14359 int area;
14360 {
14361 if (glyph->type == CHAR_GLYPH)
14362 {
14363 fprintf (stderr,
14364 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14365 glyph - row->glyphs[TEXT_AREA],
14366 'C',
14367 glyph->charpos,
14368 (BUFFERP (glyph->object)
14369 ? 'B'
14370 : (STRINGP (glyph->object)
14371 ? 'S'
14372 : '-')),
14373 glyph->pixel_width,
14374 glyph->u.ch,
14375 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
14376 ? glyph->u.ch
14377 : '.'),
14378 glyph->face_id,
14379 glyph->left_box_line_p,
14380 glyph->right_box_line_p);
14381 }
14382 else if (glyph->type == STRETCH_GLYPH)
14383 {
14384 fprintf (stderr,
14385 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14386 glyph - row->glyphs[TEXT_AREA],
14387 'S',
14388 glyph->charpos,
14389 (BUFFERP (glyph->object)
14390 ? 'B'
14391 : (STRINGP (glyph->object)
14392 ? 'S'
14393 : '-')),
14394 glyph->pixel_width,
14395 0,
14396 '.',
14397 glyph->face_id,
14398 glyph->left_box_line_p,
14399 glyph->right_box_line_p);
14400 }
14401 else if (glyph->type == IMAGE_GLYPH)
14402 {
14403 fprintf (stderr,
14404 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14405 glyph - row->glyphs[TEXT_AREA],
14406 'I',
14407 glyph->charpos,
14408 (BUFFERP (glyph->object)
14409 ? 'B'
14410 : (STRINGP (glyph->object)
14411 ? 'S'
14412 : '-')),
14413 glyph->pixel_width,
14414 glyph->u.img_id,
14415 '.',
14416 glyph->face_id,
14417 glyph->left_box_line_p,
14418 glyph->right_box_line_p);
14419 }
14420 }
14421
14422
14423 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14424 GLYPHS 0 means don't show glyph contents.
14425 GLYPHS 1 means show glyphs in short form
14426 GLYPHS > 1 means show glyphs in long form. */
14427
14428 void
14429 dump_glyph_row (row, vpos, glyphs)
14430 struct glyph_row *row;
14431 int vpos, glyphs;
14432 {
14433 if (glyphs != 1)
14434 {
14435 fprintf (stderr, "Row Start End Used oEI><\\CTZFesm X Y W H V A P\n");
14436 fprintf (stderr, "======================================================================\n");
14437
14438 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
14439 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14440 vpos,
14441 MATRIX_ROW_START_CHARPOS (row),
14442 MATRIX_ROW_END_CHARPOS (row),
14443 row->used[TEXT_AREA],
14444 row->contains_overlapping_glyphs_p,
14445 row->enabled_p,
14446 row->truncated_on_left_p,
14447 row->truncated_on_right_p,
14448 row->continued_p,
14449 MATRIX_ROW_CONTINUATION_LINE_P (row),
14450 row->displays_text_p,
14451 row->ends_at_zv_p,
14452 row->fill_line_p,
14453 row->ends_in_middle_of_char_p,
14454 row->starts_in_middle_of_char_p,
14455 row->mouse_face_p,
14456 row->x,
14457 row->y,
14458 row->pixel_width,
14459 row->height,
14460 row->visible_height,
14461 row->ascent,
14462 row->phys_ascent);
14463 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14464 row->end.overlay_string_index,
14465 row->continuation_lines_width);
14466 fprintf (stderr, "%9d %5d\n",
14467 CHARPOS (row->start.string_pos),
14468 CHARPOS (row->end.string_pos));
14469 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14470 row->end.dpvec_index);
14471 }
14472
14473 if (glyphs > 1)
14474 {
14475 int area;
14476
14477 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14478 {
14479 struct glyph *glyph = row->glyphs[area];
14480 struct glyph *glyph_end = glyph + row->used[area];
14481
14482 /* Glyph for a line end in text. */
14483 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14484 ++glyph_end;
14485
14486 if (glyph < glyph_end)
14487 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14488
14489 for (; glyph < glyph_end; ++glyph)
14490 dump_glyph (row, glyph, area);
14491 }
14492 }
14493 else if (glyphs == 1)
14494 {
14495 int area;
14496
14497 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14498 {
14499 char *s = (char *) alloca (row->used[area] + 1);
14500 int i;
14501
14502 for (i = 0; i < row->used[area]; ++i)
14503 {
14504 struct glyph *glyph = row->glyphs[area] + i;
14505 if (glyph->type == CHAR_GLYPH
14506 && glyph->u.ch < 0x80
14507 && glyph->u.ch >= ' ')
14508 s[i] = glyph->u.ch;
14509 else
14510 s[i] = '.';
14511 }
14512
14513 s[i] = '\0';
14514 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14515 }
14516 }
14517 }
14518
14519
14520 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14521 Sdump_glyph_matrix, 0, 1, "p",
14522 doc: /* Dump the current matrix of the selected window to stderr.
14523 Shows contents of glyph row structures. With non-nil
14524 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14525 glyphs in short form, otherwise show glyphs in long form. */)
14526 (glyphs)
14527 Lisp_Object glyphs;
14528 {
14529 struct window *w = XWINDOW (selected_window);
14530 struct buffer *buffer = XBUFFER (w->buffer);
14531
14532 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14533 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14534 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14535 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14536 fprintf (stderr, "=============================================\n");
14537 dump_glyph_matrix (w->current_matrix,
14538 NILP (glyphs) ? 0 : XINT (glyphs));
14539 return Qnil;
14540 }
14541
14542
14543 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14544 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14545 ()
14546 {
14547 struct frame *f = XFRAME (selected_frame);
14548 dump_glyph_matrix (f->current_matrix, 1);
14549 return Qnil;
14550 }
14551
14552
14553 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14554 doc: /* Dump glyph row ROW to stderr.
14555 GLYPH 0 means don't dump glyphs.
14556 GLYPH 1 means dump glyphs in short form.
14557 GLYPH > 1 or omitted means dump glyphs in long form. */)
14558 (row, glyphs)
14559 Lisp_Object row, glyphs;
14560 {
14561 struct glyph_matrix *matrix;
14562 int vpos;
14563
14564 CHECK_NUMBER (row);
14565 matrix = XWINDOW (selected_window)->current_matrix;
14566 vpos = XINT (row);
14567 if (vpos >= 0 && vpos < matrix->nrows)
14568 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14569 vpos,
14570 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14571 return Qnil;
14572 }
14573
14574
14575 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14576 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14577 GLYPH 0 means don't dump glyphs.
14578 GLYPH 1 means dump glyphs in short form.
14579 GLYPH > 1 or omitted means dump glyphs in long form. */)
14580 (row, glyphs)
14581 Lisp_Object row, glyphs;
14582 {
14583 struct frame *sf = SELECTED_FRAME ();
14584 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14585 int vpos;
14586
14587 CHECK_NUMBER (row);
14588 vpos = XINT (row);
14589 if (vpos >= 0 && vpos < m->nrows)
14590 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14591 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14592 return Qnil;
14593 }
14594
14595
14596 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14597 doc: /* Toggle tracing of redisplay.
14598 With ARG, turn tracing on if and only if ARG is positive. */)
14599 (arg)
14600 Lisp_Object arg;
14601 {
14602 if (NILP (arg))
14603 trace_redisplay_p = !trace_redisplay_p;
14604 else
14605 {
14606 arg = Fprefix_numeric_value (arg);
14607 trace_redisplay_p = XINT (arg) > 0;
14608 }
14609
14610 return Qnil;
14611 }
14612
14613
14614 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14615 doc: /* Like `format', but print result to stderr.
14616 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14617 (nargs, args)
14618 int nargs;
14619 Lisp_Object *args;
14620 {
14621 Lisp_Object s = Fformat (nargs, args);
14622 fprintf (stderr, "%s", SDATA (s));
14623 return Qnil;
14624 }
14625
14626 #endif /* GLYPH_DEBUG */
14627
14628
14629 \f
14630 /***********************************************************************
14631 Building Desired Matrix Rows
14632 ***********************************************************************/
14633
14634 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14635 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14636
14637 static struct glyph_row *
14638 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14639 struct window *w;
14640 Lisp_Object overlay_arrow_string;
14641 {
14642 struct frame *f = XFRAME (WINDOW_FRAME (w));
14643 struct buffer *buffer = XBUFFER (w->buffer);
14644 struct buffer *old = current_buffer;
14645 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14646 int arrow_len = SCHARS (overlay_arrow_string);
14647 const unsigned char *arrow_end = arrow_string + arrow_len;
14648 const unsigned char *p;
14649 struct it it;
14650 int multibyte_p;
14651 int n_glyphs_before;
14652
14653 set_buffer_temp (buffer);
14654 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14655 it.glyph_row->used[TEXT_AREA] = 0;
14656 SET_TEXT_POS (it.position, 0, 0);
14657
14658 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14659 p = arrow_string;
14660 while (p < arrow_end)
14661 {
14662 Lisp_Object face, ilisp;
14663
14664 /* Get the next character. */
14665 if (multibyte_p)
14666 it.c = string_char_and_length (p, arrow_len, &it.len);
14667 else
14668 it.c = *p, it.len = 1;
14669 p += it.len;
14670
14671 /* Get its face. */
14672 ilisp = make_number (p - arrow_string);
14673 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14674 it.face_id = compute_char_face (f, it.c, face);
14675
14676 /* Compute its width, get its glyphs. */
14677 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14678 SET_TEXT_POS (it.position, -1, -1);
14679 PRODUCE_GLYPHS (&it);
14680
14681 /* If this character doesn't fit any more in the line, we have
14682 to remove some glyphs. */
14683 if (it.current_x > it.last_visible_x)
14684 {
14685 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14686 break;
14687 }
14688 }
14689
14690 set_buffer_temp (old);
14691 return it.glyph_row;
14692 }
14693
14694
14695 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14696 glyphs are only inserted for terminal frames since we can't really
14697 win with truncation glyphs when partially visible glyphs are
14698 involved. Which glyphs to insert is determined by
14699 produce_special_glyphs. */
14700
14701 static void
14702 insert_left_trunc_glyphs (it)
14703 struct it *it;
14704 {
14705 struct it truncate_it;
14706 struct glyph *from, *end, *to, *toend;
14707
14708 xassert (!FRAME_WINDOW_P (it->f));
14709
14710 /* Get the truncation glyphs. */
14711 truncate_it = *it;
14712 truncate_it.current_x = 0;
14713 truncate_it.face_id = DEFAULT_FACE_ID;
14714 truncate_it.glyph_row = &scratch_glyph_row;
14715 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14716 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14717 truncate_it.object = make_number (0);
14718 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14719
14720 /* Overwrite glyphs from IT with truncation glyphs. */
14721 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14722 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14723 to = it->glyph_row->glyphs[TEXT_AREA];
14724 toend = to + it->glyph_row->used[TEXT_AREA];
14725
14726 while (from < end)
14727 *to++ = *from++;
14728
14729 /* There may be padding glyphs left over. Overwrite them too. */
14730 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14731 {
14732 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14733 while (from < end)
14734 *to++ = *from++;
14735 }
14736
14737 if (to > toend)
14738 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14739 }
14740
14741
14742 /* Compute the pixel height and width of IT->glyph_row.
14743
14744 Most of the time, ascent and height of a display line will be equal
14745 to the max_ascent and max_height values of the display iterator
14746 structure. This is not the case if
14747
14748 1. We hit ZV without displaying anything. In this case, max_ascent
14749 and max_height will be zero.
14750
14751 2. We have some glyphs that don't contribute to the line height.
14752 (The glyph row flag contributes_to_line_height_p is for future
14753 pixmap extensions).
14754
14755 The first case is easily covered by using default values because in
14756 these cases, the line height does not really matter, except that it
14757 must not be zero. */
14758
14759 static void
14760 compute_line_metrics (it)
14761 struct it *it;
14762 {
14763 struct glyph_row *row = it->glyph_row;
14764 int area, i;
14765
14766 if (FRAME_WINDOW_P (it->f))
14767 {
14768 int i, min_y, max_y;
14769
14770 /* The line may consist of one space only, that was added to
14771 place the cursor on it. If so, the row's height hasn't been
14772 computed yet. */
14773 if (row->height == 0)
14774 {
14775 if (it->max_ascent + it->max_descent == 0)
14776 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14777 row->ascent = it->max_ascent;
14778 row->height = it->max_ascent + it->max_descent;
14779 row->phys_ascent = it->max_phys_ascent;
14780 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14781 row->extra_line_spacing = it->max_extra_line_spacing;
14782 }
14783
14784 /* Compute the width of this line. */
14785 row->pixel_width = row->x;
14786 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14787 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14788
14789 xassert (row->pixel_width >= 0);
14790 xassert (row->ascent >= 0 && row->height > 0);
14791
14792 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14793 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14794
14795 /* If first line's physical ascent is larger than its logical
14796 ascent, use the physical ascent, and make the row taller.
14797 This makes accented characters fully visible. */
14798 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14799 && row->phys_ascent > row->ascent)
14800 {
14801 row->height += row->phys_ascent - row->ascent;
14802 row->ascent = row->phys_ascent;
14803 }
14804
14805 /* Compute how much of the line is visible. */
14806 row->visible_height = row->height;
14807
14808 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14809 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14810
14811 if (row->y < min_y)
14812 row->visible_height -= min_y - row->y;
14813 if (row->y + row->height > max_y)
14814 row->visible_height -= row->y + row->height - max_y;
14815 }
14816 else
14817 {
14818 row->pixel_width = row->used[TEXT_AREA];
14819 if (row->continued_p)
14820 row->pixel_width -= it->continuation_pixel_width;
14821 else if (row->truncated_on_right_p)
14822 row->pixel_width -= it->truncation_pixel_width;
14823 row->ascent = row->phys_ascent = 0;
14824 row->height = row->phys_height = row->visible_height = 1;
14825 row->extra_line_spacing = 0;
14826 }
14827
14828 /* Compute a hash code for this row. */
14829 row->hash = 0;
14830 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14831 for (i = 0; i < row->used[area]; ++i)
14832 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14833 + row->glyphs[area][i].u.val
14834 + row->glyphs[area][i].face_id
14835 + row->glyphs[area][i].padding_p
14836 + (row->glyphs[area][i].type << 2));
14837
14838 it->max_ascent = it->max_descent = 0;
14839 it->max_phys_ascent = it->max_phys_descent = 0;
14840 }
14841
14842
14843 /* Append one space to the glyph row of iterator IT if doing a
14844 window-based redisplay. The space has the same face as
14845 IT->face_id. Value is non-zero if a space was added.
14846
14847 This function is called to make sure that there is always one glyph
14848 at the end of a glyph row that the cursor can be set on under
14849 window-systems. (If there weren't such a glyph we would not know
14850 how wide and tall a box cursor should be displayed).
14851
14852 At the same time this space let's a nicely handle clearing to the
14853 end of the line if the row ends in italic text. */
14854
14855 static int
14856 append_space_for_newline (it, default_face_p)
14857 struct it *it;
14858 int default_face_p;
14859 {
14860 if (FRAME_WINDOW_P (it->f))
14861 {
14862 int n = it->glyph_row->used[TEXT_AREA];
14863
14864 if (it->glyph_row->glyphs[TEXT_AREA] + n
14865 < it->glyph_row->glyphs[1 + TEXT_AREA])
14866 {
14867 /* Save some values that must not be changed.
14868 Must save IT->c and IT->len because otherwise
14869 ITERATOR_AT_END_P wouldn't work anymore after
14870 append_space_for_newline has been called. */
14871 enum display_element_type saved_what = it->what;
14872 int saved_c = it->c, saved_len = it->len;
14873 int saved_x = it->current_x;
14874 int saved_face_id = it->face_id;
14875 struct text_pos saved_pos;
14876 Lisp_Object saved_object;
14877 struct face *face;
14878
14879 saved_object = it->object;
14880 saved_pos = it->position;
14881
14882 it->what = IT_CHARACTER;
14883 bzero (&it->position, sizeof it->position);
14884 it->object = make_number (0);
14885 it->c = ' ';
14886 it->len = 1;
14887
14888 if (default_face_p)
14889 it->face_id = DEFAULT_FACE_ID;
14890 else if (it->face_before_selective_p)
14891 it->face_id = it->saved_face_id;
14892 face = FACE_FROM_ID (it->f, it->face_id);
14893 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14894
14895 PRODUCE_GLYPHS (it);
14896
14897 it->override_ascent = -1;
14898 it->constrain_row_ascent_descent_p = 0;
14899 it->current_x = saved_x;
14900 it->object = saved_object;
14901 it->position = saved_pos;
14902 it->what = saved_what;
14903 it->face_id = saved_face_id;
14904 it->len = saved_len;
14905 it->c = saved_c;
14906 return 1;
14907 }
14908 }
14909
14910 return 0;
14911 }
14912
14913
14914 /* Extend the face of the last glyph in the text area of IT->glyph_row
14915 to the end of the display line. Called from display_line.
14916 If the glyph row is empty, add a space glyph to it so that we
14917 know the face to draw. Set the glyph row flag fill_line_p. */
14918
14919 static void
14920 extend_face_to_end_of_line (it)
14921 struct it *it;
14922 {
14923 struct face *face;
14924 struct frame *f = it->f;
14925
14926 /* If line is already filled, do nothing. */
14927 if (it->current_x >= it->last_visible_x)
14928 return;
14929
14930 /* Face extension extends the background and box of IT->face_id
14931 to the end of the line. If the background equals the background
14932 of the frame, we don't have to do anything. */
14933 if (it->face_before_selective_p)
14934 face = FACE_FROM_ID (it->f, it->saved_face_id);
14935 else
14936 face = FACE_FROM_ID (f, it->face_id);
14937
14938 if (FRAME_WINDOW_P (f)
14939 && face->box == FACE_NO_BOX
14940 && face->background == FRAME_BACKGROUND_PIXEL (f)
14941 && !face->stipple)
14942 return;
14943
14944 /* Set the glyph row flag indicating that the face of the last glyph
14945 in the text area has to be drawn to the end of the text area. */
14946 it->glyph_row->fill_line_p = 1;
14947
14948 /* If current character of IT is not ASCII, make sure we have the
14949 ASCII face. This will be automatically undone the next time
14950 get_next_display_element returns a multibyte character. Note
14951 that the character will always be single byte in unibyte text. */
14952 if (!SINGLE_BYTE_CHAR_P (it->c))
14953 {
14954 it->face_id = FACE_FOR_CHAR (f, face, 0);
14955 }
14956
14957 if (FRAME_WINDOW_P (f))
14958 {
14959 /* If the row is empty, add a space with the current face of IT,
14960 so that we know which face to draw. */
14961 if (it->glyph_row->used[TEXT_AREA] == 0)
14962 {
14963 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14964 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14965 it->glyph_row->used[TEXT_AREA] = 1;
14966 }
14967 }
14968 else
14969 {
14970 /* Save some values that must not be changed. */
14971 int saved_x = it->current_x;
14972 struct text_pos saved_pos;
14973 Lisp_Object saved_object;
14974 enum display_element_type saved_what = it->what;
14975 int saved_face_id = it->face_id;
14976
14977 saved_object = it->object;
14978 saved_pos = it->position;
14979
14980 it->what = IT_CHARACTER;
14981 bzero (&it->position, sizeof it->position);
14982 it->object = make_number (0);
14983 it->c = ' ';
14984 it->len = 1;
14985 it->face_id = face->id;
14986
14987 PRODUCE_GLYPHS (it);
14988
14989 while (it->current_x <= it->last_visible_x)
14990 PRODUCE_GLYPHS (it);
14991
14992 /* Don't count these blanks really. It would let us insert a left
14993 truncation glyph below and make us set the cursor on them, maybe. */
14994 it->current_x = saved_x;
14995 it->object = saved_object;
14996 it->position = saved_pos;
14997 it->what = saved_what;
14998 it->face_id = saved_face_id;
14999 }
15000 }
15001
15002
15003 /* Value is non-zero if text starting at CHARPOS in current_buffer is
15004 trailing whitespace. */
15005
15006 static int
15007 trailing_whitespace_p (charpos)
15008 int charpos;
15009 {
15010 int bytepos = CHAR_TO_BYTE (charpos);
15011 int c = 0;
15012
15013 while (bytepos < ZV_BYTE
15014 && (c = FETCH_CHAR (bytepos),
15015 c == ' ' || c == '\t'))
15016 ++bytepos;
15017
15018 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
15019 {
15020 if (bytepos != PT_BYTE)
15021 return 1;
15022 }
15023 return 0;
15024 }
15025
15026
15027 /* Highlight trailing whitespace, if any, in ROW. */
15028
15029 void
15030 highlight_trailing_whitespace (f, row)
15031 struct frame *f;
15032 struct glyph_row *row;
15033 {
15034 int used = row->used[TEXT_AREA];
15035
15036 if (used)
15037 {
15038 struct glyph *start = row->glyphs[TEXT_AREA];
15039 struct glyph *glyph = start + used - 1;
15040
15041 /* Skip over glyphs inserted to display the cursor at the
15042 end of a line, for extending the face of the last glyph
15043 to the end of the line on terminals, and for truncation
15044 and continuation glyphs. */
15045 while (glyph >= start
15046 && glyph->type == CHAR_GLYPH
15047 && INTEGERP (glyph->object))
15048 --glyph;
15049
15050 /* If last glyph is a space or stretch, and it's trailing
15051 whitespace, set the face of all trailing whitespace glyphs in
15052 IT->glyph_row to `trailing-whitespace'. */
15053 if (glyph >= start
15054 && BUFFERP (glyph->object)
15055 && (glyph->type == STRETCH_GLYPH
15056 || (glyph->type == CHAR_GLYPH
15057 && glyph->u.ch == ' '))
15058 && trailing_whitespace_p (glyph->charpos))
15059 {
15060 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
15061 if (face_id < 0)
15062 return;
15063
15064 while (glyph >= start
15065 && BUFFERP (glyph->object)
15066 && (glyph->type == STRETCH_GLYPH
15067 || (glyph->type == CHAR_GLYPH
15068 && glyph->u.ch == ' ')))
15069 (glyph--)->face_id = face_id;
15070 }
15071 }
15072 }
15073
15074
15075 /* Value is non-zero if glyph row ROW in window W should be
15076 used to hold the cursor. */
15077
15078 static int
15079 cursor_row_p (w, row)
15080 struct window *w;
15081 struct glyph_row *row;
15082 {
15083 int cursor_row_p = 1;
15084
15085 if (PT == MATRIX_ROW_END_CHARPOS (row))
15086 {
15087 /* If the row ends with a newline from a string, we don't want
15088 the cursor there, but we still want it at the start of the
15089 string if the string starts in this row.
15090 If the row is continued it doesn't end in a newline. */
15091 if (CHARPOS (row->end.string_pos) >= 0)
15092 cursor_row_p = (row->continued_p
15093 || PT >= MATRIX_ROW_START_CHARPOS (row));
15094 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15095 {
15096 /* If the row ends in middle of a real character,
15097 and the line is continued, we want the cursor here.
15098 That's because MATRIX_ROW_END_CHARPOS would equal
15099 PT if PT is before the character. */
15100 if (!row->ends_in_ellipsis_p)
15101 cursor_row_p = row->continued_p;
15102 else
15103 /* If the row ends in an ellipsis, then
15104 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
15105 We want that position to be displayed after the ellipsis. */
15106 cursor_row_p = 0;
15107 }
15108 /* If the row ends at ZV, display the cursor at the end of that
15109 row instead of at the start of the row below. */
15110 else if (row->ends_at_zv_p)
15111 cursor_row_p = 1;
15112 else
15113 cursor_row_p = 0;
15114 }
15115
15116 return cursor_row_p;
15117 }
15118
15119
15120 /* Construct the glyph row IT->glyph_row in the desired matrix of
15121 IT->w from text at the current position of IT. See dispextern.h
15122 for an overview of struct it. Value is non-zero if
15123 IT->glyph_row displays text, as opposed to a line displaying ZV
15124 only. */
15125
15126 static int
15127 display_line (it)
15128 struct it *it;
15129 {
15130 struct glyph_row *row = it->glyph_row;
15131 Lisp_Object overlay_arrow_string;
15132
15133 /* We always start displaying at hpos zero even if hscrolled. */
15134 xassert (it->hpos == 0 && it->current_x == 0);
15135
15136 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
15137 >= it->w->desired_matrix->nrows)
15138 {
15139 it->w->nrows_scale_factor++;
15140 fonts_changed_p = 1;
15141 return 0;
15142 }
15143
15144 /* Is IT->w showing the region? */
15145 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
15146
15147 /* Clear the result glyph row and enable it. */
15148 prepare_desired_row (row);
15149
15150 row->y = it->current_y;
15151 row->start = it->start;
15152 row->continuation_lines_width = it->continuation_lines_width;
15153 row->displays_text_p = 1;
15154 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
15155 it->starts_in_middle_of_char_p = 0;
15156
15157 /* Arrange the overlays nicely for our purposes. Usually, we call
15158 display_line on only one line at a time, in which case this
15159 can't really hurt too much, or we call it on lines which appear
15160 one after another in the buffer, in which case all calls to
15161 recenter_overlay_lists but the first will be pretty cheap. */
15162 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
15163
15164 /* Move over display elements that are not visible because we are
15165 hscrolled. This may stop at an x-position < IT->first_visible_x
15166 if the first glyph is partially visible or if we hit a line end. */
15167 if (it->current_x < it->first_visible_x)
15168 {
15169 move_it_in_display_line_to (it, ZV, it->first_visible_x,
15170 MOVE_TO_POS | MOVE_TO_X);
15171 }
15172
15173 /* Get the initial row height. This is either the height of the
15174 text hscrolled, if there is any, or zero. */
15175 row->ascent = it->max_ascent;
15176 row->height = it->max_ascent + it->max_descent;
15177 row->phys_ascent = it->max_phys_ascent;
15178 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15179 row->extra_line_spacing = it->max_extra_line_spacing;
15180
15181 /* Loop generating characters. The loop is left with IT on the next
15182 character to display. */
15183 while (1)
15184 {
15185 int n_glyphs_before, hpos_before, x_before;
15186 int x, i, nglyphs;
15187 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
15188
15189 /* Retrieve the next thing to display. Value is zero if end of
15190 buffer reached. */
15191 if (!get_next_display_element (it))
15192 {
15193 /* Maybe add a space at the end of this line that is used to
15194 display the cursor there under X. Set the charpos of the
15195 first glyph of blank lines not corresponding to any text
15196 to -1. */
15197 #ifdef HAVE_WINDOW_SYSTEM
15198 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15199 row->exact_window_width_line_p = 1;
15200 else
15201 #endif /* HAVE_WINDOW_SYSTEM */
15202 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
15203 || row->used[TEXT_AREA] == 0)
15204 {
15205 row->glyphs[TEXT_AREA]->charpos = -1;
15206 row->displays_text_p = 0;
15207
15208 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
15209 && (!MINI_WINDOW_P (it->w)
15210 || (minibuf_level && EQ (it->window, minibuf_window))))
15211 row->indicate_empty_line_p = 1;
15212 }
15213
15214 it->continuation_lines_width = 0;
15215 row->ends_at_zv_p = 1;
15216 break;
15217 }
15218
15219 /* Now, get the metrics of what we want to display. This also
15220 generates glyphs in `row' (which is IT->glyph_row). */
15221 n_glyphs_before = row->used[TEXT_AREA];
15222 x = it->current_x;
15223
15224 /* Remember the line height so far in case the next element doesn't
15225 fit on the line. */
15226 if (!it->truncate_lines_p)
15227 {
15228 ascent = it->max_ascent;
15229 descent = it->max_descent;
15230 phys_ascent = it->max_phys_ascent;
15231 phys_descent = it->max_phys_descent;
15232 }
15233
15234 PRODUCE_GLYPHS (it);
15235
15236 /* If this display element was in marginal areas, continue with
15237 the next one. */
15238 if (it->area != TEXT_AREA)
15239 {
15240 row->ascent = max (row->ascent, it->max_ascent);
15241 row->height = max (row->height, it->max_ascent + it->max_descent);
15242 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15243 row->phys_height = max (row->phys_height,
15244 it->max_phys_ascent + it->max_phys_descent);
15245 row->extra_line_spacing = max (row->extra_line_spacing,
15246 it->max_extra_line_spacing);
15247 set_iterator_to_next (it, 1);
15248 continue;
15249 }
15250
15251 /* Does the display element fit on the line? If we truncate
15252 lines, we should draw past the right edge of the window. If
15253 we don't truncate, we want to stop so that we can display the
15254 continuation glyph before the right margin. If lines are
15255 continued, there are two possible strategies for characters
15256 resulting in more than 1 glyph (e.g. tabs): Display as many
15257 glyphs as possible in this line and leave the rest for the
15258 continuation line, or display the whole element in the next
15259 line. Original redisplay did the former, so we do it also. */
15260 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
15261 hpos_before = it->hpos;
15262 x_before = x;
15263
15264 if (/* Not a newline. */
15265 nglyphs > 0
15266 /* Glyphs produced fit entirely in the line. */
15267 && it->current_x < it->last_visible_x)
15268 {
15269 it->hpos += nglyphs;
15270 row->ascent = max (row->ascent, it->max_ascent);
15271 row->height = max (row->height, it->max_ascent + it->max_descent);
15272 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15273 row->phys_height = max (row->phys_height,
15274 it->max_phys_ascent + it->max_phys_descent);
15275 row->extra_line_spacing = max (row->extra_line_spacing,
15276 it->max_extra_line_spacing);
15277 if (it->current_x - it->pixel_width < it->first_visible_x)
15278 row->x = x - it->first_visible_x;
15279 }
15280 else
15281 {
15282 int new_x;
15283 struct glyph *glyph;
15284
15285 for (i = 0; i < nglyphs; ++i, x = new_x)
15286 {
15287 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
15288 new_x = x + glyph->pixel_width;
15289
15290 if (/* Lines are continued. */
15291 !it->truncate_lines_p
15292 && (/* Glyph doesn't fit on the line. */
15293 new_x > it->last_visible_x
15294 /* Or it fits exactly on a window system frame. */
15295 || (new_x == it->last_visible_x
15296 && FRAME_WINDOW_P (it->f))))
15297 {
15298 /* End of a continued line. */
15299
15300 if (it->hpos == 0
15301 || (new_x == it->last_visible_x
15302 && FRAME_WINDOW_P (it->f)))
15303 {
15304 /* Current glyph is the only one on the line or
15305 fits exactly on the line. We must continue
15306 the line because we can't draw the cursor
15307 after the glyph. */
15308 row->continued_p = 1;
15309 it->current_x = new_x;
15310 it->continuation_lines_width += new_x;
15311 ++it->hpos;
15312 if (i == nglyphs - 1)
15313 {
15314 set_iterator_to_next (it, 1);
15315 #ifdef HAVE_WINDOW_SYSTEM
15316 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15317 {
15318 if (!get_next_display_element (it))
15319 {
15320 row->exact_window_width_line_p = 1;
15321 it->continuation_lines_width = 0;
15322 row->continued_p = 0;
15323 row->ends_at_zv_p = 1;
15324 }
15325 else if (ITERATOR_AT_END_OF_LINE_P (it))
15326 {
15327 row->continued_p = 0;
15328 row->exact_window_width_line_p = 1;
15329 }
15330 }
15331 #endif /* HAVE_WINDOW_SYSTEM */
15332 }
15333 }
15334 else if (CHAR_GLYPH_PADDING_P (*glyph)
15335 && !FRAME_WINDOW_P (it->f))
15336 {
15337 /* A padding glyph that doesn't fit on this line.
15338 This means the whole character doesn't fit
15339 on the line. */
15340 row->used[TEXT_AREA] = n_glyphs_before;
15341
15342 /* Fill the rest of the row with continuation
15343 glyphs like in 20.x. */
15344 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
15345 < row->glyphs[1 + TEXT_AREA])
15346 produce_special_glyphs (it, IT_CONTINUATION);
15347
15348 row->continued_p = 1;
15349 it->current_x = x_before;
15350 it->continuation_lines_width += x_before;
15351
15352 /* Restore the height to what it was before the
15353 element not fitting on the line. */
15354 it->max_ascent = ascent;
15355 it->max_descent = descent;
15356 it->max_phys_ascent = phys_ascent;
15357 it->max_phys_descent = phys_descent;
15358 }
15359 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
15360 {
15361 /* A TAB that extends past the right edge of the
15362 window. This produces a single glyph on
15363 window system frames. We leave the glyph in
15364 this row and let it fill the row, but don't
15365 consume the TAB. */
15366 it->continuation_lines_width += it->last_visible_x;
15367 row->ends_in_middle_of_char_p = 1;
15368 row->continued_p = 1;
15369 glyph->pixel_width = it->last_visible_x - x;
15370 it->starts_in_middle_of_char_p = 1;
15371 }
15372 else
15373 {
15374 /* Something other than a TAB that draws past
15375 the right edge of the window. Restore
15376 positions to values before the element. */
15377 row->used[TEXT_AREA] = n_glyphs_before + i;
15378
15379 /* Display continuation glyphs. */
15380 if (!FRAME_WINDOW_P (it->f))
15381 produce_special_glyphs (it, IT_CONTINUATION);
15382 row->continued_p = 1;
15383
15384 it->continuation_lines_width += x;
15385
15386 if (nglyphs > 1 && i > 0)
15387 {
15388 row->ends_in_middle_of_char_p = 1;
15389 it->starts_in_middle_of_char_p = 1;
15390 }
15391
15392 /* Restore the height to what it was before the
15393 element not fitting on the line. */
15394 it->max_ascent = ascent;
15395 it->max_descent = descent;
15396 it->max_phys_ascent = phys_ascent;
15397 it->max_phys_descent = phys_descent;
15398 }
15399
15400 break;
15401 }
15402 else if (new_x > it->first_visible_x)
15403 {
15404 /* Increment number of glyphs actually displayed. */
15405 ++it->hpos;
15406
15407 if (x < it->first_visible_x)
15408 /* Glyph is partially visible, i.e. row starts at
15409 negative X position. */
15410 row->x = x - it->first_visible_x;
15411 }
15412 else
15413 {
15414 /* Glyph is completely off the left margin of the
15415 window. This should not happen because of the
15416 move_it_in_display_line at the start of this
15417 function, unless the text display area of the
15418 window is empty. */
15419 xassert (it->first_visible_x <= it->last_visible_x);
15420 }
15421 }
15422
15423 row->ascent = max (row->ascent, it->max_ascent);
15424 row->height = max (row->height, it->max_ascent + it->max_descent);
15425 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15426 row->phys_height = max (row->phys_height,
15427 it->max_phys_ascent + it->max_phys_descent);
15428 row->extra_line_spacing = max (row->extra_line_spacing,
15429 it->max_extra_line_spacing);
15430
15431 /* End of this display line if row is continued. */
15432 if (row->continued_p || row->ends_at_zv_p)
15433 break;
15434 }
15435
15436 at_end_of_line:
15437 /* Is this a line end? If yes, we're also done, after making
15438 sure that a non-default face is extended up to the right
15439 margin of the window. */
15440 if (ITERATOR_AT_END_OF_LINE_P (it))
15441 {
15442 int used_before = row->used[TEXT_AREA];
15443
15444 row->ends_in_newline_from_string_p = STRINGP (it->object);
15445
15446 #ifdef HAVE_WINDOW_SYSTEM
15447 /* Add a space at the end of the line that is used to
15448 display the cursor there. */
15449 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15450 append_space_for_newline (it, 0);
15451 #endif /* HAVE_WINDOW_SYSTEM */
15452
15453 /* Extend the face to the end of the line. */
15454 extend_face_to_end_of_line (it);
15455
15456 /* Make sure we have the position. */
15457 if (used_before == 0)
15458 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15459
15460 /* Consume the line end. This skips over invisible lines. */
15461 set_iterator_to_next (it, 1);
15462 it->continuation_lines_width = 0;
15463 break;
15464 }
15465
15466 /* Proceed with next display element. Note that this skips
15467 over lines invisible because of selective display. */
15468 set_iterator_to_next (it, 1);
15469
15470 /* If we truncate lines, we are done when the last displayed
15471 glyphs reach past the right margin of the window. */
15472 if (it->truncate_lines_p
15473 && (FRAME_WINDOW_P (it->f)
15474 ? (it->current_x >= it->last_visible_x)
15475 : (it->current_x > it->last_visible_x)))
15476 {
15477 /* Maybe add truncation glyphs. */
15478 if (!FRAME_WINDOW_P (it->f))
15479 {
15480 int i, n;
15481
15482 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15483 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15484 break;
15485
15486 for (n = row->used[TEXT_AREA]; i < n; ++i)
15487 {
15488 row->used[TEXT_AREA] = i;
15489 produce_special_glyphs (it, IT_TRUNCATION);
15490 }
15491 }
15492 #ifdef HAVE_WINDOW_SYSTEM
15493 else
15494 {
15495 /* Don't truncate if we can overflow newline into fringe. */
15496 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15497 {
15498 if (!get_next_display_element (it))
15499 {
15500 it->continuation_lines_width = 0;
15501 row->ends_at_zv_p = 1;
15502 row->exact_window_width_line_p = 1;
15503 break;
15504 }
15505 if (ITERATOR_AT_END_OF_LINE_P (it))
15506 {
15507 row->exact_window_width_line_p = 1;
15508 goto at_end_of_line;
15509 }
15510 }
15511 }
15512 #endif /* HAVE_WINDOW_SYSTEM */
15513
15514 row->truncated_on_right_p = 1;
15515 it->continuation_lines_width = 0;
15516 reseat_at_next_visible_line_start (it, 0);
15517 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15518 it->hpos = hpos_before;
15519 it->current_x = x_before;
15520 break;
15521 }
15522 }
15523
15524 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15525 at the left window margin. */
15526 if (it->first_visible_x
15527 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15528 {
15529 if (!FRAME_WINDOW_P (it->f))
15530 insert_left_trunc_glyphs (it);
15531 row->truncated_on_left_p = 1;
15532 }
15533
15534 /* If the start of this line is the overlay arrow-position, then
15535 mark this glyph row as the one containing the overlay arrow.
15536 This is clearly a mess with variable size fonts. It would be
15537 better to let it be displayed like cursors under X. */
15538 if ((row->displays_text_p || !overlay_arrow_seen)
15539 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
15540 !NILP (overlay_arrow_string)))
15541 {
15542 /* Overlay arrow in window redisplay is a fringe bitmap. */
15543 if (STRINGP (overlay_arrow_string))
15544 {
15545 struct glyph_row *arrow_row
15546 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15547 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15548 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15549 struct glyph *p = row->glyphs[TEXT_AREA];
15550 struct glyph *p2, *end;
15551
15552 /* Copy the arrow glyphs. */
15553 while (glyph < arrow_end)
15554 *p++ = *glyph++;
15555
15556 /* Throw away padding glyphs. */
15557 p2 = p;
15558 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15559 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15560 ++p2;
15561 if (p2 > p)
15562 {
15563 while (p2 < end)
15564 *p++ = *p2++;
15565 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15566 }
15567 }
15568 else
15569 {
15570 xassert (INTEGERP (overlay_arrow_string));
15571 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
15572 }
15573 overlay_arrow_seen = 1;
15574 }
15575
15576 /* Compute pixel dimensions of this line. */
15577 compute_line_metrics (it);
15578
15579 /* Remember the position at which this line ends. */
15580 row->end = it->current;
15581
15582 /* Record whether this row ends inside an ellipsis. */
15583 row->ends_in_ellipsis_p
15584 = (it->method == GET_FROM_DISPLAY_VECTOR
15585 && it->ellipsis_p);
15586
15587 /* Save fringe bitmaps in this row. */
15588 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15589 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15590 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15591 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15592
15593 it->left_user_fringe_bitmap = 0;
15594 it->left_user_fringe_face_id = 0;
15595 it->right_user_fringe_bitmap = 0;
15596 it->right_user_fringe_face_id = 0;
15597
15598 /* Maybe set the cursor. */
15599 if (it->w->cursor.vpos < 0
15600 && PT >= MATRIX_ROW_START_CHARPOS (row)
15601 && PT <= MATRIX_ROW_END_CHARPOS (row)
15602 && cursor_row_p (it->w, row))
15603 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15604
15605 /* Highlight trailing whitespace. */
15606 if (!NILP (Vshow_trailing_whitespace))
15607 highlight_trailing_whitespace (it->f, it->glyph_row);
15608
15609 /* Prepare for the next line. This line starts horizontally at (X
15610 HPOS) = (0 0). Vertical positions are incremented. As a
15611 convenience for the caller, IT->glyph_row is set to the next
15612 row to be used. */
15613 it->current_x = it->hpos = 0;
15614 it->current_y += row->height;
15615 ++it->vpos;
15616 ++it->glyph_row;
15617 it->start = it->current;
15618 return row->displays_text_p;
15619 }
15620
15621
15622 \f
15623 /***********************************************************************
15624 Menu Bar
15625 ***********************************************************************/
15626
15627 /* Redisplay the menu bar in the frame for window W.
15628
15629 The menu bar of X frames that don't have X toolkit support is
15630 displayed in a special window W->frame->menu_bar_window.
15631
15632 The menu bar of terminal frames is treated specially as far as
15633 glyph matrices are concerned. Menu bar lines are not part of
15634 windows, so the update is done directly on the frame matrix rows
15635 for the menu bar. */
15636
15637 static void
15638 display_menu_bar (w)
15639 struct window *w;
15640 {
15641 struct frame *f = XFRAME (WINDOW_FRAME (w));
15642 struct it it;
15643 Lisp_Object items;
15644 int i;
15645
15646 /* Don't do all this for graphical frames. */
15647 #ifdef HAVE_NTGUI
15648 if (!NILP (Vwindow_system))
15649 return;
15650 #endif
15651 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15652 if (FRAME_X_P (f))
15653 return;
15654 #endif
15655 #ifdef MAC_OS
15656 if (FRAME_MAC_P (f))
15657 return;
15658 #endif
15659
15660 #ifdef USE_X_TOOLKIT
15661 xassert (!FRAME_WINDOW_P (f));
15662 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15663 it.first_visible_x = 0;
15664 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15665 #else /* not USE_X_TOOLKIT */
15666 if (FRAME_WINDOW_P (f))
15667 {
15668 /* Menu bar lines are displayed in the desired matrix of the
15669 dummy window menu_bar_window. */
15670 struct window *menu_w;
15671 xassert (WINDOWP (f->menu_bar_window));
15672 menu_w = XWINDOW (f->menu_bar_window);
15673 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15674 MENU_FACE_ID);
15675 it.first_visible_x = 0;
15676 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15677 }
15678 else
15679 {
15680 /* This is a TTY frame, i.e. character hpos/vpos are used as
15681 pixel x/y. */
15682 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15683 MENU_FACE_ID);
15684 it.first_visible_x = 0;
15685 it.last_visible_x = FRAME_COLS (f);
15686 }
15687 #endif /* not USE_X_TOOLKIT */
15688
15689 if (! mode_line_inverse_video)
15690 /* Force the menu-bar to be displayed in the default face. */
15691 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15692
15693 /* Clear all rows of the menu bar. */
15694 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15695 {
15696 struct glyph_row *row = it.glyph_row + i;
15697 clear_glyph_row (row);
15698 row->enabled_p = 1;
15699 row->full_width_p = 1;
15700 }
15701
15702 /* Display all items of the menu bar. */
15703 items = FRAME_MENU_BAR_ITEMS (it.f);
15704 for (i = 0; i < XVECTOR (items)->size; i += 4)
15705 {
15706 Lisp_Object string;
15707
15708 /* Stop at nil string. */
15709 string = AREF (items, i + 1);
15710 if (NILP (string))
15711 break;
15712
15713 /* Remember where item was displayed. */
15714 AREF (items, i + 3) = make_number (it.hpos);
15715
15716 /* Display the item, pad with one space. */
15717 if (it.current_x < it.last_visible_x)
15718 display_string (NULL, string, Qnil, 0, 0, &it,
15719 SCHARS (string) + 1, 0, 0, -1);
15720 }
15721
15722 /* Fill out the line with spaces. */
15723 if (it.current_x < it.last_visible_x)
15724 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15725
15726 /* Compute the total height of the lines. */
15727 compute_line_metrics (&it);
15728 }
15729
15730
15731 \f
15732 /***********************************************************************
15733 Mode Line
15734 ***********************************************************************/
15735
15736 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15737 FORCE is non-zero, redisplay mode lines unconditionally.
15738 Otherwise, redisplay only mode lines that are garbaged. Value is
15739 the number of windows whose mode lines were redisplayed. */
15740
15741 static int
15742 redisplay_mode_lines (window, force)
15743 Lisp_Object window;
15744 int force;
15745 {
15746 int nwindows = 0;
15747
15748 while (!NILP (window))
15749 {
15750 struct window *w = XWINDOW (window);
15751
15752 if (WINDOWP (w->hchild))
15753 nwindows += redisplay_mode_lines (w->hchild, force);
15754 else if (WINDOWP (w->vchild))
15755 nwindows += redisplay_mode_lines (w->vchild, force);
15756 else if (force
15757 || FRAME_GARBAGED_P (XFRAME (w->frame))
15758 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15759 {
15760 struct text_pos lpoint;
15761 struct buffer *old = current_buffer;
15762
15763 /* Set the window's buffer for the mode line display. */
15764 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15765 set_buffer_internal_1 (XBUFFER (w->buffer));
15766
15767 /* Point refers normally to the selected window. For any
15768 other window, set up appropriate value. */
15769 if (!EQ (window, selected_window))
15770 {
15771 struct text_pos pt;
15772
15773 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15774 if (CHARPOS (pt) < BEGV)
15775 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15776 else if (CHARPOS (pt) > (ZV - 1))
15777 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15778 else
15779 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15780 }
15781
15782 /* Display mode lines. */
15783 clear_glyph_matrix (w->desired_matrix);
15784 if (display_mode_lines (w))
15785 {
15786 ++nwindows;
15787 w->must_be_updated_p = 1;
15788 }
15789
15790 /* Restore old settings. */
15791 set_buffer_internal_1 (old);
15792 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15793 }
15794
15795 window = w->next;
15796 }
15797
15798 return nwindows;
15799 }
15800
15801
15802 /* Display the mode and/or top line of window W. Value is the number
15803 of mode lines displayed. */
15804
15805 static int
15806 display_mode_lines (w)
15807 struct window *w;
15808 {
15809 Lisp_Object old_selected_window, old_selected_frame;
15810 int n = 0;
15811
15812 old_selected_frame = selected_frame;
15813 selected_frame = w->frame;
15814 old_selected_window = selected_window;
15815 XSETWINDOW (selected_window, w);
15816
15817 /* These will be set while the mode line specs are processed. */
15818 line_number_displayed = 0;
15819 w->column_number_displayed = Qnil;
15820
15821 if (WINDOW_WANTS_MODELINE_P (w))
15822 {
15823 struct window *sel_w = XWINDOW (old_selected_window);
15824
15825 /* Select mode line face based on the real selected window. */
15826 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15827 current_buffer->mode_line_format);
15828 ++n;
15829 }
15830
15831 if (WINDOW_WANTS_HEADER_LINE_P (w))
15832 {
15833 display_mode_line (w, HEADER_LINE_FACE_ID,
15834 current_buffer->header_line_format);
15835 ++n;
15836 }
15837
15838 selected_frame = old_selected_frame;
15839 selected_window = old_selected_window;
15840 return n;
15841 }
15842
15843
15844 /* Display mode or top line of window W. FACE_ID specifies which line
15845 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15846 FORMAT is the mode line format to display. Value is the pixel
15847 height of the mode line displayed. */
15848
15849 static int
15850 display_mode_line (w, face_id, format)
15851 struct window *w;
15852 enum face_id face_id;
15853 Lisp_Object format;
15854 {
15855 struct it it;
15856 struct face *face;
15857 int count = SPECPDL_INDEX ();
15858
15859 init_iterator (&it, w, -1, -1, NULL, face_id);
15860 prepare_desired_row (it.glyph_row);
15861
15862 it.glyph_row->mode_line_p = 1;
15863
15864 if (! mode_line_inverse_video)
15865 /* Force the mode-line to be displayed in the default face. */
15866 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15867
15868 record_unwind_protect (unwind_format_mode_line,
15869 format_mode_line_unwind_data (NULL));
15870
15871 mode_line_target = MODE_LINE_DISPLAY;
15872
15873 /* Temporarily make frame's keyboard the current kboard so that
15874 kboard-local variables in the mode_line_format will get the right
15875 values. */
15876 push_frame_kboard (it.f);
15877 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15878 pop_frame_kboard ();
15879
15880 unbind_to (count, Qnil);
15881
15882 /* Fill up with spaces. */
15883 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15884
15885 compute_line_metrics (&it);
15886 it.glyph_row->full_width_p = 1;
15887 it.glyph_row->continued_p = 0;
15888 it.glyph_row->truncated_on_left_p = 0;
15889 it.glyph_row->truncated_on_right_p = 0;
15890
15891 /* Make a 3D mode-line have a shadow at its right end. */
15892 face = FACE_FROM_ID (it.f, face_id);
15893 extend_face_to_end_of_line (&it);
15894 if (face->box != FACE_NO_BOX)
15895 {
15896 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15897 + it.glyph_row->used[TEXT_AREA] - 1);
15898 last->right_box_line_p = 1;
15899 }
15900
15901 return it.glyph_row->height;
15902 }
15903
15904 /* Contribute ELT to the mode line for window IT->w. How it
15905 translates into text depends on its data type.
15906
15907 IT describes the display environment in which we display, as usual.
15908
15909 DEPTH is the depth in recursion. It is used to prevent
15910 infinite recursion here.
15911
15912 FIELD_WIDTH is the number of characters the display of ELT should
15913 occupy in the mode line, and PRECISION is the maximum number of
15914 characters to display from ELT's representation. See
15915 display_string for details.
15916
15917 Returns the hpos of the end of the text generated by ELT.
15918
15919 PROPS is a property list to add to any string we encounter.
15920
15921 If RISKY is nonzero, remove (disregard) any properties in any string
15922 we encounter, and ignore :eval and :propertize.
15923
15924 The global variable `mode_line_target' determines whether the
15925 output is passed to `store_mode_line_noprop',
15926 `store_mode_line_string', or `display_string'. */
15927
15928 static int
15929 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15930 struct it *it;
15931 int depth;
15932 int field_width, precision;
15933 Lisp_Object elt, props;
15934 int risky;
15935 {
15936 int n = 0, field, prec;
15937 int literal = 0;
15938
15939 tail_recurse:
15940 if (depth > 100)
15941 elt = build_string ("*too-deep*");
15942
15943 depth++;
15944
15945 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15946 {
15947 case Lisp_String:
15948 {
15949 /* A string: output it and check for %-constructs within it. */
15950 unsigned char c;
15951 const unsigned char *this, *lisp_string;
15952
15953 if (!NILP (props) || risky)
15954 {
15955 Lisp_Object oprops, aelt;
15956 oprops = Ftext_properties_at (make_number (0), elt);
15957
15958 /* If the starting string's properties are not what
15959 we want, translate the string. Also, if the string
15960 is risky, do that anyway. */
15961
15962 if (NILP (Fequal (props, oprops)) || risky)
15963 {
15964 /* If the starting string has properties,
15965 merge the specified ones onto the existing ones. */
15966 if (! NILP (oprops) && !risky)
15967 {
15968 Lisp_Object tem;
15969
15970 oprops = Fcopy_sequence (oprops);
15971 tem = props;
15972 while (CONSP (tem))
15973 {
15974 oprops = Fplist_put (oprops, XCAR (tem),
15975 XCAR (XCDR (tem)));
15976 tem = XCDR (XCDR (tem));
15977 }
15978 props = oprops;
15979 }
15980
15981 aelt = Fassoc (elt, mode_line_proptrans_alist);
15982 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15983 {
15984 mode_line_proptrans_alist
15985 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15986 elt = XCAR (aelt);
15987 }
15988 else
15989 {
15990 Lisp_Object tem;
15991
15992 elt = Fcopy_sequence (elt);
15993 Fset_text_properties (make_number (0), Flength (elt),
15994 props, elt);
15995 /* Add this item to mode_line_proptrans_alist. */
15996 mode_line_proptrans_alist
15997 = Fcons (Fcons (elt, props),
15998 mode_line_proptrans_alist);
15999 /* Truncate mode_line_proptrans_alist
16000 to at most 50 elements. */
16001 tem = Fnthcdr (make_number (50),
16002 mode_line_proptrans_alist);
16003 if (! NILP (tem))
16004 XSETCDR (tem, Qnil);
16005 }
16006 }
16007 }
16008
16009 this = SDATA (elt);
16010 lisp_string = this;
16011
16012 if (literal)
16013 {
16014 prec = precision - n;
16015 switch (mode_line_target)
16016 {
16017 case MODE_LINE_NOPROP:
16018 case MODE_LINE_TITLE:
16019 n += store_mode_line_noprop (SDATA (elt), -1, prec);
16020 break;
16021 case MODE_LINE_STRING:
16022 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
16023 break;
16024 case MODE_LINE_DISPLAY:
16025 n += display_string (NULL, elt, Qnil, 0, 0, it,
16026 0, prec, 0, STRING_MULTIBYTE (elt));
16027 break;
16028 }
16029
16030 break;
16031 }
16032
16033 while ((precision <= 0 || n < precision)
16034 && *this
16035 && (mode_line_target != MODE_LINE_DISPLAY
16036 || it->current_x < it->last_visible_x))
16037 {
16038 const unsigned char *last = this;
16039
16040 /* Advance to end of string or next format specifier. */
16041 while ((c = *this++) != '\0' && c != '%')
16042 ;
16043
16044 if (this - 1 != last)
16045 {
16046 int nchars, nbytes;
16047
16048 /* Output to end of string or up to '%'. Field width
16049 is length of string. Don't output more than
16050 PRECISION allows us. */
16051 --this;
16052
16053 prec = c_string_width (last, this - last, precision - n,
16054 &nchars, &nbytes);
16055
16056 switch (mode_line_target)
16057 {
16058 case MODE_LINE_NOPROP:
16059 case MODE_LINE_TITLE:
16060 n += store_mode_line_noprop (last, 0, prec);
16061 break;
16062 case MODE_LINE_STRING:
16063 {
16064 int bytepos = last - lisp_string;
16065 int charpos = string_byte_to_char (elt, bytepos);
16066 int endpos = (precision <= 0
16067 ? string_byte_to_char (elt,
16068 this - lisp_string)
16069 : charpos + nchars);
16070
16071 n += store_mode_line_string (NULL,
16072 Fsubstring (elt, make_number (charpos),
16073 make_number (endpos)),
16074 0, 0, 0, Qnil);
16075 }
16076 break;
16077 case MODE_LINE_DISPLAY:
16078 {
16079 int bytepos = last - lisp_string;
16080 int charpos = string_byte_to_char (elt, bytepos);
16081 n += display_string (NULL, elt, Qnil, 0, charpos,
16082 it, 0, prec, 0,
16083 STRING_MULTIBYTE (elt));
16084 }
16085 break;
16086 }
16087 }
16088 else /* c == '%' */
16089 {
16090 const unsigned char *percent_position = this;
16091
16092 /* Get the specified minimum width. Zero means
16093 don't pad. */
16094 field = 0;
16095 while ((c = *this++) >= '0' && c <= '9')
16096 field = field * 10 + c - '0';
16097
16098 /* Don't pad beyond the total padding allowed. */
16099 if (field_width - n > 0 && field > field_width - n)
16100 field = field_width - n;
16101
16102 /* Note that either PRECISION <= 0 or N < PRECISION. */
16103 prec = precision - n;
16104
16105 if (c == 'M')
16106 n += display_mode_element (it, depth, field, prec,
16107 Vglobal_mode_string, props,
16108 risky);
16109 else if (c != 0)
16110 {
16111 int multibyte;
16112 int bytepos, charpos;
16113 unsigned char *spec;
16114
16115 bytepos = percent_position - lisp_string;
16116 charpos = (STRING_MULTIBYTE (elt)
16117 ? string_byte_to_char (elt, bytepos)
16118 : bytepos);
16119
16120 spec
16121 = decode_mode_spec (it->w, c, field, prec, &multibyte);
16122
16123 switch (mode_line_target)
16124 {
16125 case MODE_LINE_NOPROP:
16126 case MODE_LINE_TITLE:
16127 n += store_mode_line_noprop (spec, field, prec);
16128 break;
16129 case MODE_LINE_STRING:
16130 {
16131 int len = strlen (spec);
16132 Lisp_Object tem = make_string (spec, len);
16133 props = Ftext_properties_at (make_number (charpos), elt);
16134 /* Should only keep face property in props */
16135 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
16136 }
16137 break;
16138 case MODE_LINE_DISPLAY:
16139 {
16140 int nglyphs_before, nwritten;
16141
16142 nglyphs_before = it->glyph_row->used[TEXT_AREA];
16143 nwritten = display_string (spec, Qnil, elt,
16144 charpos, 0, it,
16145 field, prec, 0,
16146 multibyte);
16147
16148 /* Assign to the glyphs written above the
16149 string where the `%x' came from, position
16150 of the `%'. */
16151 if (nwritten > 0)
16152 {
16153 struct glyph *glyph
16154 = (it->glyph_row->glyphs[TEXT_AREA]
16155 + nglyphs_before);
16156 int i;
16157
16158 for (i = 0; i < nwritten; ++i)
16159 {
16160 glyph[i].object = elt;
16161 glyph[i].charpos = charpos;
16162 }
16163
16164 n += nwritten;
16165 }
16166 }
16167 break;
16168 }
16169 }
16170 else /* c == 0 */
16171 break;
16172 }
16173 }
16174 }
16175 break;
16176
16177 case Lisp_Symbol:
16178 /* A symbol: process the value of the symbol recursively
16179 as if it appeared here directly. Avoid error if symbol void.
16180 Special case: if value of symbol is a string, output the string
16181 literally. */
16182 {
16183 register Lisp_Object tem;
16184
16185 /* If the variable is not marked as risky to set
16186 then its contents are risky to use. */
16187 if (NILP (Fget (elt, Qrisky_local_variable)))
16188 risky = 1;
16189
16190 tem = Fboundp (elt);
16191 if (!NILP (tem))
16192 {
16193 tem = Fsymbol_value (elt);
16194 /* If value is a string, output that string literally:
16195 don't check for % within it. */
16196 if (STRINGP (tem))
16197 literal = 1;
16198
16199 if (!EQ (tem, elt))
16200 {
16201 /* Give up right away for nil or t. */
16202 elt = tem;
16203 goto tail_recurse;
16204 }
16205 }
16206 }
16207 break;
16208
16209 case Lisp_Cons:
16210 {
16211 register Lisp_Object car, tem;
16212
16213 /* A cons cell: five distinct cases.
16214 If first element is :eval or :propertize, do something special.
16215 If first element is a string or a cons, process all the elements
16216 and effectively concatenate them.
16217 If first element is a negative number, truncate displaying cdr to
16218 at most that many characters. If positive, pad (with spaces)
16219 to at least that many characters.
16220 If first element is a symbol, process the cadr or caddr recursively
16221 according to whether the symbol's value is non-nil or nil. */
16222 car = XCAR (elt);
16223 if (EQ (car, QCeval))
16224 {
16225 /* An element of the form (:eval FORM) means evaluate FORM
16226 and use the result as mode line elements. */
16227
16228 if (risky)
16229 break;
16230
16231 if (CONSP (XCDR (elt)))
16232 {
16233 Lisp_Object spec;
16234 spec = safe_eval (XCAR (XCDR (elt)));
16235 n += display_mode_element (it, depth, field_width - n,
16236 precision - n, spec, props,
16237 risky);
16238 }
16239 }
16240 else if (EQ (car, QCpropertize))
16241 {
16242 /* An element of the form (:propertize ELT PROPS...)
16243 means display ELT but applying properties PROPS. */
16244
16245 if (risky)
16246 break;
16247
16248 if (CONSP (XCDR (elt)))
16249 n += display_mode_element (it, depth, field_width - n,
16250 precision - n, XCAR (XCDR (elt)),
16251 XCDR (XCDR (elt)), risky);
16252 }
16253 else if (SYMBOLP (car))
16254 {
16255 tem = Fboundp (car);
16256 elt = XCDR (elt);
16257 if (!CONSP (elt))
16258 goto invalid;
16259 /* elt is now the cdr, and we know it is a cons cell.
16260 Use its car if CAR has a non-nil value. */
16261 if (!NILP (tem))
16262 {
16263 tem = Fsymbol_value (car);
16264 if (!NILP (tem))
16265 {
16266 elt = XCAR (elt);
16267 goto tail_recurse;
16268 }
16269 }
16270 /* Symbol's value is nil (or symbol is unbound)
16271 Get the cddr of the original list
16272 and if possible find the caddr and use that. */
16273 elt = XCDR (elt);
16274 if (NILP (elt))
16275 break;
16276 else if (!CONSP (elt))
16277 goto invalid;
16278 elt = XCAR (elt);
16279 goto tail_recurse;
16280 }
16281 else if (INTEGERP (car))
16282 {
16283 register int lim = XINT (car);
16284 elt = XCDR (elt);
16285 if (lim < 0)
16286 {
16287 /* Negative int means reduce maximum width. */
16288 if (precision <= 0)
16289 precision = -lim;
16290 else
16291 precision = min (precision, -lim);
16292 }
16293 else if (lim > 0)
16294 {
16295 /* Padding specified. Don't let it be more than
16296 current maximum. */
16297 if (precision > 0)
16298 lim = min (precision, lim);
16299
16300 /* If that's more padding than already wanted, queue it.
16301 But don't reduce padding already specified even if
16302 that is beyond the current truncation point. */
16303 field_width = max (lim, field_width);
16304 }
16305 goto tail_recurse;
16306 }
16307 else if (STRINGP (car) || CONSP (car))
16308 {
16309 register int limit = 50;
16310 /* Limit is to protect against circular lists. */
16311 while (CONSP (elt)
16312 && --limit > 0
16313 && (precision <= 0 || n < precision))
16314 {
16315 n += display_mode_element (it, depth,
16316 /* Do padding only after the last
16317 element in the list. */
16318 (! CONSP (XCDR (elt))
16319 ? field_width - n
16320 : 0),
16321 precision - n, XCAR (elt),
16322 props, risky);
16323 elt = XCDR (elt);
16324 }
16325 }
16326 }
16327 break;
16328
16329 default:
16330 invalid:
16331 elt = build_string ("*invalid*");
16332 goto tail_recurse;
16333 }
16334
16335 /* Pad to FIELD_WIDTH. */
16336 if (field_width > 0 && n < field_width)
16337 {
16338 switch (mode_line_target)
16339 {
16340 case MODE_LINE_NOPROP:
16341 case MODE_LINE_TITLE:
16342 n += store_mode_line_noprop ("", field_width - n, 0);
16343 break;
16344 case MODE_LINE_STRING:
16345 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
16346 break;
16347 case MODE_LINE_DISPLAY:
16348 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
16349 0, 0, 0);
16350 break;
16351 }
16352 }
16353
16354 return n;
16355 }
16356
16357 /* Store a mode-line string element in mode_line_string_list.
16358
16359 If STRING is non-null, display that C string. Otherwise, the Lisp
16360 string LISP_STRING is displayed.
16361
16362 FIELD_WIDTH is the minimum number of output glyphs to produce.
16363 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16364 with spaces. FIELD_WIDTH <= 0 means don't pad.
16365
16366 PRECISION is the maximum number of characters to output from
16367 STRING. PRECISION <= 0 means don't truncate the string.
16368
16369 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
16370 properties to the string.
16371
16372 PROPS are the properties to add to the string.
16373 The mode_line_string_face face property is always added to the string.
16374 */
16375
16376 static int
16377 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
16378 char *string;
16379 Lisp_Object lisp_string;
16380 int copy_string;
16381 int field_width;
16382 int precision;
16383 Lisp_Object props;
16384 {
16385 int len;
16386 int n = 0;
16387
16388 if (string != NULL)
16389 {
16390 len = strlen (string);
16391 if (precision > 0 && len > precision)
16392 len = precision;
16393 lisp_string = make_string (string, len);
16394 if (NILP (props))
16395 props = mode_line_string_face_prop;
16396 else if (!NILP (mode_line_string_face))
16397 {
16398 Lisp_Object face = Fplist_get (props, Qface);
16399 props = Fcopy_sequence (props);
16400 if (NILP (face))
16401 face = mode_line_string_face;
16402 else
16403 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16404 props = Fplist_put (props, Qface, face);
16405 }
16406 Fadd_text_properties (make_number (0), make_number (len),
16407 props, lisp_string);
16408 }
16409 else
16410 {
16411 len = XFASTINT (Flength (lisp_string));
16412 if (precision > 0 && len > precision)
16413 {
16414 len = precision;
16415 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
16416 precision = -1;
16417 }
16418 if (!NILP (mode_line_string_face))
16419 {
16420 Lisp_Object face;
16421 if (NILP (props))
16422 props = Ftext_properties_at (make_number (0), lisp_string);
16423 face = Fplist_get (props, Qface);
16424 if (NILP (face))
16425 face = mode_line_string_face;
16426 else
16427 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16428 props = Fcons (Qface, Fcons (face, Qnil));
16429 if (copy_string)
16430 lisp_string = Fcopy_sequence (lisp_string);
16431 }
16432 if (!NILP (props))
16433 Fadd_text_properties (make_number (0), make_number (len),
16434 props, lisp_string);
16435 }
16436
16437 if (len > 0)
16438 {
16439 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16440 n += len;
16441 }
16442
16443 if (field_width > len)
16444 {
16445 field_width -= len;
16446 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
16447 if (!NILP (props))
16448 Fadd_text_properties (make_number (0), make_number (field_width),
16449 props, lisp_string);
16450 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16451 n += field_width;
16452 }
16453
16454 return n;
16455 }
16456
16457
16458 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
16459 1, 4, 0,
16460 doc: /* Format a string out of a mode line format specification.
16461 First arg FORMAT specifies the mode line format (see `mode-line-format'
16462 for details) to use.
16463
16464 Optional second arg FACE specifies the face property to put
16465 on all characters for which no face is specified.
16466 t means whatever face the window's mode line currently uses
16467 \(either `mode-line' or `mode-line-inactive', depending).
16468 nil means the default is no face property.
16469 If FACE is an integer, the value string has no text properties.
16470
16471 Optional third and fourth args WINDOW and BUFFER specify the window
16472 and buffer to use as the context for the formatting (defaults
16473 are the selected window and the window's buffer). */)
16474 (format, face, window, buffer)
16475 Lisp_Object format, face, window, buffer;
16476 {
16477 struct it it;
16478 int len;
16479 struct window *w;
16480 struct buffer *old_buffer = NULL;
16481 int face_id = -1;
16482 int no_props = INTEGERP (face);
16483 int count = SPECPDL_INDEX ();
16484 Lisp_Object str;
16485 int string_start = 0;
16486
16487 if (NILP (window))
16488 window = selected_window;
16489 CHECK_WINDOW (window);
16490 w = XWINDOW (window);
16491
16492 if (NILP (buffer))
16493 buffer = w->buffer;
16494 CHECK_BUFFER (buffer);
16495
16496 if (NILP (format))
16497 return build_string ("");
16498
16499 if (no_props)
16500 face = Qnil;
16501
16502 if (!NILP (face))
16503 {
16504 if (EQ (face, Qt))
16505 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
16506 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
16507 }
16508
16509 if (face_id < 0)
16510 face_id = DEFAULT_FACE_ID;
16511
16512 if (XBUFFER (buffer) != current_buffer)
16513 old_buffer = current_buffer;
16514
16515 record_unwind_protect (unwind_format_mode_line,
16516 format_mode_line_unwind_data (old_buffer));
16517
16518 if (old_buffer)
16519 set_buffer_internal_1 (XBUFFER (buffer));
16520
16521 init_iterator (&it, w, -1, -1, NULL, face_id);
16522
16523 if (no_props)
16524 {
16525 mode_line_target = MODE_LINE_NOPROP;
16526 mode_line_string_face_prop = Qnil;
16527 mode_line_string_list = Qnil;
16528 string_start = MODE_LINE_NOPROP_LEN (0);
16529 }
16530 else
16531 {
16532 mode_line_target = MODE_LINE_STRING;
16533 mode_line_string_list = Qnil;
16534 mode_line_string_face = face;
16535 mode_line_string_face_prop
16536 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
16537 }
16538
16539 push_frame_kboard (it.f);
16540 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16541 pop_frame_kboard ();
16542
16543 if (no_props)
16544 {
16545 len = MODE_LINE_NOPROP_LEN (string_start);
16546 str = make_string (mode_line_noprop_buf + string_start, len);
16547 }
16548 else
16549 {
16550 mode_line_string_list = Fnreverse (mode_line_string_list);
16551 str = Fmapconcat (intern ("identity"), mode_line_string_list,
16552 make_string ("", 0));
16553 }
16554
16555 unbind_to (count, Qnil);
16556 return str;
16557 }
16558
16559 /* Write a null-terminated, right justified decimal representation of
16560 the positive integer D to BUF using a minimal field width WIDTH. */
16561
16562 static void
16563 pint2str (buf, width, d)
16564 register char *buf;
16565 register int width;
16566 register int d;
16567 {
16568 register char *p = buf;
16569
16570 if (d <= 0)
16571 *p++ = '0';
16572 else
16573 {
16574 while (d > 0)
16575 {
16576 *p++ = d % 10 + '0';
16577 d /= 10;
16578 }
16579 }
16580
16581 for (width -= (int) (p - buf); width > 0; --width)
16582 *p++ = ' ';
16583 *p-- = '\0';
16584 while (p > buf)
16585 {
16586 d = *buf;
16587 *buf++ = *p;
16588 *p-- = d;
16589 }
16590 }
16591
16592 /* Write a null-terminated, right justified decimal and "human
16593 readable" representation of the nonnegative integer D to BUF using
16594 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16595
16596 static const char power_letter[] =
16597 {
16598 0, /* not used */
16599 'k', /* kilo */
16600 'M', /* mega */
16601 'G', /* giga */
16602 'T', /* tera */
16603 'P', /* peta */
16604 'E', /* exa */
16605 'Z', /* zetta */
16606 'Y' /* yotta */
16607 };
16608
16609 static void
16610 pint2hrstr (buf, width, d)
16611 char *buf;
16612 int width;
16613 int d;
16614 {
16615 /* We aim to represent the nonnegative integer D as
16616 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16617 int quotient = d;
16618 int remainder = 0;
16619 /* -1 means: do not use TENTHS. */
16620 int tenths = -1;
16621 int exponent = 0;
16622
16623 /* Length of QUOTIENT.TENTHS as a string. */
16624 int length;
16625
16626 char * psuffix;
16627 char * p;
16628
16629 if (1000 <= quotient)
16630 {
16631 /* Scale to the appropriate EXPONENT. */
16632 do
16633 {
16634 remainder = quotient % 1000;
16635 quotient /= 1000;
16636 exponent++;
16637 }
16638 while (1000 <= quotient);
16639
16640 /* Round to nearest and decide whether to use TENTHS or not. */
16641 if (quotient <= 9)
16642 {
16643 tenths = remainder / 100;
16644 if (50 <= remainder % 100)
16645 {
16646 if (tenths < 9)
16647 tenths++;
16648 else
16649 {
16650 quotient++;
16651 if (quotient == 10)
16652 tenths = -1;
16653 else
16654 tenths = 0;
16655 }
16656 }
16657 }
16658 else
16659 if (500 <= remainder)
16660 {
16661 if (quotient < 999)
16662 quotient++;
16663 else
16664 {
16665 quotient = 1;
16666 exponent++;
16667 tenths = 0;
16668 }
16669 }
16670 }
16671
16672 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16673 if (tenths == -1 && quotient <= 99)
16674 if (quotient <= 9)
16675 length = 1;
16676 else
16677 length = 2;
16678 else
16679 length = 3;
16680 p = psuffix = buf + max (width, length);
16681
16682 /* Print EXPONENT. */
16683 if (exponent)
16684 *psuffix++ = power_letter[exponent];
16685 *psuffix = '\0';
16686
16687 /* Print TENTHS. */
16688 if (tenths >= 0)
16689 {
16690 *--p = '0' + tenths;
16691 *--p = '.';
16692 }
16693
16694 /* Print QUOTIENT. */
16695 do
16696 {
16697 int digit = quotient % 10;
16698 *--p = '0' + digit;
16699 }
16700 while ((quotient /= 10) != 0);
16701
16702 /* Print leading spaces. */
16703 while (buf < p)
16704 *--p = ' ';
16705 }
16706
16707 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16708 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16709 type of CODING_SYSTEM. Return updated pointer into BUF. */
16710
16711 static unsigned char invalid_eol_type[] = "(*invalid*)";
16712
16713 static char *
16714 decode_mode_spec_coding (coding_system, buf, eol_flag)
16715 Lisp_Object coding_system;
16716 register char *buf;
16717 int eol_flag;
16718 {
16719 Lisp_Object val;
16720 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16721 const unsigned char *eol_str;
16722 int eol_str_len;
16723 /* The EOL conversion we are using. */
16724 Lisp_Object eoltype;
16725
16726 val = Fget (coding_system, Qcoding_system);
16727 eoltype = Qnil;
16728
16729 if (!VECTORP (val)) /* Not yet decided. */
16730 {
16731 if (multibyte)
16732 *buf++ = '-';
16733 if (eol_flag)
16734 eoltype = eol_mnemonic_undecided;
16735 /* Don't mention EOL conversion if it isn't decided. */
16736 }
16737 else
16738 {
16739 Lisp_Object eolvalue;
16740
16741 eolvalue = Fget (coding_system, Qeol_type);
16742
16743 if (multibyte)
16744 *buf++ = XFASTINT (AREF (val, 1));
16745
16746 if (eol_flag)
16747 {
16748 /* The EOL conversion that is normal on this system. */
16749
16750 if (NILP (eolvalue)) /* Not yet decided. */
16751 eoltype = eol_mnemonic_undecided;
16752 else if (VECTORP (eolvalue)) /* Not yet decided. */
16753 eoltype = eol_mnemonic_undecided;
16754 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16755 eoltype = (XFASTINT (eolvalue) == 0
16756 ? eol_mnemonic_unix
16757 : (XFASTINT (eolvalue) == 1
16758 ? eol_mnemonic_dos : eol_mnemonic_mac));
16759 }
16760 }
16761
16762 if (eol_flag)
16763 {
16764 /* Mention the EOL conversion if it is not the usual one. */
16765 if (STRINGP (eoltype))
16766 {
16767 eol_str = SDATA (eoltype);
16768 eol_str_len = SBYTES (eoltype);
16769 }
16770 else if (INTEGERP (eoltype)
16771 && CHAR_VALID_P (XINT (eoltype), 0))
16772 {
16773 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16774 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16775 eol_str = tmp;
16776 }
16777 else
16778 {
16779 eol_str = invalid_eol_type;
16780 eol_str_len = sizeof (invalid_eol_type) - 1;
16781 }
16782 bcopy (eol_str, buf, eol_str_len);
16783 buf += eol_str_len;
16784 }
16785
16786 return buf;
16787 }
16788
16789 /* Return a string for the output of a mode line %-spec for window W,
16790 generated by character C. PRECISION >= 0 means don't return a
16791 string longer than that value. FIELD_WIDTH > 0 means pad the
16792 string returned with spaces to that value. Return 1 in *MULTIBYTE
16793 if the result is multibyte text.
16794
16795 Note we operate on the current buffer for most purposes,
16796 the exception being w->base_line_pos. */
16797
16798 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16799
16800 static char *
16801 decode_mode_spec (w, c, field_width, precision, multibyte)
16802 struct window *w;
16803 register int c;
16804 int field_width, precision;
16805 int *multibyte;
16806 {
16807 Lisp_Object obj;
16808 struct frame *f = XFRAME (WINDOW_FRAME (w));
16809 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16810 struct buffer *b = current_buffer;
16811
16812 obj = Qnil;
16813 *multibyte = 0;
16814
16815 switch (c)
16816 {
16817 case '*':
16818 if (!NILP (b->read_only))
16819 return "%";
16820 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16821 return "*";
16822 return "-";
16823
16824 case '+':
16825 /* This differs from %* only for a modified read-only buffer. */
16826 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16827 return "*";
16828 if (!NILP (b->read_only))
16829 return "%";
16830 return "-";
16831
16832 case '&':
16833 /* This differs from %* in ignoring read-only-ness. */
16834 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16835 return "*";
16836 return "-";
16837
16838 case '%':
16839 return "%";
16840
16841 case '[':
16842 {
16843 int i;
16844 char *p;
16845
16846 if (command_loop_level > 5)
16847 return "[[[... ";
16848 p = decode_mode_spec_buf;
16849 for (i = 0; i < command_loop_level; i++)
16850 *p++ = '[';
16851 *p = 0;
16852 return decode_mode_spec_buf;
16853 }
16854
16855 case ']':
16856 {
16857 int i;
16858 char *p;
16859
16860 if (command_loop_level > 5)
16861 return " ...]]]";
16862 p = decode_mode_spec_buf;
16863 for (i = 0; i < command_loop_level; i++)
16864 *p++ = ']';
16865 *p = 0;
16866 return decode_mode_spec_buf;
16867 }
16868
16869 case '-':
16870 {
16871 register int i;
16872
16873 /* Let lots_of_dashes be a string of infinite length. */
16874 if (mode_line_target == MODE_LINE_NOPROP ||
16875 mode_line_target == MODE_LINE_STRING)
16876 return "--";
16877 if (field_width <= 0
16878 || field_width > sizeof (lots_of_dashes))
16879 {
16880 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16881 decode_mode_spec_buf[i] = '-';
16882 decode_mode_spec_buf[i] = '\0';
16883 return decode_mode_spec_buf;
16884 }
16885 else
16886 return lots_of_dashes;
16887 }
16888
16889 case 'b':
16890 obj = b->name;
16891 break;
16892
16893 case 'c':
16894 {
16895 int col = (int) current_column (); /* iftc */
16896 w->column_number_displayed = make_number (col);
16897 pint2str (decode_mode_spec_buf, field_width, col);
16898 return decode_mode_spec_buf;
16899 }
16900
16901 case 'F':
16902 /* %F displays the frame name. */
16903 if (!NILP (f->title))
16904 return (char *) SDATA (f->title);
16905 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16906 return (char *) SDATA (f->name);
16907 return "Emacs";
16908
16909 case 'f':
16910 obj = b->filename;
16911 break;
16912
16913 case 'i':
16914 {
16915 int size = ZV - BEGV;
16916 pint2str (decode_mode_spec_buf, field_width, size);
16917 return decode_mode_spec_buf;
16918 }
16919
16920 case 'I':
16921 {
16922 int size = ZV - BEGV;
16923 pint2hrstr (decode_mode_spec_buf, field_width, size);
16924 return decode_mode_spec_buf;
16925 }
16926
16927 case 'l':
16928 {
16929 int startpos = XMARKER (w->start)->charpos;
16930 int startpos_byte = marker_byte_position (w->start);
16931 int line, linepos, linepos_byte, topline;
16932 int nlines, junk;
16933 int height = WINDOW_TOTAL_LINES (w);
16934
16935 /* If we decided that this buffer isn't suitable for line numbers,
16936 don't forget that too fast. */
16937 if (EQ (w->base_line_pos, w->buffer))
16938 goto no_value;
16939 /* But do forget it, if the window shows a different buffer now. */
16940 else if (BUFFERP (w->base_line_pos))
16941 w->base_line_pos = Qnil;
16942
16943 /* If the buffer is very big, don't waste time. */
16944 if (INTEGERP (Vline_number_display_limit)
16945 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16946 {
16947 w->base_line_pos = Qnil;
16948 w->base_line_number = Qnil;
16949 goto no_value;
16950 }
16951
16952 if (!NILP (w->base_line_number)
16953 && !NILP (w->base_line_pos)
16954 && XFASTINT (w->base_line_pos) <= startpos)
16955 {
16956 line = XFASTINT (w->base_line_number);
16957 linepos = XFASTINT (w->base_line_pos);
16958 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16959 }
16960 else
16961 {
16962 line = 1;
16963 linepos = BUF_BEGV (b);
16964 linepos_byte = BUF_BEGV_BYTE (b);
16965 }
16966
16967 /* Count lines from base line to window start position. */
16968 nlines = display_count_lines (linepos, linepos_byte,
16969 startpos_byte,
16970 startpos, &junk);
16971
16972 topline = nlines + line;
16973
16974 /* Determine a new base line, if the old one is too close
16975 or too far away, or if we did not have one.
16976 "Too close" means it's plausible a scroll-down would
16977 go back past it. */
16978 if (startpos == BUF_BEGV (b))
16979 {
16980 w->base_line_number = make_number (topline);
16981 w->base_line_pos = make_number (BUF_BEGV (b));
16982 }
16983 else if (nlines < height + 25 || nlines > height * 3 + 50
16984 || linepos == BUF_BEGV (b))
16985 {
16986 int limit = BUF_BEGV (b);
16987 int limit_byte = BUF_BEGV_BYTE (b);
16988 int position;
16989 int distance = (height * 2 + 30) * line_number_display_limit_width;
16990
16991 if (startpos - distance > limit)
16992 {
16993 limit = startpos - distance;
16994 limit_byte = CHAR_TO_BYTE (limit);
16995 }
16996
16997 nlines = display_count_lines (startpos, startpos_byte,
16998 limit_byte,
16999 - (height * 2 + 30),
17000 &position);
17001 /* If we couldn't find the lines we wanted within
17002 line_number_display_limit_width chars per line,
17003 give up on line numbers for this window. */
17004 if (position == limit_byte && limit == startpos - distance)
17005 {
17006 w->base_line_pos = w->buffer;
17007 w->base_line_number = Qnil;
17008 goto no_value;
17009 }
17010
17011 w->base_line_number = make_number (topline - nlines);
17012 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
17013 }
17014
17015 /* Now count lines from the start pos to point. */
17016 nlines = display_count_lines (startpos, startpos_byte,
17017 PT_BYTE, PT, &junk);
17018
17019 /* Record that we did display the line number. */
17020 line_number_displayed = 1;
17021
17022 /* Make the string to show. */
17023 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
17024 return decode_mode_spec_buf;
17025 no_value:
17026 {
17027 char* p = decode_mode_spec_buf;
17028 int pad = field_width - 2;
17029 while (pad-- > 0)
17030 *p++ = ' ';
17031 *p++ = '?';
17032 *p++ = '?';
17033 *p = '\0';
17034 return decode_mode_spec_buf;
17035 }
17036 }
17037 break;
17038
17039 case 'm':
17040 obj = b->mode_name;
17041 break;
17042
17043 case 'n':
17044 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
17045 return " Narrow";
17046 break;
17047
17048 case 'p':
17049 {
17050 int pos = marker_position (w->start);
17051 int total = BUF_ZV (b) - BUF_BEGV (b);
17052
17053 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
17054 {
17055 if (pos <= BUF_BEGV (b))
17056 return "All";
17057 else
17058 return "Bottom";
17059 }
17060 else if (pos <= BUF_BEGV (b))
17061 return "Top";
17062 else
17063 {
17064 if (total > 1000000)
17065 /* Do it differently for a large value, to avoid overflow. */
17066 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17067 else
17068 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
17069 /* We can't normally display a 3-digit number,
17070 so get us a 2-digit number that is close. */
17071 if (total == 100)
17072 total = 99;
17073 sprintf (decode_mode_spec_buf, "%2d%%", total);
17074 return decode_mode_spec_buf;
17075 }
17076 }
17077
17078 /* Display percentage of size above the bottom of the screen. */
17079 case 'P':
17080 {
17081 int toppos = marker_position (w->start);
17082 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
17083 int total = BUF_ZV (b) - BUF_BEGV (b);
17084
17085 if (botpos >= BUF_ZV (b))
17086 {
17087 if (toppos <= BUF_BEGV (b))
17088 return "All";
17089 else
17090 return "Bottom";
17091 }
17092 else
17093 {
17094 if (total > 1000000)
17095 /* Do it differently for a large value, to avoid overflow. */
17096 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17097 else
17098 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
17099 /* We can't normally display a 3-digit number,
17100 so get us a 2-digit number that is close. */
17101 if (total == 100)
17102 total = 99;
17103 if (toppos <= BUF_BEGV (b))
17104 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
17105 else
17106 sprintf (decode_mode_spec_buf, "%2d%%", total);
17107 return decode_mode_spec_buf;
17108 }
17109 }
17110
17111 case 's':
17112 /* status of process */
17113 obj = Fget_buffer_process (Fcurrent_buffer ());
17114 if (NILP (obj))
17115 return "no process";
17116 #ifdef subprocesses
17117 obj = Fsymbol_name (Fprocess_status (obj));
17118 #endif
17119 break;
17120
17121 case 't': /* indicate TEXT or BINARY */
17122 #ifdef MODE_LINE_BINARY_TEXT
17123 return MODE_LINE_BINARY_TEXT (b);
17124 #else
17125 return "T";
17126 #endif
17127
17128 case 'z':
17129 /* coding-system (not including end-of-line format) */
17130 case 'Z':
17131 /* coding-system (including end-of-line type) */
17132 {
17133 int eol_flag = (c == 'Z');
17134 char *p = decode_mode_spec_buf;
17135
17136 if (! FRAME_WINDOW_P (f))
17137 {
17138 /* No need to mention EOL here--the terminal never needs
17139 to do EOL conversion. */
17140 p = decode_mode_spec_coding (FRAME_KEYBOARD_CODING (f)->symbol, p, 0);
17141 p = decode_mode_spec_coding (FRAME_TERMINAL_CODING (f)->symbol, p, 0);
17142 }
17143 p = decode_mode_spec_coding (b->buffer_file_coding_system,
17144 p, eol_flag);
17145
17146 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
17147 #ifdef subprocesses
17148 obj = Fget_buffer_process (Fcurrent_buffer ());
17149 if (PROCESSP (obj))
17150 {
17151 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
17152 p, eol_flag);
17153 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
17154 p, eol_flag);
17155 }
17156 #endif /* subprocesses */
17157 #endif /* 0 */
17158 *p = 0;
17159 return decode_mode_spec_buf;
17160 }
17161 }
17162
17163 if (STRINGP (obj))
17164 {
17165 *multibyte = STRING_MULTIBYTE (obj);
17166 return (char *) SDATA (obj);
17167 }
17168 else
17169 return "";
17170 }
17171
17172
17173 /* Count up to COUNT lines starting from START / START_BYTE.
17174 But don't go beyond LIMIT_BYTE.
17175 Return the number of lines thus found (always nonnegative).
17176
17177 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
17178
17179 static int
17180 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
17181 int start, start_byte, limit_byte, count;
17182 int *byte_pos_ptr;
17183 {
17184 register unsigned char *cursor;
17185 unsigned char *base;
17186
17187 register int ceiling;
17188 register unsigned char *ceiling_addr;
17189 int orig_count = count;
17190
17191 /* If we are not in selective display mode,
17192 check only for newlines. */
17193 int selective_display = (!NILP (current_buffer->selective_display)
17194 && !INTEGERP (current_buffer->selective_display));
17195
17196 if (count > 0)
17197 {
17198 while (start_byte < limit_byte)
17199 {
17200 ceiling = BUFFER_CEILING_OF (start_byte);
17201 ceiling = min (limit_byte - 1, ceiling);
17202 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
17203 base = (cursor = BYTE_POS_ADDR (start_byte));
17204 while (1)
17205 {
17206 if (selective_display)
17207 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
17208 ;
17209 else
17210 while (*cursor != '\n' && ++cursor != ceiling_addr)
17211 ;
17212
17213 if (cursor != ceiling_addr)
17214 {
17215 if (--count == 0)
17216 {
17217 start_byte += cursor - base + 1;
17218 *byte_pos_ptr = start_byte;
17219 return orig_count;
17220 }
17221 else
17222 if (++cursor == ceiling_addr)
17223 break;
17224 }
17225 else
17226 break;
17227 }
17228 start_byte += cursor - base;
17229 }
17230 }
17231 else
17232 {
17233 while (start_byte > limit_byte)
17234 {
17235 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
17236 ceiling = max (limit_byte, ceiling);
17237 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
17238 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
17239 while (1)
17240 {
17241 if (selective_display)
17242 while (--cursor != ceiling_addr
17243 && *cursor != '\n' && *cursor != 015)
17244 ;
17245 else
17246 while (--cursor != ceiling_addr && *cursor != '\n')
17247 ;
17248
17249 if (cursor != ceiling_addr)
17250 {
17251 if (++count == 0)
17252 {
17253 start_byte += cursor - base + 1;
17254 *byte_pos_ptr = start_byte;
17255 /* When scanning backwards, we should
17256 not count the newline posterior to which we stop. */
17257 return - orig_count - 1;
17258 }
17259 }
17260 else
17261 break;
17262 }
17263 /* Here we add 1 to compensate for the last decrement
17264 of CURSOR, which took it past the valid range. */
17265 start_byte += cursor - base + 1;
17266 }
17267 }
17268
17269 *byte_pos_ptr = limit_byte;
17270
17271 if (count < 0)
17272 return - orig_count + count;
17273 return orig_count - count;
17274
17275 }
17276
17277
17278 \f
17279 /***********************************************************************
17280 Displaying strings
17281 ***********************************************************************/
17282
17283 /* Display a NUL-terminated string, starting with index START.
17284
17285 If STRING is non-null, display that C string. Otherwise, the Lisp
17286 string LISP_STRING is displayed.
17287
17288 If FACE_STRING is not nil, FACE_STRING_POS is a position in
17289 FACE_STRING. Display STRING or LISP_STRING with the face at
17290 FACE_STRING_POS in FACE_STRING:
17291
17292 Display the string in the environment given by IT, but use the
17293 standard display table, temporarily.
17294
17295 FIELD_WIDTH is the minimum number of output glyphs to produce.
17296 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17297 with spaces. If STRING has more characters, more than FIELD_WIDTH
17298 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
17299
17300 PRECISION is the maximum number of characters to output from
17301 STRING. PRECISION < 0 means don't truncate the string.
17302
17303 This is roughly equivalent to printf format specifiers:
17304
17305 FIELD_WIDTH PRECISION PRINTF
17306 ----------------------------------------
17307 -1 -1 %s
17308 -1 10 %.10s
17309 10 -1 %10s
17310 20 10 %20.10s
17311
17312 MULTIBYTE zero means do not display multibyte chars, > 0 means do
17313 display them, and < 0 means obey the current buffer's value of
17314 enable_multibyte_characters.
17315
17316 Value is the number of glyphs produced. */
17317
17318 static int
17319 display_string (string, lisp_string, face_string, face_string_pos,
17320 start, it, field_width, precision, max_x, multibyte)
17321 unsigned char *string;
17322 Lisp_Object lisp_string;
17323 Lisp_Object face_string;
17324 int face_string_pos;
17325 int start;
17326 struct it *it;
17327 int field_width, precision, max_x;
17328 int multibyte;
17329 {
17330 int hpos_at_start = it->hpos;
17331 int saved_face_id = it->face_id;
17332 struct glyph_row *row = it->glyph_row;
17333
17334 /* Initialize the iterator IT for iteration over STRING beginning
17335 with index START. */
17336 reseat_to_string (it, string, lisp_string, start,
17337 precision, field_width, multibyte);
17338
17339 /* If displaying STRING, set up the face of the iterator
17340 from LISP_STRING, if that's given. */
17341 if (STRINGP (face_string))
17342 {
17343 int endptr;
17344 struct face *face;
17345
17346 it->face_id
17347 = face_at_string_position (it->w, face_string, face_string_pos,
17348 0, it->region_beg_charpos,
17349 it->region_end_charpos,
17350 &endptr, it->base_face_id, 0);
17351 face = FACE_FROM_ID (it->f, it->face_id);
17352 it->face_box_p = face->box != FACE_NO_BOX;
17353 }
17354
17355 /* Set max_x to the maximum allowed X position. Don't let it go
17356 beyond the right edge of the window. */
17357 if (max_x <= 0)
17358 max_x = it->last_visible_x;
17359 else
17360 max_x = min (max_x, it->last_visible_x);
17361
17362 /* Skip over display elements that are not visible. because IT->w is
17363 hscrolled. */
17364 if (it->current_x < it->first_visible_x)
17365 move_it_in_display_line_to (it, 100000, it->first_visible_x,
17366 MOVE_TO_POS | MOVE_TO_X);
17367
17368 row->ascent = it->max_ascent;
17369 row->height = it->max_ascent + it->max_descent;
17370 row->phys_ascent = it->max_phys_ascent;
17371 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17372 row->extra_line_spacing = it->max_extra_line_spacing;
17373
17374 /* This condition is for the case that we are called with current_x
17375 past last_visible_x. */
17376 while (it->current_x < max_x)
17377 {
17378 int x_before, x, n_glyphs_before, i, nglyphs;
17379
17380 /* Get the next display element. */
17381 if (!get_next_display_element (it))
17382 break;
17383
17384 /* Produce glyphs. */
17385 x_before = it->current_x;
17386 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
17387 PRODUCE_GLYPHS (it);
17388
17389 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
17390 i = 0;
17391 x = x_before;
17392 while (i < nglyphs)
17393 {
17394 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17395
17396 if (!it->truncate_lines_p
17397 && x + glyph->pixel_width > max_x)
17398 {
17399 /* End of continued line or max_x reached. */
17400 if (CHAR_GLYPH_PADDING_P (*glyph))
17401 {
17402 /* A wide character is unbreakable. */
17403 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
17404 it->current_x = x_before;
17405 }
17406 else
17407 {
17408 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
17409 it->current_x = x;
17410 }
17411 break;
17412 }
17413 else if (x + glyph->pixel_width > it->first_visible_x)
17414 {
17415 /* Glyph is at least partially visible. */
17416 ++it->hpos;
17417 if (x < it->first_visible_x)
17418 it->glyph_row->x = x - it->first_visible_x;
17419 }
17420 else
17421 {
17422 /* Glyph is off the left margin of the display area.
17423 Should not happen. */
17424 abort ();
17425 }
17426
17427 row->ascent = max (row->ascent, it->max_ascent);
17428 row->height = max (row->height, it->max_ascent + it->max_descent);
17429 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17430 row->phys_height = max (row->phys_height,
17431 it->max_phys_ascent + it->max_phys_descent);
17432 row->extra_line_spacing = max (row->extra_line_spacing,
17433 it->max_extra_line_spacing);
17434 x += glyph->pixel_width;
17435 ++i;
17436 }
17437
17438 /* Stop if max_x reached. */
17439 if (i < nglyphs)
17440 break;
17441
17442 /* Stop at line ends. */
17443 if (ITERATOR_AT_END_OF_LINE_P (it))
17444 {
17445 it->continuation_lines_width = 0;
17446 break;
17447 }
17448
17449 set_iterator_to_next (it, 1);
17450
17451 /* Stop if truncating at the right edge. */
17452 if (it->truncate_lines_p
17453 && it->current_x >= it->last_visible_x)
17454 {
17455 /* Add truncation mark, but don't do it if the line is
17456 truncated at a padding space. */
17457 if (IT_CHARPOS (*it) < it->string_nchars)
17458 {
17459 if (!FRAME_WINDOW_P (it->f))
17460 {
17461 int i, n;
17462
17463 if (it->current_x > it->last_visible_x)
17464 {
17465 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17466 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17467 break;
17468 for (n = row->used[TEXT_AREA]; i < n; ++i)
17469 {
17470 row->used[TEXT_AREA] = i;
17471 produce_special_glyphs (it, IT_TRUNCATION);
17472 }
17473 }
17474 produce_special_glyphs (it, IT_TRUNCATION);
17475 }
17476 it->glyph_row->truncated_on_right_p = 1;
17477 }
17478 break;
17479 }
17480 }
17481
17482 /* Maybe insert a truncation at the left. */
17483 if (it->first_visible_x
17484 && IT_CHARPOS (*it) > 0)
17485 {
17486 if (!FRAME_WINDOW_P (it->f))
17487 insert_left_trunc_glyphs (it);
17488 it->glyph_row->truncated_on_left_p = 1;
17489 }
17490
17491 it->face_id = saved_face_id;
17492
17493 /* Value is number of columns displayed. */
17494 return it->hpos - hpos_at_start;
17495 }
17496
17497
17498 \f
17499 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17500 appears as an element of LIST or as the car of an element of LIST.
17501 If PROPVAL is a list, compare each element against LIST in that
17502 way, and return 1/2 if any element of PROPVAL is found in LIST.
17503 Otherwise return 0. This function cannot quit.
17504 The return value is 2 if the text is invisible but with an ellipsis
17505 and 1 if it's invisible and without an ellipsis. */
17506
17507 int
17508 invisible_p (propval, list)
17509 register Lisp_Object propval;
17510 Lisp_Object list;
17511 {
17512 register Lisp_Object tail, proptail;
17513
17514 for (tail = list; CONSP (tail); tail = XCDR (tail))
17515 {
17516 register Lisp_Object tem;
17517 tem = XCAR (tail);
17518 if (EQ (propval, tem))
17519 return 1;
17520 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17521 return NILP (XCDR (tem)) ? 1 : 2;
17522 }
17523
17524 if (CONSP (propval))
17525 {
17526 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17527 {
17528 Lisp_Object propelt;
17529 propelt = XCAR (proptail);
17530 for (tail = list; CONSP (tail); tail = XCDR (tail))
17531 {
17532 register Lisp_Object tem;
17533 tem = XCAR (tail);
17534 if (EQ (propelt, tem))
17535 return 1;
17536 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17537 return NILP (XCDR (tem)) ? 1 : 2;
17538 }
17539 }
17540 }
17541
17542 return 0;
17543 }
17544
17545 /* Calculate a width or height in pixels from a specification using
17546 the following elements:
17547
17548 SPEC ::=
17549 NUM - a (fractional) multiple of the default font width/height
17550 (NUM) - specifies exactly NUM pixels
17551 UNIT - a fixed number of pixels, see below.
17552 ELEMENT - size of a display element in pixels, see below.
17553 (NUM . SPEC) - equals NUM * SPEC
17554 (+ SPEC SPEC ...) - add pixel values
17555 (- SPEC SPEC ...) - subtract pixel values
17556 (- SPEC) - negate pixel value
17557
17558 NUM ::=
17559 INT or FLOAT - a number constant
17560 SYMBOL - use symbol's (buffer local) variable binding.
17561
17562 UNIT ::=
17563 in - pixels per inch *)
17564 mm - pixels per 1/1000 meter *)
17565 cm - pixels per 1/100 meter *)
17566 width - width of current font in pixels.
17567 height - height of current font in pixels.
17568
17569 *) using the ratio(s) defined in display-pixels-per-inch.
17570
17571 ELEMENT ::=
17572
17573 left-fringe - left fringe width in pixels
17574 right-fringe - right fringe width in pixels
17575
17576 left-margin - left margin width in pixels
17577 right-margin - right margin width in pixels
17578
17579 scroll-bar - scroll-bar area width in pixels
17580
17581 Examples:
17582
17583 Pixels corresponding to 5 inches:
17584 (5 . in)
17585
17586 Total width of non-text areas on left side of window (if scroll-bar is on left):
17587 '(space :width (+ left-fringe left-margin scroll-bar))
17588
17589 Align to first text column (in header line):
17590 '(space :align-to 0)
17591
17592 Align to middle of text area minus half the width of variable `my-image'
17593 containing a loaded image:
17594 '(space :align-to (0.5 . (- text my-image)))
17595
17596 Width of left margin minus width of 1 character in the default font:
17597 '(space :width (- left-margin 1))
17598
17599 Width of left margin minus width of 2 characters in the current font:
17600 '(space :width (- left-margin (2 . width)))
17601
17602 Center 1 character over left-margin (in header line):
17603 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17604
17605 Different ways to express width of left fringe plus left margin minus one pixel:
17606 '(space :width (- (+ left-fringe left-margin) (1)))
17607 '(space :width (+ left-fringe left-margin (- (1))))
17608 '(space :width (+ left-fringe left-margin (-1)))
17609
17610 */
17611
17612 #define NUMVAL(X) \
17613 ((INTEGERP (X) || FLOATP (X)) \
17614 ? XFLOATINT (X) \
17615 : - 1)
17616
17617 int
17618 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17619 double *res;
17620 struct it *it;
17621 Lisp_Object prop;
17622 void *font;
17623 int width_p, *align_to;
17624 {
17625 double pixels;
17626
17627 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17628 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17629
17630 if (NILP (prop))
17631 return OK_PIXELS (0);
17632
17633 if (SYMBOLP (prop))
17634 {
17635 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17636 {
17637 char *unit = SDATA (SYMBOL_NAME (prop));
17638
17639 if (unit[0] == 'i' && unit[1] == 'n')
17640 pixels = 1.0;
17641 else if (unit[0] == 'm' && unit[1] == 'm')
17642 pixels = 25.4;
17643 else if (unit[0] == 'c' && unit[1] == 'm')
17644 pixels = 2.54;
17645 else
17646 pixels = 0;
17647 if (pixels > 0)
17648 {
17649 double ppi;
17650 #ifdef HAVE_WINDOW_SYSTEM
17651 if (FRAME_WINDOW_P (it->f)
17652 && (ppi = (width_p
17653 ? FRAME_X_DISPLAY_INFO (it->f)->resx
17654 : FRAME_X_DISPLAY_INFO (it->f)->resy),
17655 ppi > 0))
17656 return OK_PIXELS (ppi / pixels);
17657 #endif
17658
17659 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17660 || (CONSP (Vdisplay_pixels_per_inch)
17661 && (ppi = (width_p
17662 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17663 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17664 ppi > 0)))
17665 return OK_PIXELS (ppi / pixels);
17666
17667 return 0;
17668 }
17669 }
17670
17671 #ifdef HAVE_WINDOW_SYSTEM
17672 if (EQ (prop, Qheight))
17673 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17674 if (EQ (prop, Qwidth))
17675 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17676 #else
17677 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17678 return OK_PIXELS (1);
17679 #endif
17680
17681 if (EQ (prop, Qtext))
17682 return OK_PIXELS (width_p
17683 ? window_box_width (it->w, TEXT_AREA)
17684 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17685
17686 if (align_to && *align_to < 0)
17687 {
17688 *res = 0;
17689 if (EQ (prop, Qleft))
17690 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17691 if (EQ (prop, Qright))
17692 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17693 if (EQ (prop, Qcenter))
17694 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17695 + window_box_width (it->w, TEXT_AREA) / 2);
17696 if (EQ (prop, Qleft_fringe))
17697 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17698 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17699 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17700 if (EQ (prop, Qright_fringe))
17701 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17702 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17703 : window_box_right_offset (it->w, TEXT_AREA));
17704 if (EQ (prop, Qleft_margin))
17705 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17706 if (EQ (prop, Qright_margin))
17707 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17708 if (EQ (prop, Qscroll_bar))
17709 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17710 ? 0
17711 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17712 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17713 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17714 : 0)));
17715 }
17716 else
17717 {
17718 if (EQ (prop, Qleft_fringe))
17719 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17720 if (EQ (prop, Qright_fringe))
17721 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17722 if (EQ (prop, Qleft_margin))
17723 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17724 if (EQ (prop, Qright_margin))
17725 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17726 if (EQ (prop, Qscroll_bar))
17727 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17728 }
17729
17730 prop = Fbuffer_local_value (prop, it->w->buffer);
17731 }
17732
17733 if (INTEGERP (prop) || FLOATP (prop))
17734 {
17735 int base_unit = (width_p
17736 ? FRAME_COLUMN_WIDTH (it->f)
17737 : FRAME_LINE_HEIGHT (it->f));
17738 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17739 }
17740
17741 if (CONSP (prop))
17742 {
17743 Lisp_Object car = XCAR (prop);
17744 Lisp_Object cdr = XCDR (prop);
17745
17746 if (SYMBOLP (car))
17747 {
17748 #ifdef HAVE_WINDOW_SYSTEM
17749 if (valid_image_p (prop))
17750 {
17751 int id = lookup_image (it->f, prop);
17752 struct image *img = IMAGE_FROM_ID (it->f, id);
17753
17754 return OK_PIXELS (width_p ? img->width : img->height);
17755 }
17756 #endif
17757 if (EQ (car, Qplus) || EQ (car, Qminus))
17758 {
17759 int first = 1;
17760 double px;
17761
17762 pixels = 0;
17763 while (CONSP (cdr))
17764 {
17765 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17766 font, width_p, align_to))
17767 return 0;
17768 if (first)
17769 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17770 else
17771 pixels += px;
17772 cdr = XCDR (cdr);
17773 }
17774 if (EQ (car, Qminus))
17775 pixels = -pixels;
17776 return OK_PIXELS (pixels);
17777 }
17778
17779 car = Fbuffer_local_value (car, it->w->buffer);
17780 }
17781
17782 if (INTEGERP (car) || FLOATP (car))
17783 {
17784 double fact;
17785 pixels = XFLOATINT (car);
17786 if (NILP (cdr))
17787 return OK_PIXELS (pixels);
17788 if (calc_pixel_width_or_height (&fact, it, cdr,
17789 font, width_p, align_to))
17790 return OK_PIXELS (pixels * fact);
17791 return 0;
17792 }
17793
17794 return 0;
17795 }
17796
17797 return 0;
17798 }
17799
17800 \f
17801 /***********************************************************************
17802 Glyph Display
17803 ***********************************************************************/
17804
17805 #ifdef HAVE_WINDOW_SYSTEM
17806
17807 #if GLYPH_DEBUG
17808
17809 void
17810 dump_glyph_string (s)
17811 struct glyph_string *s;
17812 {
17813 fprintf (stderr, "glyph string\n");
17814 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17815 s->x, s->y, s->width, s->height);
17816 fprintf (stderr, " ybase = %d\n", s->ybase);
17817 fprintf (stderr, " hl = %d\n", s->hl);
17818 fprintf (stderr, " left overhang = %d, right = %d\n",
17819 s->left_overhang, s->right_overhang);
17820 fprintf (stderr, " nchars = %d\n", s->nchars);
17821 fprintf (stderr, " extends to end of line = %d\n",
17822 s->extends_to_end_of_line_p);
17823 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17824 fprintf (stderr, " bg width = %d\n", s->background_width);
17825 }
17826
17827 #endif /* GLYPH_DEBUG */
17828
17829 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17830 of XChar2b structures for S; it can't be allocated in
17831 init_glyph_string because it must be allocated via `alloca'. W
17832 is the window on which S is drawn. ROW and AREA are the glyph row
17833 and area within the row from which S is constructed. START is the
17834 index of the first glyph structure covered by S. HL is a
17835 face-override for drawing S. */
17836
17837 #ifdef HAVE_NTGUI
17838 #define OPTIONAL_HDC(hdc) hdc,
17839 #define DECLARE_HDC(hdc) HDC hdc;
17840 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17841 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17842 #endif
17843
17844 #ifndef OPTIONAL_HDC
17845 #define OPTIONAL_HDC(hdc)
17846 #define DECLARE_HDC(hdc)
17847 #define ALLOCATE_HDC(hdc, f)
17848 #define RELEASE_HDC(hdc, f)
17849 #endif
17850
17851 static void
17852 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17853 struct glyph_string *s;
17854 DECLARE_HDC (hdc)
17855 XChar2b *char2b;
17856 struct window *w;
17857 struct glyph_row *row;
17858 enum glyph_row_area area;
17859 int start;
17860 enum draw_glyphs_face hl;
17861 {
17862 bzero (s, sizeof *s);
17863 s->w = w;
17864 s->f = XFRAME (w->frame);
17865 #ifdef HAVE_NTGUI
17866 s->hdc = hdc;
17867 #endif
17868 s->display = FRAME_X_DISPLAY (s->f);
17869 s->window = FRAME_X_WINDOW (s->f);
17870 s->char2b = char2b;
17871 s->hl = hl;
17872 s->row = row;
17873 s->area = area;
17874 s->first_glyph = row->glyphs[area] + start;
17875 s->height = row->height;
17876 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17877
17878 /* Display the internal border below the tool-bar window. */
17879 if (WINDOWP (s->f->tool_bar_window)
17880 && s->w == XWINDOW (s->f->tool_bar_window))
17881 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17882
17883 s->ybase = s->y + row->ascent;
17884 }
17885
17886
17887 /* Append the list of glyph strings with head H and tail T to the list
17888 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17889
17890 static INLINE void
17891 append_glyph_string_lists (head, tail, h, t)
17892 struct glyph_string **head, **tail;
17893 struct glyph_string *h, *t;
17894 {
17895 if (h)
17896 {
17897 if (*head)
17898 (*tail)->next = h;
17899 else
17900 *head = h;
17901 h->prev = *tail;
17902 *tail = t;
17903 }
17904 }
17905
17906
17907 /* Prepend the list of glyph strings with head H and tail T to the
17908 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17909 result. */
17910
17911 static INLINE void
17912 prepend_glyph_string_lists (head, tail, h, t)
17913 struct glyph_string **head, **tail;
17914 struct glyph_string *h, *t;
17915 {
17916 if (h)
17917 {
17918 if (*head)
17919 (*head)->prev = t;
17920 else
17921 *tail = t;
17922 t->next = *head;
17923 *head = h;
17924 }
17925 }
17926
17927
17928 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17929 Set *HEAD and *TAIL to the resulting list. */
17930
17931 static INLINE void
17932 append_glyph_string (head, tail, s)
17933 struct glyph_string **head, **tail;
17934 struct glyph_string *s;
17935 {
17936 s->next = s->prev = NULL;
17937 append_glyph_string_lists (head, tail, s, s);
17938 }
17939
17940
17941 /* Get face and two-byte form of character glyph GLYPH on frame F.
17942 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17943 a pointer to a realized face that is ready for display. */
17944
17945 static INLINE struct face *
17946 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17947 struct frame *f;
17948 struct glyph *glyph;
17949 XChar2b *char2b;
17950 int *two_byte_p;
17951 {
17952 struct face *face;
17953
17954 xassert (glyph->type == CHAR_GLYPH);
17955 face = FACE_FROM_ID (f, glyph->face_id);
17956
17957 if (two_byte_p)
17958 *two_byte_p = 0;
17959
17960 if (!glyph->multibyte_p)
17961 {
17962 /* Unibyte case. We don't have to encode, but we have to make
17963 sure to use a face suitable for unibyte. */
17964 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17965 }
17966 else if (glyph->u.ch < 128
17967 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17968 {
17969 /* Case of ASCII in a face known to fit ASCII. */
17970 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17971 }
17972 else
17973 {
17974 int c1, c2, charset;
17975
17976 /* Split characters into bytes. If c2 is -1 afterwards, C is
17977 really a one-byte character so that byte1 is zero. */
17978 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17979 if (c2 > 0)
17980 STORE_XCHAR2B (char2b, c1, c2);
17981 else
17982 STORE_XCHAR2B (char2b, 0, c1);
17983
17984 /* Maybe encode the character in *CHAR2B. */
17985 if (charset != CHARSET_ASCII)
17986 {
17987 struct font_info *font_info
17988 = FONT_INFO_FROM_ID (f, face->font_info_id);
17989 if (font_info)
17990 glyph->font_type
17991 = FRAME_RIF (f)->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17992 }
17993 }
17994
17995 /* Make sure X resources of the face are allocated. */
17996 xassert (face != NULL);
17997 PREPARE_FACE_FOR_DISPLAY (f, face);
17998 return face;
17999 }
18000
18001
18002 /* Fill glyph string S with composition components specified by S->cmp.
18003
18004 FACES is an array of faces for all components of this composition.
18005 S->gidx is the index of the first component for S.
18006 OVERLAPS_P non-zero means S should draw the foreground only, and
18007 use its physical height for clipping.
18008
18009 Value is the index of a component not in S. */
18010
18011 static int
18012 fill_composite_glyph_string (s, faces, overlaps_p)
18013 struct glyph_string *s;
18014 struct face **faces;
18015 int overlaps_p;
18016 {
18017 int i;
18018
18019 xassert (s);
18020
18021 s->for_overlaps_p = overlaps_p;
18022
18023 s->face = faces[s->gidx];
18024 s->font = s->face->font;
18025 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18026
18027 /* For all glyphs of this composition, starting at the offset
18028 S->gidx, until we reach the end of the definition or encounter a
18029 glyph that requires the different face, add it to S. */
18030 ++s->nchars;
18031 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
18032 ++s->nchars;
18033
18034 /* All glyph strings for the same composition has the same width,
18035 i.e. the width set for the first component of the composition. */
18036
18037 s->width = s->first_glyph->pixel_width;
18038
18039 /* If the specified font could not be loaded, use the frame's
18040 default font, but record the fact that we couldn't load it in
18041 the glyph string so that we can draw rectangles for the
18042 characters of the glyph string. */
18043 if (s->font == NULL)
18044 {
18045 s->font_not_found_p = 1;
18046 s->font = FRAME_FONT (s->f);
18047 }
18048
18049 /* Adjust base line for subscript/superscript text. */
18050 s->ybase += s->first_glyph->voffset;
18051
18052 xassert (s->face && s->face->gc);
18053
18054 /* This glyph string must always be drawn with 16-bit functions. */
18055 s->two_byte_p = 1;
18056
18057 return s->gidx + s->nchars;
18058 }
18059
18060
18061 /* Fill glyph string S from a sequence of character glyphs.
18062
18063 FACE_ID is the face id of the string. START is the index of the
18064 first glyph to consider, END is the index of the last + 1.
18065 OVERLAPS_P non-zero means S should draw the foreground only, and
18066 use its physical height for clipping.
18067
18068 Value is the index of the first glyph not in S. */
18069
18070 static int
18071 fill_glyph_string (s, face_id, start, end, overlaps_p)
18072 struct glyph_string *s;
18073 int face_id;
18074 int start, end, overlaps_p;
18075 {
18076 struct glyph *glyph, *last;
18077 int voffset;
18078 int glyph_not_available_p;
18079
18080 xassert (s->f == XFRAME (s->w->frame));
18081 xassert (s->nchars == 0);
18082 xassert (start >= 0 && end > start);
18083
18084 s->for_overlaps_p = overlaps_p,
18085 glyph = s->row->glyphs[s->area] + start;
18086 last = s->row->glyphs[s->area] + end;
18087 voffset = glyph->voffset;
18088
18089 glyph_not_available_p = glyph->glyph_not_available_p;
18090
18091 while (glyph < last
18092 && glyph->type == CHAR_GLYPH
18093 && glyph->voffset == voffset
18094 /* Same face id implies same font, nowadays. */
18095 && glyph->face_id == face_id
18096 && glyph->glyph_not_available_p == glyph_not_available_p)
18097 {
18098 int two_byte_p;
18099
18100 s->face = get_glyph_face_and_encoding (s->f, glyph,
18101 s->char2b + s->nchars,
18102 &two_byte_p);
18103 s->two_byte_p = two_byte_p;
18104 ++s->nchars;
18105 xassert (s->nchars <= end - start);
18106 s->width += glyph->pixel_width;
18107 ++glyph;
18108 }
18109
18110 s->font = s->face->font;
18111 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18112
18113 /* If the specified font could not be loaded, use the frame's font,
18114 but record the fact that we couldn't load it in
18115 S->font_not_found_p so that we can draw rectangles for the
18116 characters of the glyph string. */
18117 if (s->font == NULL || glyph_not_available_p)
18118 {
18119 s->font_not_found_p = 1;
18120 s->font = FRAME_FONT (s->f);
18121 }
18122
18123 /* Adjust base line for subscript/superscript text. */
18124 s->ybase += voffset;
18125
18126 xassert (s->face && s->face->gc);
18127 return glyph - s->row->glyphs[s->area];
18128 }
18129
18130
18131 /* Fill glyph string S from image glyph S->first_glyph. */
18132
18133 static void
18134 fill_image_glyph_string (s)
18135 struct glyph_string *s;
18136 {
18137 xassert (s->first_glyph->type == IMAGE_GLYPH);
18138 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
18139 xassert (s->img);
18140 s->slice = s->first_glyph->slice;
18141 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
18142 s->font = s->face->font;
18143 s->width = s->first_glyph->pixel_width;
18144
18145 /* Adjust base line for subscript/superscript text. */
18146 s->ybase += s->first_glyph->voffset;
18147 }
18148
18149
18150 /* Fill glyph string S from a sequence of stretch glyphs.
18151
18152 ROW is the glyph row in which the glyphs are found, AREA is the
18153 area within the row. START is the index of the first glyph to
18154 consider, END is the index of the last + 1.
18155
18156 Value is the index of the first glyph not in S. */
18157
18158 static int
18159 fill_stretch_glyph_string (s, row, area, start, end)
18160 struct glyph_string *s;
18161 struct glyph_row *row;
18162 enum glyph_row_area area;
18163 int start, end;
18164 {
18165 struct glyph *glyph, *last;
18166 int voffset, face_id;
18167
18168 xassert (s->first_glyph->type == STRETCH_GLYPH);
18169
18170 glyph = s->row->glyphs[s->area] + start;
18171 last = s->row->glyphs[s->area] + end;
18172 face_id = glyph->face_id;
18173 s->face = FACE_FROM_ID (s->f, face_id);
18174 s->font = s->face->font;
18175 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18176 s->width = glyph->pixel_width;
18177 voffset = glyph->voffset;
18178
18179 for (++glyph;
18180 (glyph < last
18181 && glyph->type == STRETCH_GLYPH
18182 && glyph->voffset == voffset
18183 && glyph->face_id == face_id);
18184 ++glyph)
18185 s->width += glyph->pixel_width;
18186
18187 /* Adjust base line for subscript/superscript text. */
18188 s->ybase += voffset;
18189
18190 /* The case that face->gc == 0 is handled when drawing the glyph
18191 string by calling PREPARE_FACE_FOR_DISPLAY. */
18192 xassert (s->face);
18193 return glyph - s->row->glyphs[s->area];
18194 }
18195
18196
18197 /* EXPORT for RIF:
18198 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
18199 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
18200 assumed to be zero. */
18201
18202 void
18203 x_get_glyph_overhangs (glyph, f, left, right)
18204 struct glyph *glyph;
18205 struct frame *f;
18206 int *left, *right;
18207 {
18208 *left = *right = 0;
18209
18210 if (glyph->type == CHAR_GLYPH)
18211 {
18212 XFontStruct *font;
18213 struct face *face;
18214 struct font_info *font_info;
18215 XChar2b char2b;
18216 XCharStruct *pcm;
18217
18218 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
18219 font = face->font;
18220 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
18221 if (font /* ++KFS: Should this be font_info ? */
18222 && (pcm = FRAME_RIF (f)->per_char_metric (font, &char2b, glyph->font_type)))
18223 {
18224 if (pcm->rbearing > pcm->width)
18225 *right = pcm->rbearing - pcm->width;
18226 if (pcm->lbearing < 0)
18227 *left = -pcm->lbearing;
18228 }
18229 }
18230 }
18231
18232
18233 /* Return the index of the first glyph preceding glyph string S that
18234 is overwritten by S because of S's left overhang. Value is -1
18235 if no glyphs are overwritten. */
18236
18237 static int
18238 left_overwritten (s)
18239 struct glyph_string *s;
18240 {
18241 int k;
18242
18243 if (s->left_overhang)
18244 {
18245 int x = 0, i;
18246 struct glyph *glyphs = s->row->glyphs[s->area];
18247 int first = s->first_glyph - glyphs;
18248
18249 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
18250 x -= glyphs[i].pixel_width;
18251
18252 k = i + 1;
18253 }
18254 else
18255 k = -1;
18256
18257 return k;
18258 }
18259
18260
18261 /* Return the index of the first glyph preceding glyph string S that
18262 is overwriting S because of its right overhang. Value is -1 if no
18263 glyph in front of S overwrites S. */
18264
18265 static int
18266 left_overwriting (s)
18267 struct glyph_string *s;
18268 {
18269 int i, k, x;
18270 struct glyph *glyphs = s->row->glyphs[s->area];
18271 int first = s->first_glyph - glyphs;
18272
18273 k = -1;
18274 x = 0;
18275 for (i = first - 1; i >= 0; --i)
18276 {
18277 int left, right;
18278 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18279 if (x + right > 0)
18280 k = i;
18281 x -= glyphs[i].pixel_width;
18282 }
18283
18284 return k;
18285 }
18286
18287
18288 /* Return the index of the last glyph following glyph string S that is
18289 not overwritten by S because of S's right overhang. Value is -1 if
18290 no such glyph is found. */
18291
18292 static int
18293 right_overwritten (s)
18294 struct glyph_string *s;
18295 {
18296 int k = -1;
18297
18298 if (s->right_overhang)
18299 {
18300 int x = 0, i;
18301 struct glyph *glyphs = s->row->glyphs[s->area];
18302 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18303 int end = s->row->used[s->area];
18304
18305 for (i = first; i < end && s->right_overhang > x; ++i)
18306 x += glyphs[i].pixel_width;
18307
18308 k = i;
18309 }
18310
18311 return k;
18312 }
18313
18314
18315 /* Return the index of the last glyph following glyph string S that
18316 overwrites S because of its left overhang. Value is negative
18317 if no such glyph is found. */
18318
18319 static int
18320 right_overwriting (s)
18321 struct glyph_string *s;
18322 {
18323 int i, k, x;
18324 int end = s->row->used[s->area];
18325 struct glyph *glyphs = s->row->glyphs[s->area];
18326 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18327
18328 k = -1;
18329 x = 0;
18330 for (i = first; i < end; ++i)
18331 {
18332 int left, right;
18333 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18334 if (x - left < 0)
18335 k = i;
18336 x += glyphs[i].pixel_width;
18337 }
18338
18339 return k;
18340 }
18341
18342
18343 /* Get face and two-byte form of character C in face FACE_ID on frame
18344 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18345 means we want to display multibyte text. DISPLAY_P non-zero means
18346 make sure that X resources for the face returned are allocated.
18347 Value is a pointer to a realized face that is ready for display if
18348 DISPLAY_P is non-zero. */
18349
18350 static INLINE struct face *
18351 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
18352 struct frame *f;
18353 int c, face_id;
18354 XChar2b *char2b;
18355 int multibyte_p, display_p;
18356 {
18357 struct face *face = FACE_FROM_ID (f, face_id);
18358
18359 if (!multibyte_p)
18360 {
18361 /* Unibyte case. We don't have to encode, but we have to make
18362 sure to use a face suitable for unibyte. */
18363 STORE_XCHAR2B (char2b, 0, c);
18364 face_id = FACE_FOR_CHAR (f, face, c);
18365 face = FACE_FROM_ID (f, face_id);
18366 }
18367 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
18368 {
18369 /* Case of ASCII in a face known to fit ASCII. */
18370 STORE_XCHAR2B (char2b, 0, c);
18371 }
18372 else
18373 {
18374 int c1, c2, charset;
18375
18376 /* Split characters into bytes. If c2 is -1 afterwards, C is
18377 really a one-byte character so that byte1 is zero. */
18378 SPLIT_CHAR (c, charset, c1, c2);
18379 if (c2 > 0)
18380 STORE_XCHAR2B (char2b, c1, c2);
18381 else
18382 STORE_XCHAR2B (char2b, 0, c1);
18383
18384 /* Maybe encode the character in *CHAR2B. */
18385 if (face->font != NULL)
18386 {
18387 struct font_info *font_info
18388 = FONT_INFO_FROM_ID (f, face->font_info_id);
18389 if (font_info)
18390 FRAME_RIF (f)->encode_char (c, char2b, font_info, 0);
18391 }
18392 }
18393
18394 /* Make sure X resources of the face are allocated. */
18395 #ifdef HAVE_X_WINDOWS
18396 if (display_p)
18397 #endif
18398 {
18399 xassert (face != NULL);
18400 PREPARE_FACE_FOR_DISPLAY (f, face);
18401 }
18402
18403 return face;
18404 }
18405
18406
18407 /* Set background width of glyph string S. START is the index of the
18408 first glyph following S. LAST_X is the right-most x-position + 1
18409 in the drawing area. */
18410
18411 static INLINE void
18412 set_glyph_string_background_width (s, start, last_x)
18413 struct glyph_string *s;
18414 int start;
18415 int last_x;
18416 {
18417 /* If the face of this glyph string has to be drawn to the end of
18418 the drawing area, set S->extends_to_end_of_line_p. */
18419 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
18420
18421 if (start == s->row->used[s->area]
18422 && s->area == TEXT_AREA
18423 && ((s->hl == DRAW_NORMAL_TEXT
18424 && (s->row->fill_line_p
18425 || s->face->background != default_face->background
18426 || s->face->stipple != default_face->stipple
18427 || s->row->mouse_face_p))
18428 || s->hl == DRAW_MOUSE_FACE
18429 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
18430 && s->row->fill_line_p)))
18431 s->extends_to_end_of_line_p = 1;
18432
18433 /* If S extends its face to the end of the line, set its
18434 background_width to the distance to the right edge of the drawing
18435 area. */
18436 if (s->extends_to_end_of_line_p)
18437 s->background_width = last_x - s->x + 1;
18438 else
18439 s->background_width = s->width;
18440 }
18441
18442
18443 /* Compute overhangs and x-positions for glyph string S and its
18444 predecessors, or successors. X is the starting x-position for S.
18445 BACKWARD_P non-zero means process predecessors. */
18446
18447 static void
18448 compute_overhangs_and_x (s, x, backward_p)
18449 struct glyph_string *s;
18450 int x;
18451 int backward_p;
18452 {
18453 if (backward_p)
18454 {
18455 while (s)
18456 {
18457 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
18458 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
18459 x -= s->width;
18460 s->x = x;
18461 s = s->prev;
18462 }
18463 }
18464 else
18465 {
18466 while (s)
18467 {
18468 if (FRAME_RIF (s->f)->compute_glyph_string_overhangs)
18469 FRAME_RIF (s->f)->compute_glyph_string_overhangs (s);
18470 s->x = x;
18471 x += s->width;
18472 s = s->next;
18473 }
18474 }
18475 }
18476
18477
18478
18479 /* The following macros are only called from draw_glyphs below.
18480 They reference the following parameters of that function directly:
18481 `w', `row', `area', and `overlap_p'
18482 as well as the following local variables:
18483 `s', `f', and `hdc' (in W32) */
18484
18485 #ifdef HAVE_NTGUI
18486 /* On W32, silently add local `hdc' variable to argument list of
18487 init_glyph_string. */
18488 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18489 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
18490 #else
18491 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18492 init_glyph_string (s, char2b, w, row, area, start, hl)
18493 #endif
18494
18495 /* Add a glyph string for a stretch glyph to the list of strings
18496 between HEAD and TAIL. START is the index of the stretch glyph in
18497 row area AREA of glyph row ROW. END is the index of the last glyph
18498 in that glyph row area. X is the current output position assigned
18499 to the new glyph string constructed. HL overrides that face of the
18500 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18501 is the right-most x-position of the drawing area. */
18502
18503 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
18504 and below -- keep them on one line. */
18505 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18506 do \
18507 { \
18508 s = (struct glyph_string *) alloca (sizeof *s); \
18509 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18510 START = fill_stretch_glyph_string (s, row, area, START, END); \
18511 append_glyph_string (&HEAD, &TAIL, s); \
18512 s->x = (X); \
18513 } \
18514 while (0)
18515
18516
18517 /* Add a glyph string for an image glyph to the list of strings
18518 between HEAD and TAIL. START is the index of the image glyph in
18519 row area AREA of glyph row ROW. END is the index of the last glyph
18520 in that glyph row area. X is the current output position assigned
18521 to the new glyph string constructed. HL overrides that face of the
18522 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18523 is the right-most x-position of the drawing area. */
18524
18525 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18526 do \
18527 { \
18528 s = (struct glyph_string *) alloca (sizeof *s); \
18529 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18530 fill_image_glyph_string (s); \
18531 append_glyph_string (&HEAD, &TAIL, s); \
18532 ++START; \
18533 s->x = (X); \
18534 } \
18535 while (0)
18536
18537
18538 /* Add a glyph string for a sequence of character glyphs to the list
18539 of strings between HEAD and TAIL. START is the index of the first
18540 glyph in row area AREA of glyph row ROW that is part of the new
18541 glyph string. END is the index of the last glyph in that glyph row
18542 area. X is the current output position assigned to the new glyph
18543 string constructed. HL overrides that face of the glyph; e.g. it
18544 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18545 right-most x-position of the drawing area. */
18546
18547 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18548 do \
18549 { \
18550 int c, face_id; \
18551 XChar2b *char2b; \
18552 \
18553 c = (row)->glyphs[area][START].u.ch; \
18554 face_id = (row)->glyphs[area][START].face_id; \
18555 \
18556 s = (struct glyph_string *) alloca (sizeof *s); \
18557 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18558 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18559 append_glyph_string (&HEAD, &TAIL, s); \
18560 s->x = (X); \
18561 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18562 } \
18563 while (0)
18564
18565
18566 /* Add a glyph string for a composite sequence to the list of strings
18567 between HEAD and TAIL. START is the index of the first glyph in
18568 row area AREA of glyph row ROW that is part of the new glyph
18569 string. END is the index of the last glyph in that glyph row area.
18570 X is the current output position assigned to the new glyph string
18571 constructed. HL overrides that face of the glyph; e.g. it is
18572 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18573 x-position of the drawing area. */
18574
18575 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18576 do { \
18577 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18578 int face_id = (row)->glyphs[area][START].face_id; \
18579 struct face *base_face = FACE_FROM_ID (f, face_id); \
18580 struct composition *cmp = composition_table[cmp_id]; \
18581 int glyph_len = cmp->glyph_len; \
18582 XChar2b *char2b; \
18583 struct face **faces; \
18584 struct glyph_string *first_s = NULL; \
18585 int n; \
18586 \
18587 base_face = base_face->ascii_face; \
18588 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18589 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18590 /* At first, fill in `char2b' and `faces'. */ \
18591 for (n = 0; n < glyph_len; n++) \
18592 { \
18593 int c = COMPOSITION_GLYPH (cmp, n); \
18594 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18595 faces[n] = FACE_FROM_ID (f, this_face_id); \
18596 get_char_face_and_encoding (f, c, this_face_id, \
18597 char2b + n, 1, 1); \
18598 } \
18599 \
18600 /* Make glyph_strings for each glyph sequence that is drawable by \
18601 the same face, and append them to HEAD/TAIL. */ \
18602 for (n = 0; n < cmp->glyph_len;) \
18603 { \
18604 s = (struct glyph_string *) alloca (sizeof *s); \
18605 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18606 append_glyph_string (&(HEAD), &(TAIL), s); \
18607 s->cmp = cmp; \
18608 s->gidx = n; \
18609 s->x = (X); \
18610 \
18611 if (n == 0) \
18612 first_s = s; \
18613 \
18614 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18615 } \
18616 \
18617 ++START; \
18618 s = first_s; \
18619 } while (0)
18620
18621
18622 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18623 of AREA of glyph row ROW on window W between indices START and END.
18624 HL overrides the face for drawing glyph strings, e.g. it is
18625 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18626 x-positions of the drawing area.
18627
18628 This is an ugly monster macro construct because we must use alloca
18629 to allocate glyph strings (because draw_glyphs can be called
18630 asynchronously). */
18631
18632 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18633 do \
18634 { \
18635 HEAD = TAIL = NULL; \
18636 while (START < END) \
18637 { \
18638 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18639 switch (first_glyph->type) \
18640 { \
18641 case CHAR_GLYPH: \
18642 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18643 HL, X, LAST_X); \
18644 break; \
18645 \
18646 case COMPOSITE_GLYPH: \
18647 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18648 HL, X, LAST_X); \
18649 break; \
18650 \
18651 case STRETCH_GLYPH: \
18652 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18653 HL, X, LAST_X); \
18654 break; \
18655 \
18656 case IMAGE_GLYPH: \
18657 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18658 HL, X, LAST_X); \
18659 break; \
18660 \
18661 default: \
18662 abort (); \
18663 } \
18664 \
18665 set_glyph_string_background_width (s, START, LAST_X); \
18666 (X) += s->width; \
18667 } \
18668 } \
18669 while (0)
18670
18671
18672 /* Draw glyphs between START and END in AREA of ROW on window W,
18673 starting at x-position X. X is relative to AREA in W. HL is a
18674 face-override with the following meaning:
18675
18676 DRAW_NORMAL_TEXT draw normally
18677 DRAW_CURSOR draw in cursor face
18678 DRAW_MOUSE_FACE draw in mouse face.
18679 DRAW_INVERSE_VIDEO draw in mode line face
18680 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18681 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18682
18683 If OVERLAPS_P is non-zero, draw only the foreground of characters
18684 and clip to the physical height of ROW.
18685
18686 Value is the x-position reached, relative to AREA of W. */
18687
18688 static int
18689 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18690 struct window *w;
18691 int x;
18692 struct glyph_row *row;
18693 enum glyph_row_area area;
18694 int start, end;
18695 enum draw_glyphs_face hl;
18696 int overlaps_p;
18697 {
18698 struct glyph_string *head, *tail;
18699 struct glyph_string *s;
18700 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
18701 int last_x, area_width;
18702 int x_reached;
18703 int i, j;
18704 struct frame *f = XFRAME (WINDOW_FRAME (w));
18705 DECLARE_HDC (hdc);
18706
18707 ALLOCATE_HDC (hdc, f);
18708
18709 /* Let's rather be paranoid than getting a SEGV. */
18710 end = min (end, row->used[area]);
18711 start = max (0, start);
18712 start = min (end, start);
18713
18714 /* Translate X to frame coordinates. Set last_x to the right
18715 end of the drawing area. */
18716 if (row->full_width_p)
18717 {
18718 /* X is relative to the left edge of W, without scroll bars
18719 or fringes. */
18720 x += WINDOW_LEFT_EDGE_X (w);
18721 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18722 }
18723 else
18724 {
18725 int area_left = window_box_left (w, area);
18726 x += area_left;
18727 area_width = window_box_width (w, area);
18728 last_x = area_left + area_width;
18729 }
18730
18731 /* Build a doubly-linked list of glyph_string structures between
18732 head and tail from what we have to draw. Note that the macro
18733 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18734 the reason we use a separate variable `i'. */
18735 i = start;
18736 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18737 if (tail)
18738 x_reached = tail->x + tail->background_width;
18739 else
18740 x_reached = x;
18741
18742 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18743 the row, redraw some glyphs in front or following the glyph
18744 strings built above. */
18745 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18746 {
18747 int dummy_x = 0;
18748 struct glyph_string *h, *t;
18749
18750 /* Compute overhangs for all glyph strings. */
18751 if (FRAME_RIF (f)->compute_glyph_string_overhangs)
18752 for (s = head; s; s = s->next)
18753 FRAME_RIF (f)->compute_glyph_string_overhangs (s);
18754
18755 /* Prepend glyph strings for glyphs in front of the first glyph
18756 string that are overwritten because of the first glyph
18757 string's left overhang. The background of all strings
18758 prepended must be drawn because the first glyph string
18759 draws over it. */
18760 i = left_overwritten (head);
18761 if (i >= 0)
18762 {
18763 j = i;
18764 BUILD_GLYPH_STRINGS (j, start, h, t,
18765 DRAW_NORMAL_TEXT, dummy_x, last_x);
18766 start = i;
18767 compute_overhangs_and_x (t, head->x, 1);
18768 prepend_glyph_string_lists (&head, &tail, h, t);
18769 clip_head = head;
18770 }
18771
18772 /* Prepend glyph strings for glyphs in front of the first glyph
18773 string that overwrite that glyph string because of their
18774 right overhang. For these strings, only the foreground must
18775 be drawn, because it draws over the glyph string at `head'.
18776 The background must not be drawn because this would overwrite
18777 right overhangs of preceding glyphs for which no glyph
18778 strings exist. */
18779 i = left_overwriting (head);
18780 if (i >= 0)
18781 {
18782 clip_head = head;
18783 BUILD_GLYPH_STRINGS (i, start, h, t,
18784 DRAW_NORMAL_TEXT, dummy_x, last_x);
18785 for (s = h; s; s = s->next)
18786 s->background_filled_p = 1;
18787 compute_overhangs_and_x (t, head->x, 1);
18788 prepend_glyph_string_lists (&head, &tail, h, t);
18789 }
18790
18791 /* Append glyphs strings for glyphs following the last glyph
18792 string tail that are overwritten by tail. The background of
18793 these strings has to be drawn because tail's foreground draws
18794 over it. */
18795 i = right_overwritten (tail);
18796 if (i >= 0)
18797 {
18798 BUILD_GLYPH_STRINGS (end, i, h, t,
18799 DRAW_NORMAL_TEXT, x, last_x);
18800 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18801 append_glyph_string_lists (&head, &tail, h, t);
18802 clip_tail = tail;
18803 }
18804
18805 /* Append glyph strings for glyphs following the last glyph
18806 string tail that overwrite tail. The foreground of such
18807 glyphs has to be drawn because it writes into the background
18808 of tail. The background must not be drawn because it could
18809 paint over the foreground of following glyphs. */
18810 i = right_overwriting (tail);
18811 if (i >= 0)
18812 {
18813 clip_tail = tail;
18814 BUILD_GLYPH_STRINGS (end, i, h, t,
18815 DRAW_NORMAL_TEXT, x, last_x);
18816 for (s = h; s; s = s->next)
18817 s->background_filled_p = 1;
18818 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18819 append_glyph_string_lists (&head, &tail, h, t);
18820 }
18821 if (clip_head || clip_tail)
18822 for (s = head; s; s = s->next)
18823 {
18824 s->clip_head = clip_head;
18825 s->clip_tail = clip_tail;
18826 }
18827 }
18828
18829 /* Draw all strings. */
18830 for (s = head; s; s = s->next)
18831 FRAME_RIF (f)->draw_glyph_string (s);
18832
18833 if (area == TEXT_AREA
18834 && !row->full_width_p
18835 /* When drawing overlapping rows, only the glyph strings'
18836 foreground is drawn, which doesn't erase a cursor
18837 completely. */
18838 && !overlaps_p)
18839 {
18840 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
18841 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
18842 : (tail ? tail->x + tail->background_width : x));
18843
18844 int text_left = window_box_left (w, TEXT_AREA);
18845 x0 -= text_left;
18846 x1 -= text_left;
18847
18848 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18849 row->y, MATRIX_ROW_BOTTOM_Y (row));
18850 }
18851
18852 /* Value is the x-position up to which drawn, relative to AREA of W.
18853 This doesn't include parts drawn because of overhangs. */
18854 if (row->full_width_p)
18855 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18856 else
18857 x_reached -= window_box_left (w, area);
18858
18859 RELEASE_HDC (hdc, f);
18860
18861 return x_reached;
18862 }
18863
18864 /* Expand row matrix if too narrow. Don't expand if area
18865 is not present. */
18866
18867 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18868 { \
18869 if (!fonts_changed_p \
18870 && (it->glyph_row->glyphs[area] \
18871 < it->glyph_row->glyphs[area + 1])) \
18872 { \
18873 it->w->ncols_scale_factor++; \
18874 fonts_changed_p = 1; \
18875 } \
18876 }
18877
18878 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18879 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18880
18881 static INLINE void
18882 append_glyph (it)
18883 struct it *it;
18884 {
18885 struct glyph *glyph;
18886 enum glyph_row_area area = it->area;
18887
18888 xassert (it->glyph_row);
18889 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18890
18891 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18892 if (glyph < it->glyph_row->glyphs[area + 1])
18893 {
18894 glyph->charpos = CHARPOS (it->position);
18895 glyph->object = it->object;
18896 glyph->pixel_width = it->pixel_width;
18897 glyph->ascent = it->ascent;
18898 glyph->descent = it->descent;
18899 glyph->voffset = it->voffset;
18900 glyph->type = CHAR_GLYPH;
18901 glyph->multibyte_p = it->multibyte_p;
18902 glyph->left_box_line_p = it->start_of_box_run_p;
18903 glyph->right_box_line_p = it->end_of_box_run_p;
18904 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18905 || it->phys_descent > it->descent);
18906 glyph->padding_p = 0;
18907 glyph->glyph_not_available_p = it->glyph_not_available_p;
18908 glyph->face_id = it->face_id;
18909 glyph->u.ch = it->char_to_display;
18910 glyph->slice = null_glyph_slice;
18911 glyph->font_type = FONT_TYPE_UNKNOWN;
18912 ++it->glyph_row->used[area];
18913 }
18914 else
18915 IT_EXPAND_MATRIX_WIDTH (it, area);
18916 }
18917
18918 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18919 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18920
18921 static INLINE void
18922 append_composite_glyph (it)
18923 struct it *it;
18924 {
18925 struct glyph *glyph;
18926 enum glyph_row_area area = it->area;
18927
18928 xassert (it->glyph_row);
18929
18930 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18931 if (glyph < it->glyph_row->glyphs[area + 1])
18932 {
18933 glyph->charpos = CHARPOS (it->position);
18934 glyph->object = it->object;
18935 glyph->pixel_width = it->pixel_width;
18936 glyph->ascent = it->ascent;
18937 glyph->descent = it->descent;
18938 glyph->voffset = it->voffset;
18939 glyph->type = COMPOSITE_GLYPH;
18940 glyph->multibyte_p = it->multibyte_p;
18941 glyph->left_box_line_p = it->start_of_box_run_p;
18942 glyph->right_box_line_p = it->end_of_box_run_p;
18943 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18944 || it->phys_descent > it->descent);
18945 glyph->padding_p = 0;
18946 glyph->glyph_not_available_p = 0;
18947 glyph->face_id = it->face_id;
18948 glyph->u.cmp_id = it->cmp_id;
18949 glyph->slice = null_glyph_slice;
18950 glyph->font_type = FONT_TYPE_UNKNOWN;
18951 ++it->glyph_row->used[area];
18952 }
18953 else
18954 IT_EXPAND_MATRIX_WIDTH (it, area);
18955 }
18956
18957
18958 /* Change IT->ascent and IT->height according to the setting of
18959 IT->voffset. */
18960
18961 static INLINE void
18962 take_vertical_position_into_account (it)
18963 struct it *it;
18964 {
18965 if (it->voffset)
18966 {
18967 if (it->voffset < 0)
18968 /* Increase the ascent so that we can display the text higher
18969 in the line. */
18970 it->ascent -= it->voffset;
18971 else
18972 /* Increase the descent so that we can display the text lower
18973 in the line. */
18974 it->descent += it->voffset;
18975 }
18976 }
18977
18978
18979 /* Produce glyphs/get display metrics for the image IT is loaded with.
18980 See the description of struct display_iterator in dispextern.h for
18981 an overview of struct display_iterator. */
18982
18983 static void
18984 produce_image_glyph (it)
18985 struct it *it;
18986 {
18987 struct image *img;
18988 struct face *face;
18989 int glyph_ascent;
18990 struct glyph_slice slice;
18991
18992 xassert (it->what == IT_IMAGE);
18993
18994 face = FACE_FROM_ID (it->f, it->face_id);
18995 xassert (face);
18996 /* Make sure X resources of the face is loaded. */
18997 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18998
18999 if (it->image_id < 0)
19000 {
19001 /* Fringe bitmap. */
19002 it->ascent = it->phys_ascent = 0;
19003 it->descent = it->phys_descent = 0;
19004 it->pixel_width = 0;
19005 it->nglyphs = 0;
19006 return;
19007 }
19008
19009 img = IMAGE_FROM_ID (it->f, it->image_id);
19010 xassert (img);
19011 /* Make sure X resources of the image is loaded. */
19012 prepare_image_for_display (it->f, img);
19013
19014 slice.x = slice.y = 0;
19015 slice.width = img->width;
19016 slice.height = img->height;
19017
19018 if (INTEGERP (it->slice.x))
19019 slice.x = XINT (it->slice.x);
19020 else if (FLOATP (it->slice.x))
19021 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
19022
19023 if (INTEGERP (it->slice.y))
19024 slice.y = XINT (it->slice.y);
19025 else if (FLOATP (it->slice.y))
19026 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
19027
19028 if (INTEGERP (it->slice.width))
19029 slice.width = XINT (it->slice.width);
19030 else if (FLOATP (it->slice.width))
19031 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
19032
19033 if (INTEGERP (it->slice.height))
19034 slice.height = XINT (it->slice.height);
19035 else if (FLOATP (it->slice.height))
19036 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
19037
19038 if (slice.x >= img->width)
19039 slice.x = img->width;
19040 if (slice.y >= img->height)
19041 slice.y = img->height;
19042 if (slice.x + slice.width >= img->width)
19043 slice.width = img->width - slice.x;
19044 if (slice.y + slice.height > img->height)
19045 slice.height = img->height - slice.y;
19046
19047 if (slice.width == 0 || slice.height == 0)
19048 return;
19049
19050 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
19051
19052 it->descent = slice.height - glyph_ascent;
19053 if (slice.y == 0)
19054 it->descent += img->vmargin;
19055 if (slice.y + slice.height == img->height)
19056 it->descent += img->vmargin;
19057 it->phys_descent = it->descent;
19058
19059 it->pixel_width = slice.width;
19060 if (slice.x == 0)
19061 it->pixel_width += img->hmargin;
19062 if (slice.x + slice.width == img->width)
19063 it->pixel_width += img->hmargin;
19064
19065 /* It's quite possible for images to have an ascent greater than
19066 their height, so don't get confused in that case. */
19067 if (it->descent < 0)
19068 it->descent = 0;
19069
19070 #if 0 /* this breaks image tiling */
19071 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
19072 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
19073 if (face_ascent > it->ascent)
19074 it->ascent = it->phys_ascent = face_ascent;
19075 #endif
19076
19077 it->nglyphs = 1;
19078
19079 if (face->box != FACE_NO_BOX)
19080 {
19081 if (face->box_line_width > 0)
19082 {
19083 if (slice.y == 0)
19084 it->ascent += face->box_line_width;
19085 if (slice.y + slice.height == img->height)
19086 it->descent += face->box_line_width;
19087 }
19088
19089 if (it->start_of_box_run_p && slice.x == 0)
19090 it->pixel_width += abs (face->box_line_width);
19091 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
19092 it->pixel_width += abs (face->box_line_width);
19093 }
19094
19095 take_vertical_position_into_account (it);
19096
19097 if (it->glyph_row)
19098 {
19099 struct glyph *glyph;
19100 enum glyph_row_area area = it->area;
19101
19102 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19103 if (glyph < it->glyph_row->glyphs[area + 1])
19104 {
19105 glyph->charpos = CHARPOS (it->position);
19106 glyph->object = it->object;
19107 glyph->pixel_width = it->pixel_width;
19108 glyph->ascent = glyph_ascent;
19109 glyph->descent = it->descent;
19110 glyph->voffset = it->voffset;
19111 glyph->type = IMAGE_GLYPH;
19112 glyph->multibyte_p = it->multibyte_p;
19113 glyph->left_box_line_p = it->start_of_box_run_p;
19114 glyph->right_box_line_p = it->end_of_box_run_p;
19115 glyph->overlaps_vertically_p = 0;
19116 glyph->padding_p = 0;
19117 glyph->glyph_not_available_p = 0;
19118 glyph->face_id = it->face_id;
19119 glyph->u.img_id = img->id;
19120 glyph->slice = slice;
19121 glyph->font_type = FONT_TYPE_UNKNOWN;
19122 ++it->glyph_row->used[area];
19123 }
19124 else
19125 IT_EXPAND_MATRIX_WIDTH (it, area);
19126 }
19127 }
19128
19129
19130 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
19131 of the glyph, WIDTH and HEIGHT are the width and height of the
19132 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
19133
19134 static void
19135 append_stretch_glyph (it, object, width, height, ascent)
19136 struct it *it;
19137 Lisp_Object object;
19138 int width, height;
19139 int ascent;
19140 {
19141 struct glyph *glyph;
19142 enum glyph_row_area area = it->area;
19143
19144 xassert (ascent >= 0 && ascent <= height);
19145
19146 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19147 if (glyph < it->glyph_row->glyphs[area + 1])
19148 {
19149 glyph->charpos = CHARPOS (it->position);
19150 glyph->object = object;
19151 glyph->pixel_width = width;
19152 glyph->ascent = ascent;
19153 glyph->descent = height - ascent;
19154 glyph->voffset = it->voffset;
19155 glyph->type = STRETCH_GLYPH;
19156 glyph->multibyte_p = it->multibyte_p;
19157 glyph->left_box_line_p = it->start_of_box_run_p;
19158 glyph->right_box_line_p = it->end_of_box_run_p;
19159 glyph->overlaps_vertically_p = 0;
19160 glyph->padding_p = 0;
19161 glyph->glyph_not_available_p = 0;
19162 glyph->face_id = it->face_id;
19163 glyph->u.stretch.ascent = ascent;
19164 glyph->u.stretch.height = height;
19165 glyph->slice = null_glyph_slice;
19166 glyph->font_type = FONT_TYPE_UNKNOWN;
19167 ++it->glyph_row->used[area];
19168 }
19169 else
19170 IT_EXPAND_MATRIX_WIDTH (it, area);
19171 }
19172
19173
19174 /* Produce a stretch glyph for iterator IT. IT->object is the value
19175 of the glyph property displayed. The value must be a list
19176 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
19177 being recognized:
19178
19179 1. `:width WIDTH' specifies that the space should be WIDTH *
19180 canonical char width wide. WIDTH may be an integer or floating
19181 point number.
19182
19183 2. `:relative-width FACTOR' specifies that the width of the stretch
19184 should be computed from the width of the first character having the
19185 `glyph' property, and should be FACTOR times that width.
19186
19187 3. `:align-to HPOS' specifies that the space should be wide enough
19188 to reach HPOS, a value in canonical character units.
19189
19190 Exactly one of the above pairs must be present.
19191
19192 4. `:height HEIGHT' specifies that the height of the stretch produced
19193 should be HEIGHT, measured in canonical character units.
19194
19195 5. `:relative-height FACTOR' specifies that the height of the
19196 stretch should be FACTOR times the height of the characters having
19197 the glyph property.
19198
19199 Either none or exactly one of 4 or 5 must be present.
19200
19201 6. `:ascent ASCENT' specifies that ASCENT percent of the height
19202 of the stretch should be used for the ascent of the stretch.
19203 ASCENT must be in the range 0 <= ASCENT <= 100. */
19204
19205 static void
19206 produce_stretch_glyph (it)
19207 struct it *it;
19208 {
19209 /* (space :width WIDTH :height HEIGHT ...) */
19210 Lisp_Object prop, plist;
19211 int width = 0, height = 0, align_to = -1;
19212 int zero_width_ok_p = 0, zero_height_ok_p = 0;
19213 int ascent = 0;
19214 double tem;
19215 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19216 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
19217
19218 PREPARE_FACE_FOR_DISPLAY (it->f, face);
19219
19220 /* List should start with `space'. */
19221 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
19222 plist = XCDR (it->object);
19223
19224 /* Compute the width of the stretch. */
19225 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
19226 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
19227 {
19228 /* Absolute width `:width WIDTH' specified and valid. */
19229 zero_width_ok_p = 1;
19230 width = (int)tem;
19231 }
19232 else if (prop = Fplist_get (plist, QCrelative_width),
19233 NUMVAL (prop) > 0)
19234 {
19235 /* Relative width `:relative-width FACTOR' specified and valid.
19236 Compute the width of the characters having the `glyph'
19237 property. */
19238 struct it it2;
19239 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
19240
19241 it2 = *it;
19242 if (it->multibyte_p)
19243 {
19244 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
19245 - IT_BYTEPOS (*it));
19246 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
19247 }
19248 else
19249 it2.c = *p, it2.len = 1;
19250
19251 it2.glyph_row = NULL;
19252 it2.what = IT_CHARACTER;
19253 x_produce_glyphs (&it2);
19254 width = NUMVAL (prop) * it2.pixel_width;
19255 }
19256 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
19257 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
19258 {
19259 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
19260 align_to = (align_to < 0
19261 ? 0
19262 : align_to - window_box_left_offset (it->w, TEXT_AREA));
19263 else if (align_to < 0)
19264 align_to = window_box_left_offset (it->w, TEXT_AREA);
19265 width = max (0, (int)tem + align_to - it->current_x);
19266 zero_width_ok_p = 1;
19267 }
19268 else
19269 /* Nothing specified -> width defaults to canonical char width. */
19270 width = FRAME_COLUMN_WIDTH (it->f);
19271
19272 if (width <= 0 && (width < 0 || !zero_width_ok_p))
19273 width = 1;
19274
19275 /* Compute height. */
19276 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
19277 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
19278 {
19279 height = (int)tem;
19280 zero_height_ok_p = 1;
19281 }
19282 else if (prop = Fplist_get (plist, QCrelative_height),
19283 NUMVAL (prop) > 0)
19284 height = FONT_HEIGHT (font) * NUMVAL (prop);
19285 else
19286 height = FONT_HEIGHT (font);
19287
19288 if (height <= 0 && (height < 0 || !zero_height_ok_p))
19289 height = 1;
19290
19291 /* Compute percentage of height used for ascent. If
19292 `:ascent ASCENT' is present and valid, use that. Otherwise,
19293 derive the ascent from the font in use. */
19294 if (prop = Fplist_get (plist, QCascent),
19295 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
19296 ascent = height * NUMVAL (prop) / 100.0;
19297 else if (!NILP (prop)
19298 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
19299 ascent = min (max (0, (int)tem), height);
19300 else
19301 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
19302
19303 if (width > 0 && height > 0 && it->glyph_row)
19304 {
19305 Lisp_Object object = it->stack[it->sp - 1].string;
19306 if (!STRINGP (object))
19307 object = it->w->buffer;
19308 append_stretch_glyph (it, object, width, height, ascent);
19309 }
19310
19311 it->pixel_width = width;
19312 it->ascent = it->phys_ascent = ascent;
19313 it->descent = it->phys_descent = height - it->ascent;
19314 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
19315
19316 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
19317 {
19318 if (face->box_line_width > 0)
19319 {
19320 it->ascent += face->box_line_width;
19321 it->descent += face->box_line_width;
19322 }
19323
19324 if (it->start_of_box_run_p)
19325 it->pixel_width += abs (face->box_line_width);
19326 if (it->end_of_box_run_p)
19327 it->pixel_width += abs (face->box_line_width);
19328 }
19329
19330 take_vertical_position_into_account (it);
19331 }
19332
19333 /* Get line-height and line-spacing property at point.
19334 If line-height has format (HEIGHT TOTAL), return TOTAL
19335 in TOTAL_HEIGHT. */
19336
19337 static Lisp_Object
19338 get_line_height_property (it, prop)
19339 struct it *it;
19340 Lisp_Object prop;
19341 {
19342 Lisp_Object position;
19343
19344 if (STRINGP (it->object))
19345 position = make_number (IT_STRING_CHARPOS (*it));
19346 else if (BUFFERP (it->object))
19347 position = make_number (IT_CHARPOS (*it));
19348 else
19349 return Qnil;
19350
19351 return Fget_char_property (position, prop, it->object);
19352 }
19353
19354 /* Calculate line-height and line-spacing properties.
19355 An integer value specifies explicit pixel value.
19356 A float value specifies relative value to current face height.
19357 A cons (float . face-name) specifies relative value to
19358 height of specified face font.
19359
19360 Returns height in pixels, or nil. */
19361
19362
19363 static Lisp_Object
19364 calc_line_height_property (it, val, font, boff, override)
19365 struct it *it;
19366 Lisp_Object val;
19367 XFontStruct *font;
19368 int boff, override;
19369 {
19370 Lisp_Object face_name = Qnil;
19371 int ascent, descent, height;
19372
19373 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
19374 return val;
19375
19376 if (CONSP (val))
19377 {
19378 face_name = XCAR (val);
19379 val = XCDR (val);
19380 if (!NUMBERP (val))
19381 val = make_number (1);
19382 if (NILP (face_name))
19383 {
19384 height = it->ascent + it->descent;
19385 goto scale;
19386 }
19387 }
19388
19389 if (NILP (face_name))
19390 {
19391 font = FRAME_FONT (it->f);
19392 boff = FRAME_BASELINE_OFFSET (it->f);
19393 }
19394 else if (EQ (face_name, Qt))
19395 {
19396 override = 0;
19397 }
19398 else
19399 {
19400 int face_id;
19401 struct face *face;
19402 struct font_info *font_info;
19403
19404 face_id = lookup_named_face (it->f, face_name, ' ', 0);
19405 if (face_id < 0)
19406 return make_number (-1);
19407
19408 face = FACE_FROM_ID (it->f, face_id);
19409 font = face->font;
19410 if (font == NULL)
19411 return make_number (-1);
19412
19413 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19414 boff = font_info->baseline_offset;
19415 if (font_info->vertical_centering)
19416 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19417 }
19418
19419 ascent = FONT_BASE (font) + boff;
19420 descent = FONT_DESCENT (font) - boff;
19421
19422 if (override)
19423 {
19424 it->override_ascent = ascent;
19425 it->override_descent = descent;
19426 it->override_boff = boff;
19427 }
19428
19429 height = ascent + descent;
19430
19431 scale:
19432 if (FLOATP (val))
19433 height = (int)(XFLOAT_DATA (val) * height);
19434 else if (INTEGERP (val))
19435 height *= XINT (val);
19436
19437 return make_number (height);
19438 }
19439
19440
19441 /* RIF:
19442 Produce glyphs/get display metrics for the display element IT is
19443 loaded with. See the description of struct display_iterator in
19444 dispextern.h for an overview of struct display_iterator. */
19445
19446 void
19447 x_produce_glyphs (it)
19448 struct it *it;
19449 {
19450 int extra_line_spacing = it->extra_line_spacing;
19451
19452 it->glyph_not_available_p = 0;
19453
19454 if (it->what == IT_CHARACTER)
19455 {
19456 XChar2b char2b;
19457 XFontStruct *font;
19458 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19459 XCharStruct *pcm;
19460 int font_not_found_p;
19461 struct font_info *font_info;
19462 int boff; /* baseline offset */
19463 /* We may change it->multibyte_p upon unibyte<->multibyte
19464 conversion. So, save the current value now and restore it
19465 later.
19466
19467 Note: It seems that we don't have to record multibyte_p in
19468 struct glyph because the character code itself tells if or
19469 not the character is multibyte. Thus, in the future, we must
19470 consider eliminating the field `multibyte_p' in the struct
19471 glyph. */
19472 int saved_multibyte_p = it->multibyte_p;
19473
19474 /* Maybe translate single-byte characters to multibyte, or the
19475 other way. */
19476 it->char_to_display = it->c;
19477 if (!ASCII_BYTE_P (it->c))
19478 {
19479 if (unibyte_display_via_language_environment
19480 && SINGLE_BYTE_CHAR_P (it->c)
19481 && (it->c >= 0240
19482 || !NILP (Vnonascii_translation_table)))
19483 {
19484 it->char_to_display = unibyte_char_to_multibyte (it->c);
19485 it->multibyte_p = 1;
19486 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19487 face = FACE_FROM_ID (it->f, it->face_id);
19488 }
19489 else if (!SINGLE_BYTE_CHAR_P (it->c)
19490 && !it->multibyte_p)
19491 {
19492 it->multibyte_p = 1;
19493 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19494 face = FACE_FROM_ID (it->f, it->face_id);
19495 }
19496 }
19497
19498 /* Get font to use. Encode IT->char_to_display. */
19499 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19500 &char2b, it->multibyte_p, 0);
19501 font = face->font;
19502
19503 /* When no suitable font found, use the default font. */
19504 font_not_found_p = font == NULL;
19505 if (font_not_found_p)
19506 {
19507 font = FRAME_FONT (it->f);
19508 boff = FRAME_BASELINE_OFFSET (it->f);
19509 font_info = NULL;
19510 }
19511 else
19512 {
19513 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19514 boff = font_info->baseline_offset;
19515 if (font_info->vertical_centering)
19516 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19517 }
19518
19519 if (it->char_to_display >= ' '
19520 && (!it->multibyte_p || it->char_to_display < 128))
19521 {
19522 /* Either unibyte or ASCII. */
19523 int stretched_p;
19524
19525 it->nglyphs = 1;
19526
19527 pcm = FRAME_RIF (it->f)->per_char_metric
19528 (font, &char2b, FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
19529
19530 if (it->override_ascent >= 0)
19531 {
19532 it->ascent = it->override_ascent;
19533 it->descent = it->override_descent;
19534 boff = it->override_boff;
19535 }
19536 else
19537 {
19538 it->ascent = FONT_BASE (font) + boff;
19539 it->descent = FONT_DESCENT (font) - boff;
19540 }
19541
19542 if (pcm)
19543 {
19544 it->phys_ascent = pcm->ascent + boff;
19545 it->phys_descent = pcm->descent - boff;
19546 it->pixel_width = pcm->width;
19547 }
19548 else
19549 {
19550 it->glyph_not_available_p = 1;
19551 it->phys_ascent = it->ascent;
19552 it->phys_descent = it->descent;
19553 it->pixel_width = FONT_WIDTH (font);
19554 }
19555
19556 if (it->constrain_row_ascent_descent_p)
19557 {
19558 if (it->descent > it->max_descent)
19559 {
19560 it->ascent += it->descent - it->max_descent;
19561 it->descent = it->max_descent;
19562 }
19563 if (it->ascent > it->max_ascent)
19564 {
19565 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19566 it->ascent = it->max_ascent;
19567 }
19568 it->phys_ascent = min (it->phys_ascent, it->ascent);
19569 it->phys_descent = min (it->phys_descent, it->descent);
19570 extra_line_spacing = 0;
19571 }
19572
19573 /* If this is a space inside a region of text with
19574 `space-width' property, change its width. */
19575 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19576 if (stretched_p)
19577 it->pixel_width *= XFLOATINT (it->space_width);
19578
19579 /* If face has a box, add the box thickness to the character
19580 height. If character has a box line to the left and/or
19581 right, add the box line width to the character's width. */
19582 if (face->box != FACE_NO_BOX)
19583 {
19584 int thick = face->box_line_width;
19585
19586 if (thick > 0)
19587 {
19588 it->ascent += thick;
19589 it->descent += thick;
19590 }
19591 else
19592 thick = -thick;
19593
19594 if (it->start_of_box_run_p)
19595 it->pixel_width += thick;
19596 if (it->end_of_box_run_p)
19597 it->pixel_width += thick;
19598 }
19599
19600 /* If face has an overline, add the height of the overline
19601 (1 pixel) and a 1 pixel margin to the character height. */
19602 if (face->overline_p)
19603 it->ascent += 2;
19604
19605 if (it->constrain_row_ascent_descent_p)
19606 {
19607 if (it->ascent > it->max_ascent)
19608 it->ascent = it->max_ascent;
19609 if (it->descent > it->max_descent)
19610 it->descent = it->max_descent;
19611 }
19612
19613 take_vertical_position_into_account (it);
19614
19615 /* If we have to actually produce glyphs, do it. */
19616 if (it->glyph_row)
19617 {
19618 if (stretched_p)
19619 {
19620 /* Translate a space with a `space-width' property
19621 into a stretch glyph. */
19622 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19623 / FONT_HEIGHT (font));
19624 append_stretch_glyph (it, it->object, it->pixel_width,
19625 it->ascent + it->descent, ascent);
19626 }
19627 else
19628 append_glyph (it);
19629
19630 /* If characters with lbearing or rbearing are displayed
19631 in this line, record that fact in a flag of the
19632 glyph row. This is used to optimize X output code. */
19633 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19634 it->glyph_row->contains_overlapping_glyphs_p = 1;
19635 }
19636 }
19637 else if (it->char_to_display == '\n')
19638 {
19639 /* A newline has no width but we need the height of the line.
19640 But if previous part of the line set a height, don't
19641 increase that height */
19642
19643 Lisp_Object height;
19644 Lisp_Object total_height = Qnil;
19645
19646 it->override_ascent = -1;
19647 it->pixel_width = 0;
19648 it->nglyphs = 0;
19649
19650 height = get_line_height_property(it, Qline_height);
19651 /* Split (line-height total-height) list */
19652 if (CONSP (height)
19653 && CONSP (XCDR (height))
19654 && NILP (XCDR (XCDR (height))))
19655 {
19656 total_height = XCAR (XCDR (height));
19657 height = XCAR (height);
19658 }
19659 height = calc_line_height_property(it, height, font, boff, 1);
19660
19661 if (it->override_ascent >= 0)
19662 {
19663 it->ascent = it->override_ascent;
19664 it->descent = it->override_descent;
19665 boff = it->override_boff;
19666 }
19667 else
19668 {
19669 it->ascent = FONT_BASE (font) + boff;
19670 it->descent = FONT_DESCENT (font) - boff;
19671 }
19672
19673 if (EQ (height, Qt))
19674 {
19675 if (it->descent > it->max_descent)
19676 {
19677 it->ascent += it->descent - it->max_descent;
19678 it->descent = it->max_descent;
19679 }
19680 if (it->ascent > it->max_ascent)
19681 {
19682 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19683 it->ascent = it->max_ascent;
19684 }
19685 it->phys_ascent = min (it->phys_ascent, it->ascent);
19686 it->phys_descent = min (it->phys_descent, it->descent);
19687 it->constrain_row_ascent_descent_p = 1;
19688 extra_line_spacing = 0;
19689 }
19690 else
19691 {
19692 Lisp_Object spacing;
19693
19694 it->phys_ascent = it->ascent;
19695 it->phys_descent = it->descent;
19696
19697 if ((it->max_ascent > 0 || it->max_descent > 0)
19698 && face->box != FACE_NO_BOX
19699 && face->box_line_width > 0)
19700 {
19701 it->ascent += face->box_line_width;
19702 it->descent += face->box_line_width;
19703 }
19704 if (!NILP (height)
19705 && XINT (height) > it->ascent + it->descent)
19706 it->ascent = XINT (height) - it->descent;
19707
19708 if (!NILP (total_height))
19709 spacing = calc_line_height_property(it, total_height, font, boff, 0);
19710 else
19711 {
19712 spacing = get_line_height_property(it, Qline_spacing);
19713 spacing = calc_line_height_property(it, spacing, font, boff, 0);
19714 }
19715 if (INTEGERP (spacing))
19716 {
19717 extra_line_spacing = XINT (spacing);
19718 if (!NILP (total_height))
19719 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19720 }
19721 }
19722 }
19723 else if (it->char_to_display == '\t')
19724 {
19725 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
19726 int x = it->current_x + it->continuation_lines_width;
19727 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19728
19729 /* If the distance from the current position to the next tab
19730 stop is less than a space character width, use the
19731 tab stop after that. */
19732 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
19733 next_tab_x += tab_width;
19734
19735 it->pixel_width = next_tab_x - x;
19736 it->nglyphs = 1;
19737 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19738 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19739
19740 if (it->glyph_row)
19741 {
19742 append_stretch_glyph (it, it->object, it->pixel_width,
19743 it->ascent + it->descent, it->ascent);
19744 }
19745 }
19746 else
19747 {
19748 /* A multi-byte character. Assume that the display width of the
19749 character is the width of the character multiplied by the
19750 width of the font. */
19751
19752 /* If we found a font, this font should give us the right
19753 metrics. If we didn't find a font, use the frame's
19754 default font and calculate the width of the character
19755 from the charset width; this is what old redisplay code
19756 did. */
19757
19758 pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
19759 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19760
19761 if (font_not_found_p || !pcm)
19762 {
19763 int charset = CHAR_CHARSET (it->char_to_display);
19764
19765 it->glyph_not_available_p = 1;
19766 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19767 * CHARSET_WIDTH (charset));
19768 it->phys_ascent = FONT_BASE (font) + boff;
19769 it->phys_descent = FONT_DESCENT (font) - boff;
19770 }
19771 else
19772 {
19773 it->pixel_width = pcm->width;
19774 it->phys_ascent = pcm->ascent + boff;
19775 it->phys_descent = pcm->descent - boff;
19776 if (it->glyph_row
19777 && (pcm->lbearing < 0
19778 || pcm->rbearing > pcm->width))
19779 it->glyph_row->contains_overlapping_glyphs_p = 1;
19780 }
19781 it->nglyphs = 1;
19782 it->ascent = FONT_BASE (font) + boff;
19783 it->descent = FONT_DESCENT (font) - boff;
19784 if (face->box != FACE_NO_BOX)
19785 {
19786 int thick = face->box_line_width;
19787
19788 if (thick > 0)
19789 {
19790 it->ascent += thick;
19791 it->descent += thick;
19792 }
19793 else
19794 thick = - thick;
19795
19796 if (it->start_of_box_run_p)
19797 it->pixel_width += thick;
19798 if (it->end_of_box_run_p)
19799 it->pixel_width += thick;
19800 }
19801
19802 /* If face has an overline, add the height of the overline
19803 (1 pixel) and a 1 pixel margin to the character height. */
19804 if (face->overline_p)
19805 it->ascent += 2;
19806
19807 take_vertical_position_into_account (it);
19808
19809 if (it->glyph_row)
19810 append_glyph (it);
19811 }
19812 it->multibyte_p = saved_multibyte_p;
19813 }
19814 else if (it->what == IT_COMPOSITION)
19815 {
19816 /* Note: A composition is represented as one glyph in the
19817 glyph matrix. There are no padding glyphs. */
19818 XChar2b char2b;
19819 XFontStruct *font;
19820 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19821 XCharStruct *pcm;
19822 int font_not_found_p;
19823 struct font_info *font_info;
19824 int boff; /* baseline offset */
19825 struct composition *cmp = composition_table[it->cmp_id];
19826
19827 /* Maybe translate single-byte characters to multibyte. */
19828 it->char_to_display = it->c;
19829 if (unibyte_display_via_language_environment
19830 && SINGLE_BYTE_CHAR_P (it->c)
19831 && (it->c >= 0240
19832 || (it->c >= 0200
19833 && !NILP (Vnonascii_translation_table))))
19834 {
19835 it->char_to_display = unibyte_char_to_multibyte (it->c);
19836 }
19837
19838 /* Get face and font to use. Encode IT->char_to_display. */
19839 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19840 face = FACE_FROM_ID (it->f, it->face_id);
19841 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19842 &char2b, it->multibyte_p, 0);
19843 font = face->font;
19844
19845 /* When no suitable font found, use the default font. */
19846 font_not_found_p = font == NULL;
19847 if (font_not_found_p)
19848 {
19849 font = FRAME_FONT (it->f);
19850 boff = FRAME_BASELINE_OFFSET (it->f);
19851 font_info = NULL;
19852 }
19853 else
19854 {
19855 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19856 boff = font_info->baseline_offset;
19857 if (font_info->vertical_centering)
19858 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19859 }
19860
19861 /* There are no padding glyphs, so there is only one glyph to
19862 produce for the composition. Important is that pixel_width,
19863 ascent and descent are the values of what is drawn by
19864 draw_glyphs (i.e. the values of the overall glyphs composed). */
19865 it->nglyphs = 1;
19866
19867 /* If we have not yet calculated pixel size data of glyphs of
19868 the composition for the current face font, calculate them
19869 now. Theoretically, we have to check all fonts for the
19870 glyphs, but that requires much time and memory space. So,
19871 here we check only the font of the first glyph. This leads
19872 to incorrect display very rarely, and C-l (recenter) can
19873 correct the display anyway. */
19874 if (cmp->font != (void *) font)
19875 {
19876 /* Ascent and descent of the font of the first character of
19877 this composition (adjusted by baseline offset). Ascent
19878 and descent of overall glyphs should not be less than
19879 them respectively. */
19880 int font_ascent = FONT_BASE (font) + boff;
19881 int font_descent = FONT_DESCENT (font) - boff;
19882 /* Bounding box of the overall glyphs. */
19883 int leftmost, rightmost, lowest, highest;
19884 int i, width, ascent, descent;
19885
19886 cmp->font = (void *) font;
19887
19888 /* Initialize the bounding box. */
19889 if (font_info
19890 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
19891 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19892 {
19893 width = pcm->width;
19894 ascent = pcm->ascent;
19895 descent = pcm->descent;
19896 }
19897 else
19898 {
19899 width = FONT_WIDTH (font);
19900 ascent = FONT_BASE (font);
19901 descent = FONT_DESCENT (font);
19902 }
19903
19904 rightmost = width;
19905 lowest = - descent + boff;
19906 highest = ascent + boff;
19907 leftmost = 0;
19908
19909 if (font_info
19910 && font_info->default_ascent
19911 && CHAR_TABLE_P (Vuse_default_ascent)
19912 && !NILP (Faref (Vuse_default_ascent,
19913 make_number (it->char_to_display))))
19914 highest = font_info->default_ascent + boff;
19915
19916 /* Draw the first glyph at the normal position. It may be
19917 shifted to right later if some other glyphs are drawn at
19918 the left. */
19919 cmp->offsets[0] = 0;
19920 cmp->offsets[1] = boff;
19921
19922 /* Set cmp->offsets for the remaining glyphs. */
19923 for (i = 1; i < cmp->glyph_len; i++)
19924 {
19925 int left, right, btm, top;
19926 int ch = COMPOSITION_GLYPH (cmp, i);
19927 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19928
19929 face = FACE_FROM_ID (it->f, face_id);
19930 get_char_face_and_encoding (it->f, ch, face->id,
19931 &char2b, it->multibyte_p, 0);
19932 font = face->font;
19933 if (font == NULL)
19934 {
19935 font = FRAME_FONT (it->f);
19936 boff = FRAME_BASELINE_OFFSET (it->f);
19937 font_info = NULL;
19938 }
19939 else
19940 {
19941 font_info
19942 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19943 boff = font_info->baseline_offset;
19944 if (font_info->vertical_centering)
19945 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19946 }
19947
19948 if (font_info
19949 && (pcm = FRAME_RIF (it->f)->per_char_metric (font, &char2b,
19950 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19951 {
19952 width = pcm->width;
19953 ascent = pcm->ascent;
19954 descent = pcm->descent;
19955 }
19956 else
19957 {
19958 width = FONT_WIDTH (font);
19959 ascent = 1;
19960 descent = 0;
19961 }
19962
19963 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19964 {
19965 /* Relative composition with or without
19966 alternate chars. */
19967 left = (leftmost + rightmost - width) / 2;
19968 btm = - descent + boff;
19969 if (font_info && font_info->relative_compose
19970 && (! CHAR_TABLE_P (Vignore_relative_composition)
19971 || NILP (Faref (Vignore_relative_composition,
19972 make_number (ch)))))
19973 {
19974
19975 if (- descent >= font_info->relative_compose)
19976 /* One extra pixel between two glyphs. */
19977 btm = highest + 1;
19978 else if (ascent <= 0)
19979 /* One extra pixel between two glyphs. */
19980 btm = lowest - 1 - ascent - descent;
19981 }
19982 }
19983 else
19984 {
19985 /* A composition rule is specified by an integer
19986 value that encodes global and new reference
19987 points (GREF and NREF). GREF and NREF are
19988 specified by numbers as below:
19989
19990 0---1---2 -- ascent
19991 | |
19992 | |
19993 | |
19994 9--10--11 -- center
19995 | |
19996 ---3---4---5--- baseline
19997 | |
19998 6---7---8 -- descent
19999 */
20000 int rule = COMPOSITION_RULE (cmp, i);
20001 int gref, nref, grefx, grefy, nrefx, nrefy;
20002
20003 COMPOSITION_DECODE_RULE (rule, gref, nref);
20004 grefx = gref % 3, nrefx = nref % 3;
20005 grefy = gref / 3, nrefy = nref / 3;
20006
20007 left = (leftmost
20008 + grefx * (rightmost - leftmost) / 2
20009 - nrefx * width / 2);
20010 btm = ((grefy == 0 ? highest
20011 : grefy == 1 ? 0
20012 : grefy == 2 ? lowest
20013 : (highest + lowest) / 2)
20014 - (nrefy == 0 ? ascent + descent
20015 : nrefy == 1 ? descent - boff
20016 : nrefy == 2 ? 0
20017 : (ascent + descent) / 2));
20018 }
20019
20020 cmp->offsets[i * 2] = left;
20021 cmp->offsets[i * 2 + 1] = btm + descent;
20022
20023 /* Update the bounding box of the overall glyphs. */
20024 right = left + width;
20025 top = btm + descent + ascent;
20026 if (left < leftmost)
20027 leftmost = left;
20028 if (right > rightmost)
20029 rightmost = right;
20030 if (top > highest)
20031 highest = top;
20032 if (btm < lowest)
20033 lowest = btm;
20034 }
20035
20036 /* If there are glyphs whose x-offsets are negative,
20037 shift all glyphs to the right and make all x-offsets
20038 non-negative. */
20039 if (leftmost < 0)
20040 {
20041 for (i = 0; i < cmp->glyph_len; i++)
20042 cmp->offsets[i * 2] -= leftmost;
20043 rightmost -= leftmost;
20044 }
20045
20046 cmp->pixel_width = rightmost;
20047 cmp->ascent = highest;
20048 cmp->descent = - lowest;
20049 if (cmp->ascent < font_ascent)
20050 cmp->ascent = font_ascent;
20051 if (cmp->descent < font_descent)
20052 cmp->descent = font_descent;
20053 }
20054
20055 it->pixel_width = cmp->pixel_width;
20056 it->ascent = it->phys_ascent = cmp->ascent;
20057 it->descent = it->phys_descent = cmp->descent;
20058
20059 if (face->box != FACE_NO_BOX)
20060 {
20061 int thick = face->box_line_width;
20062
20063 if (thick > 0)
20064 {
20065 it->ascent += thick;
20066 it->descent += thick;
20067 }
20068 else
20069 thick = - thick;
20070
20071 if (it->start_of_box_run_p)
20072 it->pixel_width += thick;
20073 if (it->end_of_box_run_p)
20074 it->pixel_width += thick;
20075 }
20076
20077 /* If face has an overline, add the height of the overline
20078 (1 pixel) and a 1 pixel margin to the character height. */
20079 if (face->overline_p)
20080 it->ascent += 2;
20081
20082 take_vertical_position_into_account (it);
20083
20084 if (it->glyph_row)
20085 append_composite_glyph (it);
20086 }
20087 else if (it->what == IT_IMAGE)
20088 produce_image_glyph (it);
20089 else if (it->what == IT_STRETCH)
20090 produce_stretch_glyph (it);
20091
20092 /* Accumulate dimensions. Note: can't assume that it->descent > 0
20093 because this isn't true for images with `:ascent 100'. */
20094 xassert (it->ascent >= 0 && it->descent >= 0);
20095 if (it->area == TEXT_AREA)
20096 it->current_x += it->pixel_width;
20097
20098 if (extra_line_spacing > 0)
20099 {
20100 it->descent += extra_line_spacing;
20101 if (extra_line_spacing > it->max_extra_line_spacing)
20102 it->max_extra_line_spacing = extra_line_spacing;
20103 }
20104
20105 it->max_ascent = max (it->max_ascent, it->ascent);
20106 it->max_descent = max (it->max_descent, it->descent);
20107 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
20108 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
20109 }
20110
20111 /* EXPORT for RIF:
20112 Output LEN glyphs starting at START at the nominal cursor position.
20113 Advance the nominal cursor over the text. The global variable
20114 updated_window contains the window being updated, updated_row is
20115 the glyph row being updated, and updated_area is the area of that
20116 row being updated. */
20117
20118 void
20119 x_write_glyphs (start, len)
20120 struct glyph *start;
20121 int len;
20122 {
20123 int x, hpos;
20124
20125 xassert (updated_window && updated_row);
20126 BLOCK_INPUT;
20127
20128 /* Write glyphs. */
20129
20130 hpos = start - updated_row->glyphs[updated_area];
20131 x = draw_glyphs (updated_window, output_cursor.x,
20132 updated_row, updated_area,
20133 hpos, hpos + len,
20134 DRAW_NORMAL_TEXT, 0);
20135
20136 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
20137 if (updated_area == TEXT_AREA
20138 && updated_window->phys_cursor_on_p
20139 && updated_window->phys_cursor.vpos == output_cursor.vpos
20140 && updated_window->phys_cursor.hpos >= hpos
20141 && updated_window->phys_cursor.hpos < hpos + len)
20142 updated_window->phys_cursor_on_p = 0;
20143
20144 UNBLOCK_INPUT;
20145
20146 /* Advance the output cursor. */
20147 output_cursor.hpos += len;
20148 output_cursor.x = x;
20149 }
20150
20151
20152 /* EXPORT for RIF:
20153 Insert LEN glyphs from START at the nominal cursor position. */
20154
20155 void
20156 x_insert_glyphs (start, len)
20157 struct glyph *start;
20158 int len;
20159 {
20160 struct frame *f;
20161 struct window *w;
20162 int line_height, shift_by_width, shifted_region_width;
20163 struct glyph_row *row;
20164 struct glyph *glyph;
20165 int frame_x, frame_y, hpos;
20166
20167 xassert (updated_window && updated_row);
20168 BLOCK_INPUT;
20169 w = updated_window;
20170 f = XFRAME (WINDOW_FRAME (w));
20171
20172 /* Get the height of the line we are in. */
20173 row = updated_row;
20174 line_height = row->height;
20175
20176 /* Get the width of the glyphs to insert. */
20177 shift_by_width = 0;
20178 for (glyph = start; glyph < start + len; ++glyph)
20179 shift_by_width += glyph->pixel_width;
20180
20181 /* Get the width of the region to shift right. */
20182 shifted_region_width = (window_box_width (w, updated_area)
20183 - output_cursor.x
20184 - shift_by_width);
20185
20186 /* Shift right. */
20187 frame_x = window_box_left (w, updated_area) + output_cursor.x;
20188 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
20189
20190 FRAME_RIF (f)->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
20191 line_height, shift_by_width);
20192
20193 /* Write the glyphs. */
20194 hpos = start - row->glyphs[updated_area];
20195 draw_glyphs (w, output_cursor.x, row, updated_area,
20196 hpos, hpos + len,
20197 DRAW_NORMAL_TEXT, 0);
20198
20199 /* Advance the output cursor. */
20200 output_cursor.hpos += len;
20201 output_cursor.x += shift_by_width;
20202 UNBLOCK_INPUT;
20203 }
20204
20205
20206 /* EXPORT for RIF:
20207 Erase the current text line from the nominal cursor position
20208 (inclusive) to pixel column TO_X (exclusive). The idea is that
20209 everything from TO_X onward is already erased.
20210
20211 TO_X is a pixel position relative to updated_area of
20212 updated_window. TO_X == -1 means clear to the end of this area. */
20213
20214 void
20215 x_clear_end_of_line (to_x)
20216 int to_x;
20217 {
20218 struct frame *f;
20219 struct window *w = updated_window;
20220 int max_x, min_y, max_y;
20221 int from_x, from_y, to_y;
20222
20223 xassert (updated_window && updated_row);
20224 f = XFRAME (w->frame);
20225
20226 if (updated_row->full_width_p)
20227 max_x = WINDOW_TOTAL_WIDTH (w);
20228 else
20229 max_x = window_box_width (w, updated_area);
20230 max_y = window_text_bottom_y (w);
20231
20232 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
20233 of window. For TO_X > 0, truncate to end of drawing area. */
20234 if (to_x == 0)
20235 return;
20236 else if (to_x < 0)
20237 to_x = max_x;
20238 else
20239 to_x = min (to_x, max_x);
20240
20241 to_y = min (max_y, output_cursor.y + updated_row->height);
20242
20243 /* Notice if the cursor will be cleared by this operation. */
20244 if (!updated_row->full_width_p)
20245 notice_overwritten_cursor (w, updated_area,
20246 output_cursor.x, -1,
20247 updated_row->y,
20248 MATRIX_ROW_BOTTOM_Y (updated_row));
20249
20250 from_x = output_cursor.x;
20251
20252 /* Translate to frame coordinates. */
20253 if (updated_row->full_width_p)
20254 {
20255 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
20256 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
20257 }
20258 else
20259 {
20260 int area_left = window_box_left (w, updated_area);
20261 from_x += area_left;
20262 to_x += area_left;
20263 }
20264
20265 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
20266 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
20267 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
20268
20269 /* Prevent inadvertently clearing to end of the X window. */
20270 if (to_x > from_x && to_y > from_y)
20271 {
20272 BLOCK_INPUT;
20273 FRAME_RIF (f)->clear_frame_area (f, from_x, from_y,
20274 to_x - from_x, to_y - from_y);
20275 UNBLOCK_INPUT;
20276 }
20277 }
20278
20279 #endif /* HAVE_WINDOW_SYSTEM */
20280
20281
20282 \f
20283 /***********************************************************************
20284 Cursor types
20285 ***********************************************************************/
20286
20287 /* Value is the internal representation of the specified cursor type
20288 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
20289 of the bar cursor. */
20290
20291 static enum text_cursor_kinds
20292 get_specified_cursor_type (arg, width)
20293 Lisp_Object arg;
20294 int *width;
20295 {
20296 enum text_cursor_kinds type;
20297
20298 if (NILP (arg))
20299 return NO_CURSOR;
20300
20301 if (EQ (arg, Qbox))
20302 return FILLED_BOX_CURSOR;
20303
20304 if (EQ (arg, Qhollow))
20305 return HOLLOW_BOX_CURSOR;
20306
20307 if (EQ (arg, Qbar))
20308 {
20309 *width = 2;
20310 return BAR_CURSOR;
20311 }
20312
20313 if (CONSP (arg)
20314 && EQ (XCAR (arg), Qbar)
20315 && INTEGERP (XCDR (arg))
20316 && XINT (XCDR (arg)) >= 0)
20317 {
20318 *width = XINT (XCDR (arg));
20319 return BAR_CURSOR;
20320 }
20321
20322 if (EQ (arg, Qhbar))
20323 {
20324 *width = 2;
20325 return HBAR_CURSOR;
20326 }
20327
20328 if (CONSP (arg)
20329 && EQ (XCAR (arg), Qhbar)
20330 && INTEGERP (XCDR (arg))
20331 && XINT (XCDR (arg)) >= 0)
20332 {
20333 *width = XINT (XCDR (arg));
20334 return HBAR_CURSOR;
20335 }
20336
20337 /* Treat anything unknown as "hollow box cursor".
20338 It was bad to signal an error; people have trouble fixing
20339 .Xdefaults with Emacs, when it has something bad in it. */
20340 type = HOLLOW_BOX_CURSOR;
20341
20342 return type;
20343 }
20344
20345 /* Set the default cursor types for specified frame. */
20346 void
20347 set_frame_cursor_types (f, arg)
20348 struct frame *f;
20349 Lisp_Object arg;
20350 {
20351 int width;
20352 Lisp_Object tem;
20353
20354 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
20355 FRAME_CURSOR_WIDTH (f) = width;
20356
20357 /* By default, set up the blink-off state depending on the on-state. */
20358
20359 tem = Fassoc (arg, Vblink_cursor_alist);
20360 if (!NILP (tem))
20361 {
20362 FRAME_BLINK_OFF_CURSOR (f)
20363 = get_specified_cursor_type (XCDR (tem), &width);
20364 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
20365 }
20366 else
20367 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
20368 }
20369
20370
20371 /* Return the cursor we want to be displayed in window W. Return
20372 width of bar/hbar cursor through WIDTH arg. Return with
20373 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
20374 (i.e. if the `system caret' should track this cursor).
20375
20376 In a mini-buffer window, we want the cursor only to appear if we
20377 are reading input from this window. For the selected window, we
20378 want the cursor type given by the frame parameter or buffer local
20379 setting of cursor-type. If explicitly marked off, draw no cursor.
20380 In all other cases, we want a hollow box cursor. */
20381
20382 static enum text_cursor_kinds
20383 get_window_cursor_type (w, glyph, width, active_cursor)
20384 struct window *w;
20385 struct glyph *glyph;
20386 int *width;
20387 int *active_cursor;
20388 {
20389 struct frame *f = XFRAME (w->frame);
20390 struct buffer *b = XBUFFER (w->buffer);
20391 int cursor_type = DEFAULT_CURSOR;
20392 Lisp_Object alt_cursor;
20393 int non_selected = 0;
20394
20395 *active_cursor = 1;
20396
20397 /* Echo area */
20398 if (cursor_in_echo_area
20399 && FRAME_HAS_MINIBUF_P (f)
20400 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
20401 {
20402 if (w == XWINDOW (echo_area_window))
20403 {
20404 *width = FRAME_CURSOR_WIDTH (f);
20405 return FRAME_DESIRED_CURSOR (f);
20406 }
20407
20408 *active_cursor = 0;
20409 non_selected = 1;
20410 }
20411
20412 /* Nonselected window or nonselected frame. */
20413 else if (w != XWINDOW (f->selected_window)
20414 #ifdef HAVE_WINDOW_SYSTEM
20415 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
20416 #endif
20417 )
20418 {
20419 *active_cursor = 0;
20420
20421 if (MINI_WINDOW_P (w) && minibuf_level == 0)
20422 return NO_CURSOR;
20423
20424 non_selected = 1;
20425 }
20426
20427 /* Never display a cursor in a window in which cursor-type is nil. */
20428 if (NILP (b->cursor_type))
20429 return NO_CURSOR;
20430
20431 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
20432 if (non_selected)
20433 {
20434 alt_cursor = XBUFFER (w->buffer)->cursor_in_non_selected_windows;
20435 return get_specified_cursor_type (alt_cursor, width);
20436 }
20437
20438 /* Get the normal cursor type for this window. */
20439 if (EQ (b->cursor_type, Qt))
20440 {
20441 cursor_type = FRAME_DESIRED_CURSOR (f);
20442 *width = FRAME_CURSOR_WIDTH (f);
20443 }
20444 else
20445 cursor_type = get_specified_cursor_type (b->cursor_type, width);
20446
20447 /* Use normal cursor if not blinked off. */
20448 if (!w->cursor_off_p)
20449 {
20450 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
20451 if (cursor_type == FILLED_BOX_CURSOR)
20452 cursor_type = HOLLOW_BOX_CURSOR;
20453 }
20454 return cursor_type;
20455 }
20456
20457 /* Cursor is blinked off, so determine how to "toggle" it. */
20458
20459 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
20460 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
20461 return get_specified_cursor_type (XCDR (alt_cursor), width);
20462
20463 /* Then see if frame has specified a specific blink off cursor type. */
20464 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
20465 {
20466 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
20467 return FRAME_BLINK_OFF_CURSOR (f);
20468 }
20469
20470 #if 0
20471 /* Some people liked having a permanently visible blinking cursor,
20472 while others had very strong opinions against it. So it was
20473 decided to remove it. KFS 2003-09-03 */
20474
20475 /* Finally perform built-in cursor blinking:
20476 filled box <-> hollow box
20477 wide [h]bar <-> narrow [h]bar
20478 narrow [h]bar <-> no cursor
20479 other type <-> no cursor */
20480
20481 if (cursor_type == FILLED_BOX_CURSOR)
20482 return HOLLOW_BOX_CURSOR;
20483
20484 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
20485 {
20486 *width = 1;
20487 return cursor_type;
20488 }
20489 #endif
20490
20491 return NO_CURSOR;
20492 }
20493
20494
20495 #ifdef HAVE_WINDOW_SYSTEM
20496
20497 /* Notice when the text cursor of window W has been completely
20498 overwritten by a drawing operation that outputs glyphs in AREA
20499 starting at X0 and ending at X1 in the line starting at Y0 and
20500 ending at Y1. X coordinates are area-relative. X1 < 0 means all
20501 the rest of the line after X0 has been written. Y coordinates
20502 are window-relative. */
20503
20504 static void
20505 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
20506 struct window *w;
20507 enum glyph_row_area area;
20508 int x0, y0, x1, y1;
20509 {
20510 int cx0, cx1, cy0, cy1;
20511 struct glyph_row *row;
20512
20513 if (!w->phys_cursor_on_p)
20514 return;
20515 if (area != TEXT_AREA)
20516 return;
20517
20518 if (w->phys_cursor.vpos < 0
20519 || w->phys_cursor.vpos >= w->current_matrix->nrows
20520 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
20521 !(row->enabled_p && row->displays_text_p)))
20522 return;
20523
20524 if (row->cursor_in_fringe_p)
20525 {
20526 row->cursor_in_fringe_p = 0;
20527 draw_fringe_bitmap (w, row, 0);
20528 w->phys_cursor_on_p = 0;
20529 return;
20530 }
20531
20532 cx0 = w->phys_cursor.x;
20533 cx1 = cx0 + w->phys_cursor_width;
20534 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20535 return;
20536
20537 /* The cursor image will be completely removed from the
20538 screen if the output area intersects the cursor area in
20539 y-direction. When we draw in [y0 y1[, and some part of
20540 the cursor is at y < y0, that part must have been drawn
20541 before. When scrolling, the cursor is erased before
20542 actually scrolling, so we don't come here. When not
20543 scrolling, the rows above the old cursor row must have
20544 changed, and in this case these rows must have written
20545 over the cursor image.
20546
20547 Likewise if part of the cursor is below y1, with the
20548 exception of the cursor being in the first blank row at
20549 the buffer and window end because update_text_area
20550 doesn't draw that row. (Except when it does, but
20551 that's handled in update_text_area.) */
20552
20553 cy0 = w->phys_cursor.y;
20554 cy1 = cy0 + w->phys_cursor_height;
20555 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20556 return;
20557
20558 w->phys_cursor_on_p = 0;
20559 }
20560
20561 #endif /* HAVE_WINDOW_SYSTEM */
20562
20563 \f
20564 /************************************************************************
20565 Mouse Face
20566 ************************************************************************/
20567
20568 #ifdef HAVE_WINDOW_SYSTEM
20569
20570 /* EXPORT for RIF:
20571 Fix the display of area AREA of overlapping row ROW in window W. */
20572
20573 void
20574 x_fix_overlapping_area (w, row, area)
20575 struct window *w;
20576 struct glyph_row *row;
20577 enum glyph_row_area area;
20578 {
20579 int i, x;
20580
20581 BLOCK_INPUT;
20582
20583 x = 0;
20584 for (i = 0; i < row->used[area];)
20585 {
20586 if (row->glyphs[area][i].overlaps_vertically_p)
20587 {
20588 int start = i, start_x = x;
20589
20590 do
20591 {
20592 x += row->glyphs[area][i].pixel_width;
20593 ++i;
20594 }
20595 while (i < row->used[area]
20596 && row->glyphs[area][i].overlaps_vertically_p);
20597
20598 draw_glyphs (w, start_x, row, area,
20599 start, i,
20600 DRAW_NORMAL_TEXT, 1);
20601 }
20602 else
20603 {
20604 x += row->glyphs[area][i].pixel_width;
20605 ++i;
20606 }
20607 }
20608
20609 UNBLOCK_INPUT;
20610 }
20611
20612
20613 /* EXPORT:
20614 Draw the cursor glyph of window W in glyph row ROW. See the
20615 comment of draw_glyphs for the meaning of HL. */
20616
20617 void
20618 draw_phys_cursor_glyph (w, row, hl)
20619 struct window *w;
20620 struct glyph_row *row;
20621 enum draw_glyphs_face hl;
20622 {
20623 /* If cursor hpos is out of bounds, don't draw garbage. This can
20624 happen in mini-buffer windows when switching between echo area
20625 glyphs and mini-buffer. */
20626 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20627 {
20628 int on_p = w->phys_cursor_on_p;
20629 int x1;
20630 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20631 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20632 hl, 0);
20633 w->phys_cursor_on_p = on_p;
20634
20635 if (hl == DRAW_CURSOR)
20636 w->phys_cursor_width = x1 - w->phys_cursor.x;
20637 /* When we erase the cursor, and ROW is overlapped by other
20638 rows, make sure that these overlapping parts of other rows
20639 are redrawn. */
20640 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20641 {
20642 if (row > w->current_matrix->rows
20643 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20644 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20645
20646 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20647 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20648 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20649 }
20650 }
20651 }
20652
20653
20654 /* EXPORT:
20655 Erase the image of a cursor of window W from the screen. */
20656
20657 void
20658 erase_phys_cursor (w)
20659 struct window *w;
20660 {
20661 struct frame *f = XFRAME (w->frame);
20662 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20663 int hpos = w->phys_cursor.hpos;
20664 int vpos = w->phys_cursor.vpos;
20665 int mouse_face_here_p = 0;
20666 struct glyph_matrix *active_glyphs = w->current_matrix;
20667 struct glyph_row *cursor_row;
20668 struct glyph *cursor_glyph;
20669 enum draw_glyphs_face hl;
20670
20671 /* No cursor displayed or row invalidated => nothing to do on the
20672 screen. */
20673 if (w->phys_cursor_type == NO_CURSOR)
20674 goto mark_cursor_off;
20675
20676 /* VPOS >= active_glyphs->nrows means that window has been resized.
20677 Don't bother to erase the cursor. */
20678 if (vpos >= active_glyphs->nrows)
20679 goto mark_cursor_off;
20680
20681 /* If row containing cursor is marked invalid, there is nothing we
20682 can do. */
20683 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20684 if (!cursor_row->enabled_p)
20685 goto mark_cursor_off;
20686
20687 /* If line spacing is > 0, old cursor may only be partially visible in
20688 window after split-window. So adjust visible height. */
20689 cursor_row->visible_height = min (cursor_row->visible_height,
20690 window_text_bottom_y (w) - cursor_row->y);
20691
20692 /* If row is completely invisible, don't attempt to delete a cursor which
20693 isn't there. This can happen if cursor is at top of a window, and
20694 we switch to a buffer with a header line in that window. */
20695 if (cursor_row->visible_height <= 0)
20696 goto mark_cursor_off;
20697
20698 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20699 if (cursor_row->cursor_in_fringe_p)
20700 {
20701 cursor_row->cursor_in_fringe_p = 0;
20702 draw_fringe_bitmap (w, cursor_row, 0);
20703 goto mark_cursor_off;
20704 }
20705
20706 /* This can happen when the new row is shorter than the old one.
20707 In this case, either draw_glyphs or clear_end_of_line
20708 should have cleared the cursor. Note that we wouldn't be
20709 able to erase the cursor in this case because we don't have a
20710 cursor glyph at hand. */
20711 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20712 goto mark_cursor_off;
20713
20714 /* If the cursor is in the mouse face area, redisplay that when
20715 we clear the cursor. */
20716 if (! NILP (dpyinfo->mouse_face_window)
20717 && w == XWINDOW (dpyinfo->mouse_face_window)
20718 && (vpos > dpyinfo->mouse_face_beg_row
20719 || (vpos == dpyinfo->mouse_face_beg_row
20720 && hpos >= dpyinfo->mouse_face_beg_col))
20721 && (vpos < dpyinfo->mouse_face_end_row
20722 || (vpos == dpyinfo->mouse_face_end_row
20723 && hpos < dpyinfo->mouse_face_end_col))
20724 /* Don't redraw the cursor's spot in mouse face if it is at the
20725 end of a line (on a newline). The cursor appears there, but
20726 mouse highlighting does not. */
20727 && cursor_row->used[TEXT_AREA] > hpos)
20728 mouse_face_here_p = 1;
20729
20730 /* Maybe clear the display under the cursor. */
20731 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20732 {
20733 int x, y;
20734 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20735 int width;
20736
20737 cursor_glyph = get_phys_cursor_glyph (w);
20738 if (cursor_glyph == NULL)
20739 goto mark_cursor_off;
20740
20741 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20742 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20743 width = min (cursor_glyph->pixel_width,
20744 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
20745
20746 FRAME_RIF (f)->clear_frame_area (f, x, y, width, cursor_row->visible_height);
20747 }
20748
20749 /* Erase the cursor by redrawing the character underneath it. */
20750 if (mouse_face_here_p)
20751 hl = DRAW_MOUSE_FACE;
20752 else
20753 hl = DRAW_NORMAL_TEXT;
20754 draw_phys_cursor_glyph (w, cursor_row, hl);
20755
20756 mark_cursor_off:
20757 w->phys_cursor_on_p = 0;
20758 w->phys_cursor_type = NO_CURSOR;
20759 }
20760
20761
20762 /* EXPORT:
20763 Display or clear cursor of window W. If ON is zero, clear the
20764 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20765 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20766
20767 void
20768 display_and_set_cursor (w, on, hpos, vpos, x, y)
20769 struct window *w;
20770 int on, hpos, vpos, x, y;
20771 {
20772 struct frame *f = XFRAME (w->frame);
20773 int new_cursor_type;
20774 int new_cursor_width;
20775 int active_cursor;
20776 struct glyph_row *glyph_row;
20777 struct glyph *glyph;
20778
20779 /* This is pointless on invisible frames, and dangerous on garbaged
20780 windows and frames; in the latter case, the frame or window may
20781 be in the midst of changing its size, and x and y may be off the
20782 window. */
20783 if (! FRAME_VISIBLE_P (f)
20784 || FRAME_GARBAGED_P (f)
20785 || vpos >= w->current_matrix->nrows
20786 || hpos >= w->current_matrix->matrix_w)
20787 return;
20788
20789 /* If cursor is off and we want it off, return quickly. */
20790 if (!on && !w->phys_cursor_on_p)
20791 return;
20792
20793 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20794 /* If cursor row is not enabled, we don't really know where to
20795 display the cursor. */
20796 if (!glyph_row->enabled_p)
20797 {
20798 w->phys_cursor_on_p = 0;
20799 return;
20800 }
20801
20802 glyph = NULL;
20803 if (!glyph_row->exact_window_width_line_p
20804 || hpos < glyph_row->used[TEXT_AREA])
20805 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20806
20807 xassert (interrupt_input_blocked);
20808
20809 /* Set new_cursor_type to the cursor we want to be displayed. */
20810 new_cursor_type = get_window_cursor_type (w, glyph,
20811 &new_cursor_width, &active_cursor);
20812
20813 /* If cursor is currently being shown and we don't want it to be or
20814 it is in the wrong place, or the cursor type is not what we want,
20815 erase it. */
20816 if (w->phys_cursor_on_p
20817 && (!on
20818 || w->phys_cursor.x != x
20819 || w->phys_cursor.y != y
20820 || new_cursor_type != w->phys_cursor_type
20821 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20822 && new_cursor_width != w->phys_cursor_width)))
20823 erase_phys_cursor (w);
20824
20825 /* Don't check phys_cursor_on_p here because that flag is only set
20826 to zero in some cases where we know that the cursor has been
20827 completely erased, to avoid the extra work of erasing the cursor
20828 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20829 still not be visible, or it has only been partly erased. */
20830 if (on)
20831 {
20832 w->phys_cursor_ascent = glyph_row->ascent;
20833 w->phys_cursor_height = glyph_row->height;
20834
20835 /* Set phys_cursor_.* before x_draw_.* is called because some
20836 of them may need the information. */
20837 w->phys_cursor.x = x;
20838 w->phys_cursor.y = glyph_row->y;
20839 w->phys_cursor.hpos = hpos;
20840 w->phys_cursor.vpos = vpos;
20841 }
20842
20843 FRAME_RIF (f)->draw_window_cursor (w, glyph_row, x, y,
20844 new_cursor_type, new_cursor_width,
20845 on, active_cursor);
20846 }
20847
20848
20849 /* Switch the display of W's cursor on or off, according to the value
20850 of ON. */
20851
20852 static void
20853 update_window_cursor (w, on)
20854 struct window *w;
20855 int on;
20856 {
20857 /* Don't update cursor in windows whose frame is in the process
20858 of being deleted. */
20859 if (w->current_matrix)
20860 {
20861 BLOCK_INPUT;
20862 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20863 w->phys_cursor.x, w->phys_cursor.y);
20864 UNBLOCK_INPUT;
20865 }
20866 }
20867
20868
20869 /* Call update_window_cursor with parameter ON_P on all leaf windows
20870 in the window tree rooted at W. */
20871
20872 static void
20873 update_cursor_in_window_tree (w, on_p)
20874 struct window *w;
20875 int on_p;
20876 {
20877 while (w)
20878 {
20879 if (!NILP (w->hchild))
20880 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20881 else if (!NILP (w->vchild))
20882 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20883 else
20884 update_window_cursor (w, on_p);
20885
20886 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20887 }
20888 }
20889
20890
20891 /* EXPORT:
20892 Display the cursor on window W, or clear it, according to ON_P.
20893 Don't change the cursor's position. */
20894
20895 void
20896 x_update_cursor (f, on_p)
20897 struct frame *f;
20898 int on_p;
20899 {
20900 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20901 }
20902
20903
20904 /* EXPORT:
20905 Clear the cursor of window W to background color, and mark the
20906 cursor as not shown. This is used when the text where the cursor
20907 is is about to be rewritten. */
20908
20909 void
20910 x_clear_cursor (w)
20911 struct window *w;
20912 {
20913 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20914 update_window_cursor (w, 0);
20915 }
20916
20917
20918 /* EXPORT:
20919 Display the active region described by mouse_face_* according to DRAW. */
20920
20921 void
20922 show_mouse_face (dpyinfo, draw)
20923 Display_Info *dpyinfo;
20924 enum draw_glyphs_face draw;
20925 {
20926 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20927 struct frame *f = XFRAME (WINDOW_FRAME (w));
20928
20929 if (/* If window is in the process of being destroyed, don't bother
20930 to do anything. */
20931 w->current_matrix != NULL
20932 /* Don't update mouse highlight if hidden */
20933 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20934 /* Recognize when we are called to operate on rows that don't exist
20935 anymore. This can happen when a window is split. */
20936 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20937 {
20938 int phys_cursor_on_p = w->phys_cursor_on_p;
20939 struct glyph_row *row, *first, *last;
20940
20941 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20942 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20943
20944 for (row = first; row <= last && row->enabled_p; ++row)
20945 {
20946 int start_hpos, end_hpos, start_x;
20947
20948 /* For all but the first row, the highlight starts at column 0. */
20949 if (row == first)
20950 {
20951 start_hpos = dpyinfo->mouse_face_beg_col;
20952 start_x = dpyinfo->mouse_face_beg_x;
20953 }
20954 else
20955 {
20956 start_hpos = 0;
20957 start_x = 0;
20958 }
20959
20960 if (row == last)
20961 end_hpos = dpyinfo->mouse_face_end_col;
20962 else
20963 end_hpos = row->used[TEXT_AREA];
20964
20965 if (end_hpos > start_hpos)
20966 {
20967 draw_glyphs (w, start_x, row, TEXT_AREA,
20968 start_hpos, end_hpos,
20969 draw, 0);
20970
20971 row->mouse_face_p
20972 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20973 }
20974 }
20975
20976 /* When we've written over the cursor, arrange for it to
20977 be displayed again. */
20978 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20979 {
20980 BLOCK_INPUT;
20981 display_and_set_cursor (w, 1,
20982 w->phys_cursor.hpos, w->phys_cursor.vpos,
20983 w->phys_cursor.x, w->phys_cursor.y);
20984 UNBLOCK_INPUT;
20985 }
20986 }
20987
20988 /* Change the mouse cursor. */
20989 if (draw == DRAW_NORMAL_TEXT)
20990 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20991 else if (draw == DRAW_MOUSE_FACE)
20992 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20993 else
20994 FRAME_RIF (f)->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20995 }
20996
20997 /* EXPORT:
20998 Clear out the mouse-highlighted active region.
20999 Redraw it un-highlighted first. Value is non-zero if mouse
21000 face was actually drawn unhighlighted. */
21001
21002 int
21003 clear_mouse_face (dpyinfo)
21004 Display_Info *dpyinfo;
21005 {
21006 int cleared = 0;
21007
21008 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
21009 {
21010 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
21011 cleared = 1;
21012 }
21013
21014 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21015 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21016 dpyinfo->mouse_face_window = Qnil;
21017 dpyinfo->mouse_face_overlay = Qnil;
21018 return cleared;
21019 }
21020
21021
21022 /* EXPORT:
21023 Non-zero if physical cursor of window W is within mouse face. */
21024
21025 int
21026 cursor_in_mouse_face_p (w)
21027 struct window *w;
21028 {
21029 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21030 int in_mouse_face = 0;
21031
21032 if (WINDOWP (dpyinfo->mouse_face_window)
21033 && XWINDOW (dpyinfo->mouse_face_window) == w)
21034 {
21035 int hpos = w->phys_cursor.hpos;
21036 int vpos = w->phys_cursor.vpos;
21037
21038 if (vpos >= dpyinfo->mouse_face_beg_row
21039 && vpos <= dpyinfo->mouse_face_end_row
21040 && (vpos > dpyinfo->mouse_face_beg_row
21041 || hpos >= dpyinfo->mouse_face_beg_col)
21042 && (vpos < dpyinfo->mouse_face_end_row
21043 || hpos < dpyinfo->mouse_face_end_col
21044 || dpyinfo->mouse_face_past_end))
21045 in_mouse_face = 1;
21046 }
21047
21048 return in_mouse_face;
21049 }
21050
21051
21052
21053 \f
21054 /* Find the glyph matrix position of buffer position CHARPOS in window
21055 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
21056 current glyphs must be up to date. If CHARPOS is above window
21057 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
21058 of last line in W. In the row containing CHARPOS, stop before glyphs
21059 having STOP as object. */
21060
21061 #if 1 /* This is a version of fast_find_position that's more correct
21062 in the presence of hscrolling, for example. I didn't install
21063 it right away because the problem fixed is minor, it failed
21064 in 20.x as well, and I think it's too risky to install
21065 so near the release of 21.1. 2001-09-25 gerd. */
21066
21067 static int
21068 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
21069 struct window *w;
21070 int charpos;
21071 int *hpos, *vpos, *x, *y;
21072 Lisp_Object stop;
21073 {
21074 struct glyph_row *row, *first;
21075 struct glyph *glyph, *end;
21076 int past_end = 0;
21077
21078 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21079 if (charpos < MATRIX_ROW_START_CHARPOS (first))
21080 {
21081 *x = first->x;
21082 *y = first->y;
21083 *hpos = 0;
21084 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
21085 return 1;
21086 }
21087
21088 row = row_containing_pos (w, charpos, first, NULL, 0);
21089 if (row == NULL)
21090 {
21091 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
21092 past_end = 1;
21093 }
21094
21095 /* If whole rows or last part of a row came from a display overlay,
21096 row_containing_pos will skip over such rows because their end pos
21097 equals the start pos of the overlay or interval.
21098
21099 Move back if we have a STOP object and previous row's
21100 end glyph came from STOP. */
21101 if (!NILP (stop))
21102 {
21103 struct glyph_row *prev;
21104 while ((prev = row - 1, prev >= first)
21105 && MATRIX_ROW_END_CHARPOS (prev) == charpos
21106 && prev->used[TEXT_AREA] > 0)
21107 {
21108 struct glyph *beg = prev->glyphs[TEXT_AREA];
21109 glyph = beg + prev->used[TEXT_AREA];
21110 while (--glyph >= beg
21111 && INTEGERP (glyph->object));
21112 if (glyph < beg
21113 || !EQ (stop, glyph->object))
21114 break;
21115 row = prev;
21116 }
21117 }
21118
21119 *x = row->x;
21120 *y = row->y;
21121 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
21122
21123 glyph = row->glyphs[TEXT_AREA];
21124 end = glyph + row->used[TEXT_AREA];
21125
21126 /* Skip over glyphs not having an object at the start of the row.
21127 These are special glyphs like truncation marks on terminal
21128 frames. */
21129 if (row->displays_text_p)
21130 while (glyph < end
21131 && INTEGERP (glyph->object)
21132 && !EQ (stop, glyph->object)
21133 && glyph->charpos < 0)
21134 {
21135 *x += glyph->pixel_width;
21136 ++glyph;
21137 }
21138
21139 while (glyph < end
21140 && !INTEGERP (glyph->object)
21141 && !EQ (stop, glyph->object)
21142 && (!BUFFERP (glyph->object)
21143 || glyph->charpos < charpos))
21144 {
21145 *x += glyph->pixel_width;
21146 ++glyph;
21147 }
21148
21149 *hpos = glyph - row->glyphs[TEXT_AREA];
21150 return !past_end;
21151 }
21152
21153 #else /* not 1 */
21154
21155 static int
21156 fast_find_position (w, pos, hpos, vpos, x, y, stop)
21157 struct window *w;
21158 int pos;
21159 int *hpos, *vpos, *x, *y;
21160 Lisp_Object stop;
21161 {
21162 int i;
21163 int lastcol;
21164 int maybe_next_line_p = 0;
21165 int line_start_position;
21166 int yb = window_text_bottom_y (w);
21167 struct glyph_row *row, *best_row;
21168 int row_vpos, best_row_vpos;
21169 int current_x;
21170
21171 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21172 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
21173
21174 while (row->y < yb)
21175 {
21176 if (row->used[TEXT_AREA])
21177 line_start_position = row->glyphs[TEXT_AREA]->charpos;
21178 else
21179 line_start_position = 0;
21180
21181 if (line_start_position > pos)
21182 break;
21183 /* If the position sought is the end of the buffer,
21184 don't include the blank lines at the bottom of the window. */
21185 else if (line_start_position == pos
21186 && pos == BUF_ZV (XBUFFER (w->buffer)))
21187 {
21188 maybe_next_line_p = 1;
21189 break;
21190 }
21191 else if (line_start_position > 0)
21192 {
21193 best_row = row;
21194 best_row_vpos = row_vpos;
21195 }
21196
21197 if (row->y + row->height >= yb)
21198 break;
21199
21200 ++row;
21201 ++row_vpos;
21202 }
21203
21204 /* Find the right column within BEST_ROW. */
21205 lastcol = 0;
21206 current_x = best_row->x;
21207 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
21208 {
21209 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
21210 int charpos = glyph->charpos;
21211
21212 if (BUFFERP (glyph->object))
21213 {
21214 if (charpos == pos)
21215 {
21216 *hpos = i;
21217 *vpos = best_row_vpos;
21218 *x = current_x;
21219 *y = best_row->y;
21220 return 1;
21221 }
21222 else if (charpos > pos)
21223 break;
21224 }
21225 else if (EQ (glyph->object, stop))
21226 break;
21227
21228 if (charpos > 0)
21229 lastcol = i;
21230 current_x += glyph->pixel_width;
21231 }
21232
21233 /* If we're looking for the end of the buffer,
21234 and we didn't find it in the line we scanned,
21235 use the start of the following line. */
21236 if (maybe_next_line_p)
21237 {
21238 ++best_row;
21239 ++best_row_vpos;
21240 lastcol = 0;
21241 current_x = best_row->x;
21242 }
21243
21244 *vpos = best_row_vpos;
21245 *hpos = lastcol + 1;
21246 *x = current_x;
21247 *y = best_row->y;
21248 return 0;
21249 }
21250
21251 #endif /* not 1 */
21252
21253
21254 /* Find the position of the glyph for position POS in OBJECT in
21255 window W's current matrix, and return in *X, *Y the pixel
21256 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
21257
21258 RIGHT_P non-zero means return the position of the right edge of the
21259 glyph, RIGHT_P zero means return the left edge position.
21260
21261 If no glyph for POS exists in the matrix, return the position of
21262 the glyph with the next smaller position that is in the matrix, if
21263 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
21264 exists in the matrix, return the position of the glyph with the
21265 next larger position in OBJECT.
21266
21267 Value is non-zero if a glyph was found. */
21268
21269 static int
21270 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
21271 struct window *w;
21272 int pos;
21273 Lisp_Object object;
21274 int *hpos, *vpos, *x, *y;
21275 int right_p;
21276 {
21277 int yb = window_text_bottom_y (w);
21278 struct glyph_row *r;
21279 struct glyph *best_glyph = NULL;
21280 struct glyph_row *best_row = NULL;
21281 int best_x = 0;
21282
21283 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21284 r->enabled_p && r->y < yb;
21285 ++r)
21286 {
21287 struct glyph *g = r->glyphs[TEXT_AREA];
21288 struct glyph *e = g + r->used[TEXT_AREA];
21289 int gx;
21290
21291 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
21292 if (EQ (g->object, object))
21293 {
21294 if (g->charpos == pos)
21295 {
21296 best_glyph = g;
21297 best_x = gx;
21298 best_row = r;
21299 goto found;
21300 }
21301 else if (best_glyph == NULL
21302 || ((abs (g->charpos - pos)
21303 < abs (best_glyph->charpos - pos))
21304 && (right_p
21305 ? g->charpos < pos
21306 : g->charpos > pos)))
21307 {
21308 best_glyph = g;
21309 best_x = gx;
21310 best_row = r;
21311 }
21312 }
21313 }
21314
21315 found:
21316
21317 if (best_glyph)
21318 {
21319 *x = best_x;
21320 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
21321
21322 if (right_p)
21323 {
21324 *x += best_glyph->pixel_width;
21325 ++*hpos;
21326 }
21327
21328 *y = best_row->y;
21329 *vpos = best_row - w->current_matrix->rows;
21330 }
21331
21332 return best_glyph != NULL;
21333 }
21334
21335
21336 /* See if position X, Y is within a hot-spot of an image. */
21337
21338 static int
21339 on_hot_spot_p (hot_spot, x, y)
21340 Lisp_Object hot_spot;
21341 int x, y;
21342 {
21343 if (!CONSP (hot_spot))
21344 return 0;
21345
21346 if (EQ (XCAR (hot_spot), Qrect))
21347 {
21348 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
21349 Lisp_Object rect = XCDR (hot_spot);
21350 Lisp_Object tem;
21351 if (!CONSP (rect))
21352 return 0;
21353 if (!CONSP (XCAR (rect)))
21354 return 0;
21355 if (!CONSP (XCDR (rect)))
21356 return 0;
21357 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
21358 return 0;
21359 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
21360 return 0;
21361 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
21362 return 0;
21363 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
21364 return 0;
21365 return 1;
21366 }
21367 else if (EQ (XCAR (hot_spot), Qcircle))
21368 {
21369 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
21370 Lisp_Object circ = XCDR (hot_spot);
21371 Lisp_Object lr, lx0, ly0;
21372 if (CONSP (circ)
21373 && CONSP (XCAR (circ))
21374 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
21375 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
21376 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
21377 {
21378 double r = XFLOATINT (lr);
21379 double dx = XINT (lx0) - x;
21380 double dy = XINT (ly0) - y;
21381 return (dx * dx + dy * dy <= r * r);
21382 }
21383 }
21384 else if (EQ (XCAR (hot_spot), Qpoly))
21385 {
21386 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
21387 if (VECTORP (XCDR (hot_spot)))
21388 {
21389 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
21390 Lisp_Object *poly = v->contents;
21391 int n = v->size;
21392 int i;
21393 int inside = 0;
21394 Lisp_Object lx, ly;
21395 int x0, y0;
21396
21397 /* Need an even number of coordinates, and at least 3 edges. */
21398 if (n < 6 || n & 1)
21399 return 0;
21400
21401 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
21402 If count is odd, we are inside polygon. Pixels on edges
21403 may or may not be included depending on actual geometry of the
21404 polygon. */
21405 if ((lx = poly[n-2], !INTEGERP (lx))
21406 || (ly = poly[n-1], !INTEGERP (lx)))
21407 return 0;
21408 x0 = XINT (lx), y0 = XINT (ly);
21409 for (i = 0; i < n; i += 2)
21410 {
21411 int x1 = x0, y1 = y0;
21412 if ((lx = poly[i], !INTEGERP (lx))
21413 || (ly = poly[i+1], !INTEGERP (ly)))
21414 return 0;
21415 x0 = XINT (lx), y0 = XINT (ly);
21416
21417 /* Does this segment cross the X line? */
21418 if (x0 >= x)
21419 {
21420 if (x1 >= x)
21421 continue;
21422 }
21423 else if (x1 < x)
21424 continue;
21425 if (y > y0 && y > y1)
21426 continue;
21427 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
21428 inside = !inside;
21429 }
21430 return inside;
21431 }
21432 }
21433 return 0;
21434 }
21435
21436 Lisp_Object
21437 find_hot_spot (map, x, y)
21438 Lisp_Object map;
21439 int x, y;
21440 {
21441 while (CONSP (map))
21442 {
21443 if (CONSP (XCAR (map))
21444 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
21445 return XCAR (map);
21446 map = XCDR (map);
21447 }
21448
21449 return Qnil;
21450 }
21451
21452 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
21453 3, 3, 0,
21454 doc: /* Lookup in image map MAP coordinates X and Y.
21455 An image map is an alist where each element has the format (AREA ID PLIST).
21456 An AREA is specified as either a rectangle, a circle, or a polygon:
21457 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
21458 pixel coordinates of the upper left and bottom right corners.
21459 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
21460 and the radius of the circle; r may be a float or integer.
21461 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
21462 vector describes one corner in the polygon.
21463 Returns the alist element for the first matching AREA in MAP. */)
21464 (map, x, y)
21465 Lisp_Object map;
21466 Lisp_Object x, y;
21467 {
21468 if (NILP (map))
21469 return Qnil;
21470
21471 CHECK_NUMBER (x);
21472 CHECK_NUMBER (y);
21473
21474 return find_hot_spot (map, XINT (x), XINT (y));
21475 }
21476
21477
21478 /* Display frame CURSOR, optionally using shape defined by POINTER. */
21479 static void
21480 define_frame_cursor1 (f, cursor, pointer)
21481 struct frame *f;
21482 Cursor cursor;
21483 Lisp_Object pointer;
21484 {
21485 /* Do not change cursor shape while dragging mouse. */
21486 if (!NILP (do_mouse_tracking))
21487 return;
21488
21489 if (!NILP (pointer))
21490 {
21491 if (EQ (pointer, Qarrow))
21492 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21493 else if (EQ (pointer, Qhand))
21494 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
21495 else if (EQ (pointer, Qtext))
21496 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21497 else if (EQ (pointer, intern ("hdrag")))
21498 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21499 #ifdef HAVE_X_WINDOWS
21500 else if (EQ (pointer, intern ("vdrag")))
21501 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
21502 #endif
21503 else if (EQ (pointer, intern ("hourglass")))
21504 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
21505 else if (EQ (pointer, Qmodeline))
21506 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
21507 else
21508 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21509 }
21510
21511 if (cursor != No_Cursor)
21512 FRAME_RIF (f)->define_frame_cursor (f, cursor);
21513 }
21514
21515 /* Take proper action when mouse has moved to the mode or header line
21516 or marginal area AREA of window W, x-position X and y-position Y.
21517 X is relative to the start of the text display area of W, so the
21518 width of bitmap areas and scroll bars must be subtracted to get a
21519 position relative to the start of the mode line. */
21520
21521 static void
21522 note_mode_line_or_margin_highlight (window, x, y, area)
21523 Lisp_Object window;
21524 int x, y;
21525 enum window_part area;
21526 {
21527 struct window *w = XWINDOW (window);
21528 struct frame *f = XFRAME (w->frame);
21529 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21530 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21531 Lisp_Object pointer = Qnil;
21532 int charpos, dx, dy, width, height;
21533 Lisp_Object string, object = Qnil;
21534 Lisp_Object pos, help;
21535
21536 Lisp_Object mouse_face;
21537 int original_x_pixel = x;
21538 struct glyph * glyph = NULL;
21539 struct glyph_row *row;
21540
21541 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
21542 {
21543 int x0;
21544 struct glyph *end;
21545
21546 string = mode_line_string (w, area, &x, &y, &charpos,
21547 &object, &dx, &dy, &width, &height);
21548
21549 row = (area == ON_MODE_LINE
21550 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
21551 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
21552
21553 /* Find glyph */
21554 if (row->mode_line_p && row->enabled_p)
21555 {
21556 glyph = row->glyphs[TEXT_AREA];
21557 end = glyph + row->used[TEXT_AREA];
21558
21559 for (x0 = original_x_pixel;
21560 glyph < end && x0 >= glyph->pixel_width;
21561 ++glyph)
21562 x0 -= glyph->pixel_width;
21563
21564 if (glyph >= end)
21565 glyph = NULL;
21566 }
21567 }
21568 else
21569 {
21570 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
21571 string = marginal_area_string (w, area, &x, &y, &charpos,
21572 &object, &dx, &dy, &width, &height);
21573 }
21574
21575 help = Qnil;
21576
21577 if (IMAGEP (object))
21578 {
21579 Lisp_Object image_map, hotspot;
21580 if ((image_map = Fplist_get (XCDR (object), QCmap),
21581 !NILP (image_map))
21582 && (hotspot = find_hot_spot (image_map, dx, dy),
21583 CONSP (hotspot))
21584 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21585 {
21586 Lisp_Object area_id, plist;
21587
21588 area_id = XCAR (hotspot);
21589 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21590 If so, we could look for mouse-enter, mouse-leave
21591 properties in PLIST (and do something...). */
21592 hotspot = XCDR (hotspot);
21593 if (CONSP (hotspot)
21594 && (plist = XCAR (hotspot), CONSP (plist)))
21595 {
21596 pointer = Fplist_get (plist, Qpointer);
21597 if (NILP (pointer))
21598 pointer = Qhand;
21599 help = Fplist_get (plist, Qhelp_echo);
21600 if (!NILP (help))
21601 {
21602 help_echo_string = help;
21603 /* Is this correct? ++kfs */
21604 XSETWINDOW (help_echo_window, w);
21605 help_echo_object = w->buffer;
21606 help_echo_pos = charpos;
21607 }
21608 }
21609 }
21610 if (NILP (pointer))
21611 pointer = Fplist_get (XCDR (object), QCpointer);
21612 }
21613
21614 if (STRINGP (string))
21615 {
21616 pos = make_number (charpos);
21617 /* If we're on a string with `help-echo' text property, arrange
21618 for the help to be displayed. This is done by setting the
21619 global variable help_echo_string to the help string. */
21620 if (NILP (help))
21621 {
21622 help = Fget_text_property (pos, Qhelp_echo, string);
21623 if (!NILP (help))
21624 {
21625 help_echo_string = help;
21626 XSETWINDOW (help_echo_window, w);
21627 help_echo_object = string;
21628 help_echo_pos = charpos;
21629 }
21630 }
21631
21632 if (NILP (pointer))
21633 pointer = Fget_text_property (pos, Qpointer, string);
21634
21635 /* Change the mouse pointer according to what is under X/Y. */
21636 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
21637 {
21638 Lisp_Object map;
21639 map = Fget_text_property (pos, Qlocal_map, string);
21640 if (!KEYMAPP (map))
21641 map = Fget_text_property (pos, Qkeymap, string);
21642 if (!KEYMAPP (map))
21643 cursor = dpyinfo->vertical_scroll_bar_cursor;
21644 }
21645
21646 /* Change the mouse face according to what is under X/Y. */
21647 mouse_face = Fget_text_property (pos, Qmouse_face, string);
21648 if (!NILP (mouse_face)
21649 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
21650 && glyph)
21651 {
21652 Lisp_Object b, e;
21653
21654 struct glyph * tmp_glyph;
21655
21656 int gpos;
21657 int gseq_length;
21658 int total_pixel_width;
21659 int ignore;
21660
21661 int vpos, hpos;
21662
21663 b = Fprevious_single_property_change (make_number (charpos + 1),
21664 Qmouse_face, string, Qnil);
21665 if (NILP (b))
21666 b = make_number (0);
21667
21668 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
21669 if (NILP (e))
21670 e = make_number (SCHARS (string));
21671
21672 /* Calculate the position(glyph position: GPOS) of GLYPH in
21673 displayed string. GPOS is different from CHARPOS.
21674
21675 CHARPOS is the position of glyph in internal string
21676 object. A mode line string format has structures which
21677 is converted to a flatten by emacs lisp interpreter.
21678 The internal string is an element of the structures.
21679 The displayed string is the flatten string. */
21680 for (tmp_glyph = glyph - 1, gpos = 0;
21681 tmp_glyph->charpos >= XINT (b);
21682 tmp_glyph--, gpos++)
21683 {
21684 if (!EQ (tmp_glyph->object, glyph->object))
21685 break;
21686 }
21687
21688 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
21689 displayed string holding GLYPH.
21690
21691 GSEQ_LENGTH is different from SCHARS (STRING).
21692 SCHARS (STRING) returns the length of the internal string. */
21693 for (tmp_glyph = glyph, gseq_length = gpos;
21694 tmp_glyph->charpos < XINT (e);
21695 tmp_glyph++, gseq_length++)
21696 {
21697 if (!EQ (tmp_glyph->object, glyph->object))
21698 break;
21699 }
21700
21701 total_pixel_width = 0;
21702 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
21703 total_pixel_width += tmp_glyph->pixel_width;
21704
21705 /* Pre calculation of re-rendering position */
21706 vpos = (x - gpos);
21707 hpos = (area == ON_MODE_LINE
21708 ? (w->current_matrix)->nrows - 1
21709 : 0);
21710
21711 /* If the re-rendering position is included in the last
21712 re-rendering area, we should do nothing. */
21713 if ( EQ (window, dpyinfo->mouse_face_window)
21714 && dpyinfo->mouse_face_beg_col <= vpos
21715 && vpos < dpyinfo->mouse_face_end_col
21716 && dpyinfo->mouse_face_beg_row == hpos )
21717 return;
21718
21719 if (clear_mouse_face (dpyinfo))
21720 cursor = No_Cursor;
21721
21722 dpyinfo->mouse_face_beg_col = vpos;
21723 dpyinfo->mouse_face_beg_row = hpos;
21724
21725 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
21726 dpyinfo->mouse_face_beg_y = 0;
21727
21728 dpyinfo->mouse_face_end_col = vpos + gseq_length;
21729 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
21730
21731 dpyinfo->mouse_face_end_x = 0;
21732 dpyinfo->mouse_face_end_y = 0;
21733
21734 dpyinfo->mouse_face_past_end = 0;
21735 dpyinfo->mouse_face_window = window;
21736
21737 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
21738 charpos,
21739 0, 0, 0, &ignore,
21740 glyph->face_id, 1);
21741 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21742
21743 if (NILP (pointer))
21744 pointer = Qhand;
21745 }
21746 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
21747 clear_mouse_face (dpyinfo);
21748 }
21749 define_frame_cursor1 (f, cursor, pointer);
21750 }
21751
21752
21753 /* EXPORT:
21754 Take proper action when the mouse has moved to position X, Y on
21755 frame F as regards highlighting characters that have mouse-face
21756 properties. Also de-highlighting chars where the mouse was before.
21757 X and Y can be negative or out of range. */
21758
21759 void
21760 note_mouse_highlight (f, x, y)
21761 struct frame *f;
21762 int x, y;
21763 {
21764 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21765 enum window_part part;
21766 Lisp_Object window;
21767 struct window *w;
21768 Cursor cursor = No_Cursor;
21769 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21770 struct buffer *b;
21771
21772 /* When a menu is active, don't highlight because this looks odd. */
21773 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21774 if (popup_activated ())
21775 return;
21776 #endif
21777
21778 if (NILP (Vmouse_highlight)
21779 || !f->glyphs_initialized_p)
21780 return;
21781
21782 dpyinfo->mouse_face_mouse_x = x;
21783 dpyinfo->mouse_face_mouse_y = y;
21784 dpyinfo->mouse_face_mouse_frame = f;
21785
21786 if (dpyinfo->mouse_face_defer)
21787 return;
21788
21789 if (gc_in_progress)
21790 {
21791 dpyinfo->mouse_face_deferred_gc = 1;
21792 return;
21793 }
21794
21795 /* Which window is that in? */
21796 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21797
21798 /* If we were displaying active text in another window, clear that.
21799 Also clear if we move out of text area in same window. */
21800 if (! EQ (window, dpyinfo->mouse_face_window)
21801 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
21802 && !NILP (dpyinfo->mouse_face_window)))
21803 clear_mouse_face (dpyinfo);
21804
21805 /* Not on a window -> return. */
21806 if (!WINDOWP (window))
21807 return;
21808
21809 /* Reset help_echo_string. It will get recomputed below. */
21810 help_echo_string = Qnil;
21811
21812 /* Convert to window-relative pixel coordinates. */
21813 w = XWINDOW (window);
21814 frame_to_window_pixel_xy (w, &x, &y);
21815
21816 /* Handle tool-bar window differently since it doesn't display a
21817 buffer. */
21818 if (EQ (window, f->tool_bar_window))
21819 {
21820 note_tool_bar_highlight (f, x, y);
21821 return;
21822 }
21823
21824 /* Mouse is on the mode, header line or margin? */
21825 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21826 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21827 {
21828 note_mode_line_or_margin_highlight (window, x, y, part);
21829 return;
21830 }
21831
21832 if (part == ON_VERTICAL_BORDER)
21833 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21834 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21835 || part == ON_SCROLL_BAR)
21836 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21837 else
21838 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21839
21840 /* Are we in a window whose display is up to date?
21841 And verify the buffer's text has not changed. */
21842 b = XBUFFER (w->buffer);
21843 if (part == ON_TEXT
21844 && EQ (w->window_end_valid, w->buffer)
21845 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21846 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21847 {
21848 int hpos, vpos, pos, i, dx, dy, area;
21849 struct glyph *glyph;
21850 Lisp_Object object;
21851 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21852 Lisp_Object *overlay_vec = NULL;
21853 int noverlays;
21854 struct buffer *obuf;
21855 int obegv, ozv, same_region;
21856
21857 /* Find the glyph under X/Y. */
21858 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21859
21860 /* Look for :pointer property on image. */
21861 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21862 {
21863 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21864 if (img != NULL && IMAGEP (img->spec))
21865 {
21866 Lisp_Object image_map, hotspot;
21867 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
21868 !NILP (image_map))
21869 && (hotspot = find_hot_spot (image_map,
21870 glyph->slice.x + dx,
21871 glyph->slice.y + dy),
21872 CONSP (hotspot))
21873 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21874 {
21875 Lisp_Object area_id, plist;
21876
21877 area_id = XCAR (hotspot);
21878 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21879 If so, we could look for mouse-enter, mouse-leave
21880 properties in PLIST (and do something...). */
21881 hotspot = XCDR (hotspot);
21882 if (CONSP (hotspot)
21883 && (plist = XCAR (hotspot), CONSP (plist)))
21884 {
21885 pointer = Fplist_get (plist, Qpointer);
21886 if (NILP (pointer))
21887 pointer = Qhand;
21888 help_echo_string = Fplist_get (plist, Qhelp_echo);
21889 if (!NILP (help_echo_string))
21890 {
21891 help_echo_window = window;
21892 help_echo_object = glyph->object;
21893 help_echo_pos = glyph->charpos;
21894 }
21895 }
21896 }
21897 if (NILP (pointer))
21898 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21899 }
21900 }
21901
21902 /* Clear mouse face if X/Y not over text. */
21903 if (glyph == NULL
21904 || area != TEXT_AREA
21905 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21906 {
21907 if (clear_mouse_face (dpyinfo))
21908 cursor = No_Cursor;
21909 if (NILP (pointer))
21910 {
21911 if (area != TEXT_AREA)
21912 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21913 else
21914 pointer = Vvoid_text_area_pointer;
21915 }
21916 goto set_cursor;
21917 }
21918
21919 pos = glyph->charpos;
21920 object = glyph->object;
21921 if (!STRINGP (object) && !BUFFERP (object))
21922 goto set_cursor;
21923
21924 /* If we get an out-of-range value, return now; avoid an error. */
21925 if (BUFFERP (object) && pos > BUF_Z (b))
21926 goto set_cursor;
21927
21928 /* Make the window's buffer temporarily current for
21929 overlays_at and compute_char_face. */
21930 obuf = current_buffer;
21931 current_buffer = b;
21932 obegv = BEGV;
21933 ozv = ZV;
21934 BEGV = BEG;
21935 ZV = Z;
21936
21937 /* Is this char mouse-active or does it have help-echo? */
21938 position = make_number (pos);
21939
21940 if (BUFFERP (object))
21941 {
21942 /* Put all the overlays we want in a vector in overlay_vec. */
21943 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21944 /* Sort overlays into increasing priority order. */
21945 noverlays = sort_overlays (overlay_vec, noverlays, w);
21946 }
21947 else
21948 noverlays = 0;
21949
21950 same_region = (EQ (window, dpyinfo->mouse_face_window)
21951 && vpos >= dpyinfo->mouse_face_beg_row
21952 && vpos <= dpyinfo->mouse_face_end_row
21953 && (vpos > dpyinfo->mouse_face_beg_row
21954 || hpos >= dpyinfo->mouse_face_beg_col)
21955 && (vpos < dpyinfo->mouse_face_end_row
21956 || hpos < dpyinfo->mouse_face_end_col
21957 || dpyinfo->mouse_face_past_end));
21958
21959 if (same_region)
21960 cursor = No_Cursor;
21961
21962 /* Check mouse-face highlighting. */
21963 if (! same_region
21964 /* If there exists an overlay with mouse-face overlapping
21965 the one we are currently highlighting, we have to
21966 check if we enter the overlapping overlay, and then
21967 highlight only that. */
21968 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21969 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21970 {
21971 /* Find the highest priority overlay that has a mouse-face
21972 property. */
21973 overlay = Qnil;
21974 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21975 {
21976 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21977 if (!NILP (mouse_face))
21978 overlay = overlay_vec[i];
21979 }
21980
21981 /* If we're actually highlighting the same overlay as
21982 before, there's no need to do that again. */
21983 if (!NILP (overlay)
21984 && EQ (overlay, dpyinfo->mouse_face_overlay))
21985 goto check_help_echo;
21986
21987 dpyinfo->mouse_face_overlay = overlay;
21988
21989 /* Clear the display of the old active region, if any. */
21990 if (clear_mouse_face (dpyinfo))
21991 cursor = No_Cursor;
21992
21993 /* If no overlay applies, get a text property. */
21994 if (NILP (overlay))
21995 mouse_face = Fget_text_property (position, Qmouse_face, object);
21996
21997 /* Handle the overlay case. */
21998 if (!NILP (overlay))
21999 {
22000 /* Find the range of text around this char that
22001 should be active. */
22002 Lisp_Object before, after;
22003 int ignore;
22004
22005 before = Foverlay_start (overlay);
22006 after = Foverlay_end (overlay);
22007 /* Record this as the current active region. */
22008 fast_find_position (w, XFASTINT (before),
22009 &dpyinfo->mouse_face_beg_col,
22010 &dpyinfo->mouse_face_beg_row,
22011 &dpyinfo->mouse_face_beg_x,
22012 &dpyinfo->mouse_face_beg_y, Qnil);
22013
22014 dpyinfo->mouse_face_past_end
22015 = !fast_find_position (w, XFASTINT (after),
22016 &dpyinfo->mouse_face_end_col,
22017 &dpyinfo->mouse_face_end_row,
22018 &dpyinfo->mouse_face_end_x,
22019 &dpyinfo->mouse_face_end_y, Qnil);
22020 dpyinfo->mouse_face_window = window;
22021
22022 dpyinfo->mouse_face_face_id
22023 = face_at_buffer_position (w, pos, 0, 0,
22024 &ignore, pos + 1,
22025 !dpyinfo->mouse_face_hidden);
22026
22027 /* Display it as active. */
22028 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22029 cursor = No_Cursor;
22030 }
22031 /* Handle the text property case. */
22032 else if (!NILP (mouse_face) && BUFFERP (object))
22033 {
22034 /* Find the range of text around this char that
22035 should be active. */
22036 Lisp_Object before, after, beginning, end;
22037 int ignore;
22038
22039 beginning = Fmarker_position (w->start);
22040 end = make_number (BUF_Z (XBUFFER (object))
22041 - XFASTINT (w->window_end_pos));
22042 before
22043 = Fprevious_single_property_change (make_number (pos + 1),
22044 Qmouse_face,
22045 object, beginning);
22046 after
22047 = Fnext_single_property_change (position, Qmouse_face,
22048 object, end);
22049
22050 /* Record this as the current active region. */
22051 fast_find_position (w, XFASTINT (before),
22052 &dpyinfo->mouse_face_beg_col,
22053 &dpyinfo->mouse_face_beg_row,
22054 &dpyinfo->mouse_face_beg_x,
22055 &dpyinfo->mouse_face_beg_y, Qnil);
22056 dpyinfo->mouse_face_past_end
22057 = !fast_find_position (w, XFASTINT (after),
22058 &dpyinfo->mouse_face_end_col,
22059 &dpyinfo->mouse_face_end_row,
22060 &dpyinfo->mouse_face_end_x,
22061 &dpyinfo->mouse_face_end_y, Qnil);
22062 dpyinfo->mouse_face_window = window;
22063
22064 if (BUFFERP (object))
22065 dpyinfo->mouse_face_face_id
22066 = face_at_buffer_position (w, pos, 0, 0,
22067 &ignore, pos + 1,
22068 !dpyinfo->mouse_face_hidden);
22069
22070 /* Display it as active. */
22071 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22072 cursor = No_Cursor;
22073 }
22074 else if (!NILP (mouse_face) && STRINGP (object))
22075 {
22076 Lisp_Object b, e;
22077 int ignore;
22078
22079 b = Fprevious_single_property_change (make_number (pos + 1),
22080 Qmouse_face,
22081 object, Qnil);
22082 e = Fnext_single_property_change (position, Qmouse_face,
22083 object, Qnil);
22084 if (NILP (b))
22085 b = make_number (0);
22086 if (NILP (e))
22087 e = make_number (SCHARS (object) - 1);
22088
22089 fast_find_string_pos (w, XINT (b), object,
22090 &dpyinfo->mouse_face_beg_col,
22091 &dpyinfo->mouse_face_beg_row,
22092 &dpyinfo->mouse_face_beg_x,
22093 &dpyinfo->mouse_face_beg_y, 0);
22094 fast_find_string_pos (w, XINT (e), object,
22095 &dpyinfo->mouse_face_end_col,
22096 &dpyinfo->mouse_face_end_row,
22097 &dpyinfo->mouse_face_end_x,
22098 &dpyinfo->mouse_face_end_y, 1);
22099 dpyinfo->mouse_face_past_end = 0;
22100 dpyinfo->mouse_face_window = window;
22101 dpyinfo->mouse_face_face_id
22102 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
22103 glyph->face_id, 1);
22104 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22105 cursor = No_Cursor;
22106 }
22107 else if (STRINGP (object) && NILP (mouse_face))
22108 {
22109 /* A string which doesn't have mouse-face, but
22110 the text ``under'' it might have. */
22111 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
22112 int start = MATRIX_ROW_START_CHARPOS (r);
22113
22114 pos = string_buffer_position (w, object, start);
22115 if (pos > 0)
22116 mouse_face = get_char_property_and_overlay (make_number (pos),
22117 Qmouse_face,
22118 w->buffer,
22119 &overlay);
22120 if (!NILP (mouse_face) && !NILP (overlay))
22121 {
22122 Lisp_Object before = Foverlay_start (overlay);
22123 Lisp_Object after = Foverlay_end (overlay);
22124 int ignore;
22125
22126 /* Note that we might not be able to find position
22127 BEFORE in the glyph matrix if the overlay is
22128 entirely covered by a `display' property. In
22129 this case, we overshoot. So let's stop in
22130 the glyph matrix before glyphs for OBJECT. */
22131 fast_find_position (w, XFASTINT (before),
22132 &dpyinfo->mouse_face_beg_col,
22133 &dpyinfo->mouse_face_beg_row,
22134 &dpyinfo->mouse_face_beg_x,
22135 &dpyinfo->mouse_face_beg_y,
22136 object);
22137
22138 dpyinfo->mouse_face_past_end
22139 = !fast_find_position (w, XFASTINT (after),
22140 &dpyinfo->mouse_face_end_col,
22141 &dpyinfo->mouse_face_end_row,
22142 &dpyinfo->mouse_face_end_x,
22143 &dpyinfo->mouse_face_end_y,
22144 Qnil);
22145 dpyinfo->mouse_face_window = window;
22146 dpyinfo->mouse_face_face_id
22147 = face_at_buffer_position (w, pos, 0, 0,
22148 &ignore, pos + 1,
22149 !dpyinfo->mouse_face_hidden);
22150
22151 /* Display it as active. */
22152 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22153 cursor = No_Cursor;
22154 }
22155 }
22156 }
22157
22158 check_help_echo:
22159
22160 /* Look for a `help-echo' property. */
22161 if (NILP (help_echo_string)) {
22162 Lisp_Object help, overlay;
22163
22164 /* Check overlays first. */
22165 help = overlay = Qnil;
22166 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
22167 {
22168 overlay = overlay_vec[i];
22169 help = Foverlay_get (overlay, Qhelp_echo);
22170 }
22171
22172 if (!NILP (help))
22173 {
22174 help_echo_string = help;
22175 help_echo_window = window;
22176 help_echo_object = overlay;
22177 help_echo_pos = pos;
22178 }
22179 else
22180 {
22181 Lisp_Object object = glyph->object;
22182 int charpos = glyph->charpos;
22183
22184 /* Try text properties. */
22185 if (STRINGP (object)
22186 && charpos >= 0
22187 && charpos < SCHARS (object))
22188 {
22189 help = Fget_text_property (make_number (charpos),
22190 Qhelp_echo, object);
22191 if (NILP (help))
22192 {
22193 /* If the string itself doesn't specify a help-echo,
22194 see if the buffer text ``under'' it does. */
22195 struct glyph_row *r
22196 = MATRIX_ROW (w->current_matrix, vpos);
22197 int start = MATRIX_ROW_START_CHARPOS (r);
22198 int pos = string_buffer_position (w, object, start);
22199 if (pos > 0)
22200 {
22201 help = Fget_char_property (make_number (pos),
22202 Qhelp_echo, w->buffer);
22203 if (!NILP (help))
22204 {
22205 charpos = pos;
22206 object = w->buffer;
22207 }
22208 }
22209 }
22210 }
22211 else if (BUFFERP (object)
22212 && charpos >= BEGV
22213 && charpos < ZV)
22214 help = Fget_text_property (make_number (charpos), Qhelp_echo,
22215 object);
22216
22217 if (!NILP (help))
22218 {
22219 help_echo_string = help;
22220 help_echo_window = window;
22221 help_echo_object = object;
22222 help_echo_pos = charpos;
22223 }
22224 }
22225 }
22226
22227 /* Look for a `pointer' property. */
22228 if (NILP (pointer))
22229 {
22230 /* Check overlays first. */
22231 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
22232 pointer = Foverlay_get (overlay_vec[i], Qpointer);
22233
22234 if (NILP (pointer))
22235 {
22236 Lisp_Object object = glyph->object;
22237 int charpos = glyph->charpos;
22238
22239 /* Try text properties. */
22240 if (STRINGP (object)
22241 && charpos >= 0
22242 && charpos < SCHARS (object))
22243 {
22244 pointer = Fget_text_property (make_number (charpos),
22245 Qpointer, object);
22246 if (NILP (pointer))
22247 {
22248 /* If the string itself doesn't specify a pointer,
22249 see if the buffer text ``under'' it does. */
22250 struct glyph_row *r
22251 = MATRIX_ROW (w->current_matrix, vpos);
22252 int start = MATRIX_ROW_START_CHARPOS (r);
22253 int pos = string_buffer_position (w, object, start);
22254 if (pos > 0)
22255 pointer = Fget_char_property (make_number (pos),
22256 Qpointer, w->buffer);
22257 }
22258 }
22259 else if (BUFFERP (object)
22260 && charpos >= BEGV
22261 && charpos < ZV)
22262 pointer = Fget_text_property (make_number (charpos),
22263 Qpointer, object);
22264 }
22265 }
22266
22267 BEGV = obegv;
22268 ZV = ozv;
22269 current_buffer = obuf;
22270 }
22271
22272 set_cursor:
22273
22274 define_frame_cursor1 (f, cursor, pointer);
22275 }
22276
22277
22278 /* EXPORT for RIF:
22279 Clear any mouse-face on window W. This function is part of the
22280 redisplay interface, and is called from try_window_id and similar
22281 functions to ensure the mouse-highlight is off. */
22282
22283 void
22284 x_clear_window_mouse_face (w)
22285 struct window *w;
22286 {
22287 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22288 Lisp_Object window;
22289
22290 BLOCK_INPUT;
22291 XSETWINDOW (window, w);
22292 if (EQ (window, dpyinfo->mouse_face_window))
22293 clear_mouse_face (dpyinfo);
22294 UNBLOCK_INPUT;
22295 }
22296
22297
22298 /* EXPORT:
22299 Just discard the mouse face information for frame F, if any.
22300 This is used when the size of F is changed. */
22301
22302 void
22303 cancel_mouse_face (f)
22304 struct frame *f;
22305 {
22306 Lisp_Object window;
22307 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22308
22309 window = dpyinfo->mouse_face_window;
22310 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
22311 {
22312 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22313 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22314 dpyinfo->mouse_face_window = Qnil;
22315 }
22316 }
22317
22318
22319 #endif /* HAVE_WINDOW_SYSTEM */
22320
22321 \f
22322 /***********************************************************************
22323 Exposure Events
22324 ***********************************************************************/
22325
22326 #ifdef HAVE_WINDOW_SYSTEM
22327
22328 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
22329 which intersects rectangle R. R is in window-relative coordinates. */
22330
22331 static void
22332 expose_area (w, row, r, area)
22333 struct window *w;
22334 struct glyph_row *row;
22335 XRectangle *r;
22336 enum glyph_row_area area;
22337 {
22338 struct glyph *first = row->glyphs[area];
22339 struct glyph *end = row->glyphs[area] + row->used[area];
22340 struct glyph *last;
22341 int first_x, start_x, x;
22342
22343 if (area == TEXT_AREA && row->fill_line_p)
22344 /* If row extends face to end of line write the whole line. */
22345 draw_glyphs (w, 0, row, area,
22346 0, row->used[area],
22347 DRAW_NORMAL_TEXT, 0);
22348 else
22349 {
22350 /* Set START_X to the window-relative start position for drawing glyphs of
22351 AREA. The first glyph of the text area can be partially visible.
22352 The first glyphs of other areas cannot. */
22353 start_x = window_box_left_offset (w, area);
22354 x = start_x;
22355 if (area == TEXT_AREA)
22356 x += row->x;
22357
22358 /* Find the first glyph that must be redrawn. */
22359 while (first < end
22360 && x + first->pixel_width < r->x)
22361 {
22362 x += first->pixel_width;
22363 ++first;
22364 }
22365
22366 /* Find the last one. */
22367 last = first;
22368 first_x = x;
22369 while (last < end
22370 && x < r->x + r->width)
22371 {
22372 x += last->pixel_width;
22373 ++last;
22374 }
22375
22376 /* Repaint. */
22377 if (last > first)
22378 draw_glyphs (w, first_x - start_x, row, area,
22379 first - row->glyphs[area], last - row->glyphs[area],
22380 DRAW_NORMAL_TEXT, 0);
22381 }
22382 }
22383
22384
22385 /* Redraw the parts of the glyph row ROW on window W intersecting
22386 rectangle R. R is in window-relative coordinates. Value is
22387 non-zero if mouse-face was overwritten. */
22388
22389 static int
22390 expose_line (w, row, r)
22391 struct window *w;
22392 struct glyph_row *row;
22393 XRectangle *r;
22394 {
22395 xassert (row->enabled_p);
22396
22397 if (row->mode_line_p || w->pseudo_window_p)
22398 draw_glyphs (w, 0, row, TEXT_AREA,
22399 0, row->used[TEXT_AREA],
22400 DRAW_NORMAL_TEXT, 0);
22401 else
22402 {
22403 if (row->used[LEFT_MARGIN_AREA])
22404 expose_area (w, row, r, LEFT_MARGIN_AREA);
22405 if (row->used[TEXT_AREA])
22406 expose_area (w, row, r, TEXT_AREA);
22407 if (row->used[RIGHT_MARGIN_AREA])
22408 expose_area (w, row, r, RIGHT_MARGIN_AREA);
22409 draw_row_fringe_bitmaps (w, row);
22410 }
22411
22412 return row->mouse_face_p;
22413 }
22414
22415
22416 /* Redraw those parts of glyphs rows during expose event handling that
22417 overlap other rows. Redrawing of an exposed line writes over parts
22418 of lines overlapping that exposed line; this function fixes that.
22419
22420 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
22421 row in W's current matrix that is exposed and overlaps other rows.
22422 LAST_OVERLAPPING_ROW is the last such row. */
22423
22424 static void
22425 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
22426 struct window *w;
22427 struct glyph_row *first_overlapping_row;
22428 struct glyph_row *last_overlapping_row;
22429 {
22430 struct glyph_row *row;
22431
22432 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
22433 if (row->overlapping_p)
22434 {
22435 xassert (row->enabled_p && !row->mode_line_p);
22436
22437 if (row->used[LEFT_MARGIN_AREA])
22438 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
22439
22440 if (row->used[TEXT_AREA])
22441 x_fix_overlapping_area (w, row, TEXT_AREA);
22442
22443 if (row->used[RIGHT_MARGIN_AREA])
22444 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
22445 }
22446 }
22447
22448
22449 /* Return non-zero if W's cursor intersects rectangle R. */
22450
22451 static int
22452 phys_cursor_in_rect_p (w, r)
22453 struct window *w;
22454 XRectangle *r;
22455 {
22456 XRectangle cr, result;
22457 struct glyph *cursor_glyph;
22458
22459 cursor_glyph = get_phys_cursor_glyph (w);
22460 if (cursor_glyph)
22461 {
22462 /* r is relative to W's box, but w->phys_cursor.x is relative
22463 to left edge of W's TEXT area. Adjust it. */
22464 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
22465 cr.y = w->phys_cursor.y;
22466 cr.width = cursor_glyph->pixel_width;
22467 cr.height = w->phys_cursor_height;
22468 /* ++KFS: W32 version used W32-specific IntersectRect here, but
22469 I assume the effect is the same -- and this is portable. */
22470 return x_intersect_rectangles (&cr, r, &result);
22471 }
22472 /* If we don't understand the format, pretend we're not in the hot-spot. */
22473 return 0;
22474 }
22475
22476
22477 /* EXPORT:
22478 Draw a vertical window border to the right of window W if W doesn't
22479 have vertical scroll bars. */
22480
22481 void
22482 x_draw_vertical_border (w)
22483 struct window *w;
22484 {
22485 struct frame *f = XFRAME (WINDOW_FRAME (w));
22486
22487 /* We could do better, if we knew what type of scroll-bar the adjacent
22488 windows (on either side) have... But we don't :-(
22489 However, I think this works ok. ++KFS 2003-04-25 */
22490
22491 /* Redraw borders between horizontally adjacent windows. Don't
22492 do it for frames with vertical scroll bars because either the
22493 right scroll bar of a window, or the left scroll bar of its
22494 neighbor will suffice as a border. */
22495 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
22496 return;
22497
22498 if (!WINDOW_RIGHTMOST_P (w)
22499 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
22500 {
22501 int x0, x1, y0, y1;
22502
22503 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22504 y1 -= 1;
22505
22506 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
22507 x1 -= 1;
22508
22509 FRAME_RIF (f)->draw_vertical_window_border (w, x1, y0, y1);
22510 }
22511 else if (!WINDOW_LEFTMOST_P (w)
22512 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
22513 {
22514 int x0, x1, y0, y1;
22515
22516 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22517 y1 -= 1;
22518
22519 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
22520 x0 -= 1;
22521
22522 FRAME_RIF (f)->draw_vertical_window_border (w, x0, y0, y1);
22523 }
22524 }
22525
22526
22527 /* Redraw the part of window W intersection rectangle FR. Pixel
22528 coordinates in FR are frame-relative. Call this function with
22529 input blocked. Value is non-zero if the exposure overwrites
22530 mouse-face. */
22531
22532 static int
22533 expose_window (w, fr)
22534 struct window *w;
22535 XRectangle *fr;
22536 {
22537 struct frame *f = XFRAME (w->frame);
22538 XRectangle wr, r;
22539 int mouse_face_overwritten_p = 0;
22540
22541 /* If window is not yet fully initialized, do nothing. This can
22542 happen when toolkit scroll bars are used and a window is split.
22543 Reconfiguring the scroll bar will generate an expose for a newly
22544 created window. */
22545 if (w->current_matrix == NULL)
22546 return 0;
22547
22548 /* When we're currently updating the window, display and current
22549 matrix usually don't agree. Arrange for a thorough display
22550 later. */
22551 if (w == updated_window)
22552 {
22553 SET_FRAME_GARBAGED (f);
22554 return 0;
22555 }
22556
22557 /* Frame-relative pixel rectangle of W. */
22558 wr.x = WINDOW_LEFT_EDGE_X (w);
22559 wr.y = WINDOW_TOP_EDGE_Y (w);
22560 wr.width = WINDOW_TOTAL_WIDTH (w);
22561 wr.height = WINDOW_TOTAL_HEIGHT (w);
22562
22563 if (x_intersect_rectangles (fr, &wr, &r))
22564 {
22565 int yb = window_text_bottom_y (w);
22566 struct glyph_row *row;
22567 int cursor_cleared_p;
22568 struct glyph_row *first_overlapping_row, *last_overlapping_row;
22569
22570 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
22571 r.x, r.y, r.width, r.height));
22572
22573 /* Convert to window coordinates. */
22574 r.x -= WINDOW_LEFT_EDGE_X (w);
22575 r.y -= WINDOW_TOP_EDGE_Y (w);
22576
22577 /* Turn off the cursor. */
22578 if (!w->pseudo_window_p
22579 && phys_cursor_in_rect_p (w, &r))
22580 {
22581 x_clear_cursor (w);
22582 cursor_cleared_p = 1;
22583 }
22584 else
22585 cursor_cleared_p = 0;
22586
22587 /* Update lines intersecting rectangle R. */
22588 first_overlapping_row = last_overlapping_row = NULL;
22589 for (row = w->current_matrix->rows;
22590 row->enabled_p;
22591 ++row)
22592 {
22593 int y0 = row->y;
22594 int y1 = MATRIX_ROW_BOTTOM_Y (row);
22595
22596 if ((y0 >= r.y && y0 < r.y + r.height)
22597 || (y1 > r.y && y1 < r.y + r.height)
22598 || (r.y >= y0 && r.y < y1)
22599 || (r.y + r.height > y0 && r.y + r.height < y1))
22600 {
22601 /* A header line may be overlapping, but there is no need
22602 to fix overlapping areas for them. KFS 2005-02-12 */
22603 if (row->overlapping_p && !row->mode_line_p)
22604 {
22605 if (first_overlapping_row == NULL)
22606 first_overlapping_row = row;
22607 last_overlapping_row = row;
22608 }
22609
22610 if (expose_line (w, row, &r))
22611 mouse_face_overwritten_p = 1;
22612 }
22613
22614 if (y1 >= yb)
22615 break;
22616 }
22617
22618 /* Display the mode line if there is one. */
22619 if (WINDOW_WANTS_MODELINE_P (w)
22620 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
22621 row->enabled_p)
22622 && row->y < r.y + r.height)
22623 {
22624 if (expose_line (w, row, &r))
22625 mouse_face_overwritten_p = 1;
22626 }
22627
22628 if (!w->pseudo_window_p)
22629 {
22630 /* Fix the display of overlapping rows. */
22631 if (first_overlapping_row)
22632 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
22633
22634 /* Draw border between windows. */
22635 x_draw_vertical_border (w);
22636
22637 /* Turn the cursor on again. */
22638 if (cursor_cleared_p)
22639 update_window_cursor (w, 1);
22640 }
22641 }
22642
22643 return mouse_face_overwritten_p;
22644 }
22645
22646
22647
22648 /* Redraw (parts) of all windows in the window tree rooted at W that
22649 intersect R. R contains frame pixel coordinates. Value is
22650 non-zero if the exposure overwrites mouse-face. */
22651
22652 static int
22653 expose_window_tree (w, r)
22654 struct window *w;
22655 XRectangle *r;
22656 {
22657 struct frame *f = XFRAME (w->frame);
22658 int mouse_face_overwritten_p = 0;
22659
22660 while (w && !FRAME_GARBAGED_P (f))
22661 {
22662 if (!NILP (w->hchild))
22663 mouse_face_overwritten_p
22664 |= expose_window_tree (XWINDOW (w->hchild), r);
22665 else if (!NILP (w->vchild))
22666 mouse_face_overwritten_p
22667 |= expose_window_tree (XWINDOW (w->vchild), r);
22668 else
22669 mouse_face_overwritten_p |= expose_window (w, r);
22670
22671 w = NILP (w->next) ? NULL : XWINDOW (w->next);
22672 }
22673
22674 return mouse_face_overwritten_p;
22675 }
22676
22677
22678 /* EXPORT:
22679 Redisplay an exposed area of frame F. X and Y are the upper-left
22680 corner of the exposed rectangle. W and H are width and height of
22681 the exposed area. All are pixel values. W or H zero means redraw
22682 the entire frame. */
22683
22684 void
22685 expose_frame (f, x, y, w, h)
22686 struct frame *f;
22687 int x, y, w, h;
22688 {
22689 XRectangle r;
22690 int mouse_face_overwritten_p = 0;
22691
22692 TRACE ((stderr, "expose_frame "));
22693
22694 /* No need to redraw if frame will be redrawn soon. */
22695 if (FRAME_GARBAGED_P (f))
22696 {
22697 TRACE ((stderr, " garbaged\n"));
22698 return;
22699 }
22700
22701 /* If basic faces haven't been realized yet, there is no point in
22702 trying to redraw anything. This can happen when we get an expose
22703 event while Emacs is starting, e.g. by moving another window. */
22704 if (FRAME_FACE_CACHE (f) == NULL
22705 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
22706 {
22707 TRACE ((stderr, " no faces\n"));
22708 return;
22709 }
22710
22711 if (w == 0 || h == 0)
22712 {
22713 r.x = r.y = 0;
22714 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
22715 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
22716 }
22717 else
22718 {
22719 r.x = x;
22720 r.y = y;
22721 r.width = w;
22722 r.height = h;
22723 }
22724
22725 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
22726 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
22727
22728 if (WINDOWP (f->tool_bar_window))
22729 mouse_face_overwritten_p
22730 |= expose_window (XWINDOW (f->tool_bar_window), &r);
22731
22732 #ifdef HAVE_X_WINDOWS
22733 #ifndef MSDOS
22734 #ifndef USE_X_TOOLKIT
22735 if (WINDOWP (f->menu_bar_window))
22736 mouse_face_overwritten_p
22737 |= expose_window (XWINDOW (f->menu_bar_window), &r);
22738 #endif /* not USE_X_TOOLKIT */
22739 #endif
22740 #endif
22741
22742 /* Some window managers support a focus-follows-mouse style with
22743 delayed raising of frames. Imagine a partially obscured frame,
22744 and moving the mouse into partially obscured mouse-face on that
22745 frame. The visible part of the mouse-face will be highlighted,
22746 then the WM raises the obscured frame. With at least one WM, KDE
22747 2.1, Emacs is not getting any event for the raising of the frame
22748 (even tried with SubstructureRedirectMask), only Expose events.
22749 These expose events will draw text normally, i.e. not
22750 highlighted. Which means we must redo the highlight here.
22751 Subsume it under ``we love X''. --gerd 2001-08-15 */
22752 /* Included in Windows version because Windows most likely does not
22753 do the right thing if any third party tool offers
22754 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22755 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22756 {
22757 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22758 if (f == dpyinfo->mouse_face_mouse_frame)
22759 {
22760 int x = dpyinfo->mouse_face_mouse_x;
22761 int y = dpyinfo->mouse_face_mouse_y;
22762 clear_mouse_face (dpyinfo);
22763 note_mouse_highlight (f, x, y);
22764 }
22765 }
22766 }
22767
22768
22769 /* EXPORT:
22770 Determine the intersection of two rectangles R1 and R2. Return
22771 the intersection in *RESULT. Value is non-zero if RESULT is not
22772 empty. */
22773
22774 int
22775 x_intersect_rectangles (r1, r2, result)
22776 XRectangle *r1, *r2, *result;
22777 {
22778 XRectangle *left, *right;
22779 XRectangle *upper, *lower;
22780 int intersection_p = 0;
22781
22782 /* Rearrange so that R1 is the left-most rectangle. */
22783 if (r1->x < r2->x)
22784 left = r1, right = r2;
22785 else
22786 left = r2, right = r1;
22787
22788 /* X0 of the intersection is right.x0, if this is inside R1,
22789 otherwise there is no intersection. */
22790 if (right->x <= left->x + left->width)
22791 {
22792 result->x = right->x;
22793
22794 /* The right end of the intersection is the minimum of the
22795 the right ends of left and right. */
22796 result->width = (min (left->x + left->width, right->x + right->width)
22797 - result->x);
22798
22799 /* Same game for Y. */
22800 if (r1->y < r2->y)
22801 upper = r1, lower = r2;
22802 else
22803 upper = r2, lower = r1;
22804
22805 /* The upper end of the intersection is lower.y0, if this is inside
22806 of upper. Otherwise, there is no intersection. */
22807 if (lower->y <= upper->y + upper->height)
22808 {
22809 result->y = lower->y;
22810
22811 /* The lower end of the intersection is the minimum of the lower
22812 ends of upper and lower. */
22813 result->height = (min (lower->y + lower->height,
22814 upper->y + upper->height)
22815 - result->y);
22816 intersection_p = 1;
22817 }
22818 }
22819
22820 return intersection_p;
22821 }
22822
22823 #endif /* HAVE_WINDOW_SYSTEM */
22824
22825 \f
22826 /***********************************************************************
22827 Initialization
22828 ***********************************************************************/
22829
22830 void
22831 syms_of_xdisp ()
22832 {
22833 Vwith_echo_area_save_vector = Qnil;
22834 staticpro (&Vwith_echo_area_save_vector);
22835
22836 Vmessage_stack = Qnil;
22837 staticpro (&Vmessage_stack);
22838
22839 Qinhibit_redisplay = intern ("inhibit-redisplay");
22840 staticpro (&Qinhibit_redisplay);
22841
22842 message_dolog_marker1 = Fmake_marker ();
22843 staticpro (&message_dolog_marker1);
22844 message_dolog_marker2 = Fmake_marker ();
22845 staticpro (&message_dolog_marker2);
22846 message_dolog_marker3 = Fmake_marker ();
22847 staticpro (&message_dolog_marker3);
22848
22849 #if GLYPH_DEBUG
22850 defsubr (&Sdump_frame_glyph_matrix);
22851 defsubr (&Sdump_glyph_matrix);
22852 defsubr (&Sdump_glyph_row);
22853 defsubr (&Sdump_tool_bar_row);
22854 defsubr (&Strace_redisplay);
22855 defsubr (&Strace_to_stderr);
22856 #endif
22857 #ifdef HAVE_WINDOW_SYSTEM
22858 defsubr (&Stool_bar_lines_needed);
22859 defsubr (&Slookup_image_map);
22860 #endif
22861 defsubr (&Sformat_mode_line);
22862
22863 staticpro (&Qmenu_bar_update_hook);
22864 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22865
22866 staticpro (&Qoverriding_terminal_local_map);
22867 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22868
22869 staticpro (&Qoverriding_local_map);
22870 Qoverriding_local_map = intern ("overriding-local-map");
22871
22872 staticpro (&Qwindow_scroll_functions);
22873 Qwindow_scroll_functions = intern ("window-scroll-functions");
22874
22875 staticpro (&Qredisplay_end_trigger_functions);
22876 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22877
22878 staticpro (&Qinhibit_point_motion_hooks);
22879 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22880
22881 QCdata = intern (":data");
22882 staticpro (&QCdata);
22883 Qdisplay = intern ("display");
22884 staticpro (&Qdisplay);
22885 Qspace_width = intern ("space-width");
22886 staticpro (&Qspace_width);
22887 Qraise = intern ("raise");
22888 staticpro (&Qraise);
22889 Qslice = intern ("slice");
22890 staticpro (&Qslice);
22891 Qspace = intern ("space");
22892 staticpro (&Qspace);
22893 Qmargin = intern ("margin");
22894 staticpro (&Qmargin);
22895 Qpointer = intern ("pointer");
22896 staticpro (&Qpointer);
22897 Qleft_margin = intern ("left-margin");
22898 staticpro (&Qleft_margin);
22899 Qright_margin = intern ("right-margin");
22900 staticpro (&Qright_margin);
22901 Qcenter = intern ("center");
22902 staticpro (&Qcenter);
22903 Qline_height = intern ("line-height");
22904 staticpro (&Qline_height);
22905 QCalign_to = intern (":align-to");
22906 staticpro (&QCalign_to);
22907 QCrelative_width = intern (":relative-width");
22908 staticpro (&QCrelative_width);
22909 QCrelative_height = intern (":relative-height");
22910 staticpro (&QCrelative_height);
22911 QCeval = intern (":eval");
22912 staticpro (&QCeval);
22913 QCpropertize = intern (":propertize");
22914 staticpro (&QCpropertize);
22915 QCfile = intern (":file");
22916 staticpro (&QCfile);
22917 Qfontified = intern ("fontified");
22918 staticpro (&Qfontified);
22919 Qfontification_functions = intern ("fontification-functions");
22920 staticpro (&Qfontification_functions);
22921 Qtrailing_whitespace = intern ("trailing-whitespace");
22922 staticpro (&Qtrailing_whitespace);
22923 Qescape_glyph = intern ("escape-glyph");
22924 staticpro (&Qescape_glyph);
22925 Qnobreak_space = intern ("nobreak-space");
22926 staticpro (&Qnobreak_space);
22927 Qimage = intern ("image");
22928 staticpro (&Qimage);
22929 QCmap = intern (":map");
22930 staticpro (&QCmap);
22931 QCpointer = intern (":pointer");
22932 staticpro (&QCpointer);
22933 Qrect = intern ("rect");
22934 staticpro (&Qrect);
22935 Qcircle = intern ("circle");
22936 staticpro (&Qcircle);
22937 Qpoly = intern ("poly");
22938 staticpro (&Qpoly);
22939 Qmessage_truncate_lines = intern ("message-truncate-lines");
22940 staticpro (&Qmessage_truncate_lines);
22941 Qgrow_only = intern ("grow-only");
22942 staticpro (&Qgrow_only);
22943 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22944 staticpro (&Qinhibit_menubar_update);
22945 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22946 staticpro (&Qinhibit_eval_during_redisplay);
22947 Qposition = intern ("position");
22948 staticpro (&Qposition);
22949 Qbuffer_position = intern ("buffer-position");
22950 staticpro (&Qbuffer_position);
22951 Qobject = intern ("object");
22952 staticpro (&Qobject);
22953 Qbar = intern ("bar");
22954 staticpro (&Qbar);
22955 Qhbar = intern ("hbar");
22956 staticpro (&Qhbar);
22957 Qbox = intern ("box");
22958 staticpro (&Qbox);
22959 Qhollow = intern ("hollow");
22960 staticpro (&Qhollow);
22961 Qhand = intern ("hand");
22962 staticpro (&Qhand);
22963 Qarrow = intern ("arrow");
22964 staticpro (&Qarrow);
22965 Qtext = intern ("text");
22966 staticpro (&Qtext);
22967 Qrisky_local_variable = intern ("risky-local-variable");
22968 staticpro (&Qrisky_local_variable);
22969 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22970 staticpro (&Qinhibit_free_realized_faces);
22971
22972 list_of_error = Fcons (Fcons (intern ("error"),
22973 Fcons (intern ("void-variable"), Qnil)),
22974 Qnil);
22975 staticpro (&list_of_error);
22976
22977 Qlast_arrow_position = intern ("last-arrow-position");
22978 staticpro (&Qlast_arrow_position);
22979 Qlast_arrow_string = intern ("last-arrow-string");
22980 staticpro (&Qlast_arrow_string);
22981
22982 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22983 staticpro (&Qoverlay_arrow_string);
22984 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22985 staticpro (&Qoverlay_arrow_bitmap);
22986
22987 echo_buffer[0] = echo_buffer[1] = Qnil;
22988 staticpro (&echo_buffer[0]);
22989 staticpro (&echo_buffer[1]);
22990
22991 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22992 staticpro (&echo_area_buffer[0]);
22993 staticpro (&echo_area_buffer[1]);
22994
22995 Vmessages_buffer_name = build_string ("*Messages*");
22996 staticpro (&Vmessages_buffer_name);
22997
22998 mode_line_proptrans_alist = Qnil;
22999 staticpro (&mode_line_proptrans_alist);
23000 mode_line_string_list = Qnil;
23001 staticpro (&mode_line_string_list);
23002 mode_line_string_face = Qnil;
23003 staticpro (&mode_line_string_face);
23004 mode_line_string_face_prop = Qnil;
23005 staticpro (&mode_line_string_face_prop);
23006 Vmode_line_unwind_vector = Qnil;
23007 staticpro (&Vmode_line_unwind_vector);
23008
23009 help_echo_string = Qnil;
23010 staticpro (&help_echo_string);
23011 help_echo_object = Qnil;
23012 staticpro (&help_echo_object);
23013 help_echo_window = Qnil;
23014 staticpro (&help_echo_window);
23015 previous_help_echo_string = Qnil;
23016 staticpro (&previous_help_echo_string);
23017 help_echo_pos = -1;
23018
23019 #ifdef HAVE_WINDOW_SYSTEM
23020 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
23021 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
23022 For example, if a block cursor is over a tab, it will be drawn as
23023 wide as that tab on the display. */);
23024 x_stretch_cursor_p = 0;
23025 #endif
23026
23027 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
23028 doc: /* *Non-nil means highlight trailing whitespace.
23029 The face used for trailing whitespace is `trailing-whitespace'. */);
23030 Vshow_trailing_whitespace = Qnil;
23031
23032 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
23033 doc: /* *Control highlighting of nobreak space and soft hyphen.
23034 A value of t means highlight the character itself (for nobreak space,
23035 use face `nobreak-space').
23036 A value of nil means no highlighting.
23037 Other values mean display the escape glyph followed by an ordinary
23038 space or ordinary hyphen. */);
23039 Vnobreak_char_display = Qt;
23040
23041 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
23042 doc: /* *The pointer shape to show in void text areas.
23043 A value of nil means to show the text pointer. Other options are `arrow',
23044 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
23045 Vvoid_text_area_pointer = Qarrow;
23046
23047 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
23048 doc: /* Non-nil means don't actually do any redisplay.
23049 This is used for internal purposes. */);
23050 Vinhibit_redisplay = Qnil;
23051
23052 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
23053 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
23054 Vglobal_mode_string = Qnil;
23055
23056 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
23057 doc: /* Marker for where to display an arrow on top of the buffer text.
23058 This must be the beginning of a line in order to work.
23059 See also `overlay-arrow-string'. */);
23060 Voverlay_arrow_position = Qnil;
23061
23062 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
23063 doc: /* String to display as an arrow in non-window frames.
23064 See also `overlay-arrow-position'. */);
23065 Voverlay_arrow_string = build_string ("=>");
23066
23067 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
23068 doc: /* List of variables (symbols) which hold markers for overlay arrows.
23069 The symbols on this list are examined during redisplay to determine
23070 where to display overlay arrows. */);
23071 Voverlay_arrow_variable_list
23072 = Fcons (intern ("overlay-arrow-position"), Qnil);
23073
23074 DEFVAR_INT ("scroll-step", &scroll_step,
23075 doc: /* *The number of lines to try scrolling a window by when point moves out.
23076 If that fails to bring point back on frame, point is centered instead.
23077 If this is zero, point is always centered after it moves off frame.
23078 If you want scrolling to always be a line at a time, you should set
23079 `scroll-conservatively' to a large value rather than set this to 1. */);
23080
23081 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
23082 doc: /* *Scroll up to this many lines, to bring point back on screen.
23083 A value of zero means to scroll the text to center point vertically
23084 in the window. */);
23085 scroll_conservatively = 0;
23086
23087 DEFVAR_INT ("scroll-margin", &scroll_margin,
23088 doc: /* *Number of lines of margin at the top and bottom of a window.
23089 Recenter the window whenever point gets within this many lines
23090 of the top or bottom of the window. */);
23091 scroll_margin = 0;
23092
23093 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
23094 doc: /* Pixels per inch value for non-window system displays.
23095 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
23096 Vdisplay_pixels_per_inch = make_float (72.0);
23097
23098 #if GLYPH_DEBUG
23099 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
23100 #endif
23101
23102 DEFVAR_BOOL ("truncate-partial-width-windows",
23103 &truncate_partial_width_windows,
23104 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
23105 truncate_partial_width_windows = 1;
23106
23107 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
23108 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
23109 Any other value means to use the appropriate face, `mode-line',
23110 `header-line', or `menu' respectively. */);
23111 mode_line_inverse_video = 1;
23112
23113 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
23114 doc: /* *Maximum buffer size for which line number should be displayed.
23115 If the buffer is bigger than this, the line number does not appear
23116 in the mode line. A value of nil means no limit. */);
23117 Vline_number_display_limit = Qnil;
23118
23119 DEFVAR_INT ("line-number-display-limit-width",
23120 &line_number_display_limit_width,
23121 doc: /* *Maximum line width (in characters) for line number display.
23122 If the average length of the lines near point is bigger than this, then the
23123 line number may be omitted from the mode line. */);
23124 line_number_display_limit_width = 200;
23125
23126 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
23127 doc: /* *Non-nil means highlight region even in nonselected windows. */);
23128 highlight_nonselected_windows = 0;
23129
23130 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
23131 doc: /* Non-nil if more than one frame is visible on this display.
23132 Minibuffer-only frames don't count, but iconified frames do.
23133 This variable is not guaranteed to be accurate except while processing
23134 `frame-title-format' and `icon-title-format'. */);
23135
23136 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
23137 doc: /* Template for displaying the title bar of visible frames.
23138 \(Assuming the window manager supports this feature.)
23139 This variable has the same structure as `mode-line-format' (which see),
23140 and is used only on frames for which no explicit name has been set
23141 \(see `modify-frame-parameters'). */);
23142
23143 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
23144 doc: /* Template for displaying the title bar of an iconified frame.
23145 \(Assuming the window manager supports this feature.)
23146 This variable has the same structure as `mode-line-format' (which see),
23147 and is used only on frames for which no explicit name has been set
23148 \(see `modify-frame-parameters'). */);
23149 Vicon_title_format
23150 = Vframe_title_format
23151 = Fcons (intern ("multiple-frames"),
23152 Fcons (build_string ("%b"),
23153 Fcons (Fcons (empty_string,
23154 Fcons (intern ("invocation-name"),
23155 Fcons (build_string ("@"),
23156 Fcons (intern ("system-name"),
23157 Qnil)))),
23158 Qnil)));
23159
23160 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
23161 doc: /* Maximum number of lines to keep in the message log buffer.
23162 If nil, disable message logging. If t, log messages but don't truncate
23163 the buffer when it becomes large. */);
23164 Vmessage_log_max = make_number (50);
23165
23166 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
23167 doc: /* Functions called before redisplay, if window sizes have changed.
23168 The value should be a list of functions that take one argument.
23169 Just before redisplay, for each frame, if any of its windows have changed
23170 size since the last redisplay, or have been split or deleted,
23171 all the functions in the list are called, with the frame as argument. */);
23172 Vwindow_size_change_functions = Qnil;
23173
23174 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
23175 doc: /* List of functions to call before redisplaying a window with scrolling.
23176 Each function is called with two arguments, the window
23177 and its new display-start position. Note that the value of `window-end'
23178 is not valid when these functions are called. */);
23179 Vwindow_scroll_functions = Qnil;
23180
23181 DEFVAR_LISP ("redisplay-end-trigger-functions", &Vredisplay_end_trigger_functions,
23182 doc: /* Functions called when redisplay of a window reaches the end trigger.
23183 Each function is called with two arguments, the window and the end trigger value.
23184 See `set-window-redisplay-end-trigger'. */);
23185 Vredisplay_end_trigger_functions = Qnil;
23186
23187 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
23188 doc: /* *Non-nil means autoselect window with mouse pointer. */);
23189 mouse_autoselect_window = 0;
23190
23191 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
23192 doc: /* *Non-nil means automatically resize tool-bars.
23193 This increases a tool-bar's height if not all tool-bar items are visible.
23194 It decreases a tool-bar's height when it would display blank lines
23195 otherwise. */);
23196 auto_resize_tool_bars_p = 1;
23197
23198 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
23199 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
23200 auto_raise_tool_bar_buttons_p = 1;
23201
23202 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
23203 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
23204 make_cursor_line_fully_visible_p = 1;
23205
23206 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
23207 doc: /* *Margin around tool-bar buttons in pixels.
23208 If an integer, use that for both horizontal and vertical margins.
23209 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
23210 HORZ specifying the horizontal margin, and VERT specifying the
23211 vertical margin. */);
23212 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
23213
23214 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
23215 doc: /* *Relief thickness of tool-bar buttons. */);
23216 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
23217
23218 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
23219 doc: /* List of functions to call to fontify regions of text.
23220 Each function is called with one argument POS. Functions must
23221 fontify a region starting at POS in the current buffer, and give
23222 fontified regions the property `fontified'. */);
23223 Vfontification_functions = Qnil;
23224 Fmake_variable_buffer_local (Qfontification_functions);
23225
23226 DEFVAR_BOOL ("unibyte-display-via-language-environment",
23227 &unibyte_display_via_language_environment,
23228 doc: /* *Non-nil means display unibyte text according to language environment.
23229 Specifically this means that unibyte non-ASCII characters
23230 are displayed by converting them to the equivalent multibyte characters
23231 according to the current language environment. As a result, they are
23232 displayed according to the current fontset. */);
23233 unibyte_display_via_language_environment = 0;
23234
23235 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
23236 doc: /* *Maximum height for resizing mini-windows.
23237 If a float, it specifies a fraction of the mini-window frame's height.
23238 If an integer, it specifies a number of lines. */);
23239 Vmax_mini_window_height = make_float (0.25);
23240
23241 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
23242 doc: /* *How to resize mini-windows.
23243 A value of nil means don't automatically resize mini-windows.
23244 A value of t means resize them to fit the text displayed in them.
23245 A value of `grow-only', the default, means let mini-windows grow
23246 only, until their display becomes empty, at which point the windows
23247 go back to their normal size. */);
23248 Vresize_mini_windows = Qgrow_only;
23249
23250 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
23251 doc: /* Alist specifying how to blink the cursor off.
23252 Each element has the form (ON-STATE . OFF-STATE). Whenever the
23253 `cursor-type' frame-parameter or variable equals ON-STATE,
23254 comparing using `equal', Emacs uses OFF-STATE to specify
23255 how to blink it off. */);
23256 Vblink_cursor_alist = Qnil;
23257
23258 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
23259 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
23260 automatic_hscrolling_p = 1;
23261
23262 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
23263 doc: /* *How many columns away from the window edge point is allowed to get
23264 before automatic hscrolling will horizontally scroll the window. */);
23265 hscroll_margin = 5;
23266
23267 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
23268 doc: /* *How many columns to scroll the window when point gets too close to the edge.
23269 When point is less than `automatic-hscroll-margin' columns from the window
23270 edge, automatic hscrolling will scroll the window by the amount of columns
23271 determined by this variable. If its value is a positive integer, scroll that
23272 many columns. If it's a positive floating-point number, it specifies the
23273 fraction of the window's width to scroll. If it's nil or zero, point will be
23274 centered horizontally after the scroll. Any other value, including negative
23275 numbers, are treated as if the value were zero.
23276
23277 Automatic hscrolling always moves point outside the scroll margin, so if
23278 point was more than scroll step columns inside the margin, the window will
23279 scroll more than the value given by the scroll step.
23280
23281 Note that the lower bound for automatic hscrolling specified by `scroll-left'
23282 and `scroll-right' overrides this variable's effect. */);
23283 Vhscroll_step = make_number (0);
23284
23285 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
23286 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
23287 Bind this around calls to `message' to let it take effect. */);
23288 message_truncate_lines = 0;
23289
23290 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
23291 doc: /* Normal hook run to update the menu bar definitions.
23292 Redisplay runs this hook before it redisplays the menu bar.
23293 This is used to update submenus such as Buffers,
23294 whose contents depend on various data. */);
23295 Vmenu_bar_update_hook = Qnil;
23296
23297 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
23298 doc: /* Non-nil means don't update menu bars. Internal use only. */);
23299 inhibit_menubar_update = 0;
23300
23301 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
23302 doc: /* Non-nil means don't eval Lisp during redisplay. */);
23303 inhibit_eval_during_redisplay = 0;
23304
23305 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
23306 doc: /* Non-nil means don't free realized faces. Internal use only. */);
23307 inhibit_free_realized_faces = 0;
23308
23309 #if GLYPH_DEBUG
23310 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
23311 doc: /* Inhibit try_window_id display optimization. */);
23312 inhibit_try_window_id = 0;
23313
23314 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
23315 doc: /* Inhibit try_window_reusing display optimization. */);
23316 inhibit_try_window_reusing = 0;
23317
23318 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
23319 doc: /* Inhibit try_cursor_movement display optimization. */);
23320 inhibit_try_cursor_movement = 0;
23321 #endif /* GLYPH_DEBUG */
23322 }
23323
23324
23325 /* Initialize this module when Emacs starts. */
23326
23327 void
23328 init_xdisp ()
23329 {
23330 Lisp_Object root_window;
23331 struct window *mini_w;
23332
23333 current_header_line_height = current_mode_line_height = -1;
23334
23335 CHARPOS (this_line_start_pos) = 0;
23336
23337 mini_w = XWINDOW (minibuf_window);
23338 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
23339
23340 if (!noninteractive)
23341 {
23342 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
23343 int i;
23344
23345 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
23346 set_window_height (root_window,
23347 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
23348 0);
23349 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
23350 set_window_height (minibuf_window, 1, 0);
23351
23352 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
23353 mini_w->total_cols = make_number (FRAME_COLS (f));
23354
23355 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
23356 scratch_glyph_row.glyphs[TEXT_AREA + 1]
23357 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
23358
23359 /* The default ellipsis glyphs `...'. */
23360 for (i = 0; i < 3; ++i)
23361 default_invis_vector[i] = make_number ('.');
23362 }
23363
23364 {
23365 /* Allocate the buffer for frame titles.
23366 Also used for `format-mode-line'. */
23367 int size = 100;
23368 mode_line_noprop_buf = (char *) xmalloc (size);
23369 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
23370 mode_line_noprop_ptr = mode_line_noprop_buf;
23371 mode_line_target = MODE_LINE_DISPLAY;
23372 }
23373
23374 help_echo_showing_p = 0;
23375 }
23376
23377
23378 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
23379 (do not change this comment) */