]> code.delx.au - gnu-emacs/blob - src/xdisp.c
*** empty log message ***
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
125
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
131
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
138
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
146
147
148 Frame matrices.
149
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
156
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
168
169 #include <config.h>
170 #include <stdio.h>
171
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
192
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201 #endif
202
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
206
207 #define INFINITY 10000000
208
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
214
215 extern int interrupt_input;
216 extern int command_loop_level;
217
218 extern Lisp_Object do_mouse_tracking;
219
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
222
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
225
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
231
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
241
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
244
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
247
248 Lisp_Object Qrisky_local_variable;
249
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
252
253 /* Functions called to fontify regions of text. */
254
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
257
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
261
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
264
265 int auto_raise_tool_bar_buttons_p;
266
267 /* Non-zero means to reposition window if cursor line is only partially visible. */
268
269 int make_cursor_line_fully_visible_p;
270
271 /* Margin around tool bar buttons in pixels. */
272
273 Lisp_Object Vtool_bar_button_margin;
274
275 /* Thickness of shadow to draw around tool bar buttons. */
276
277 EMACS_INT tool_bar_button_relief;
278
279 /* Non-zero means automatically resize tool-bars so that all tool-bar
280 items are visible, and no blank lines remain. */
281
282 int auto_resize_tool_bars_p;
283
284 /* Non-zero means draw block and hollow cursor as wide as the glyph
285 under it. For example, if a block cursor is over a tab, it will be
286 drawn as wide as that tab on the display. */
287
288 int x_stretch_cursor_p;
289
290 /* Non-nil means don't actually do any redisplay. */
291
292 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
293
294 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
295
296 int inhibit_eval_during_redisplay;
297
298 /* Names of text properties relevant for redisplay. */
299
300 Lisp_Object Qdisplay;
301 extern Lisp_Object Qface, Qinvisible, Qwidth;
302
303 /* Symbols used in text property values. */
304
305 Lisp_Object Vdisplay_pixels_per_inch;
306 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
307 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
308 Lisp_Object Qslice;
309 Lisp_Object Qcenter;
310 Lisp_Object Qmargin, Qpointer;
311 Lisp_Object Qline_height;
312 extern Lisp_Object Qheight;
313 extern Lisp_Object QCwidth, QCheight, QCascent;
314 extern Lisp_Object Qscroll_bar;
315 extern Lisp_Object Qcursor;
316
317 /* Non-nil means highlight trailing whitespace. */
318
319 Lisp_Object Vshow_trailing_whitespace;
320
321 /* Non-nil means escape non-break space and hyphens. */
322
323 Lisp_Object Vnobreak_char_display;
324
325 #ifdef HAVE_WINDOW_SYSTEM
326 extern Lisp_Object Voverflow_newline_into_fringe;
327
328 /* Test if overflow newline into fringe. Called with iterator IT
329 at or past right window margin, and with IT->current_x set. */
330
331 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
332 (!NILP (Voverflow_newline_into_fringe) \
333 && FRAME_WINDOW_P (it->f) \
334 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
335 && it->current_x == it->last_visible_x)
336
337 #endif /* HAVE_WINDOW_SYSTEM */
338
339 /* Non-nil means show the text cursor in void text areas
340 i.e. in blank areas after eol and eob. This used to be
341 the default in 21.3. */
342
343 Lisp_Object Vvoid_text_area_pointer;
344
345 /* Name of the face used to highlight trailing whitespace. */
346
347 Lisp_Object Qtrailing_whitespace;
348
349 /* Name and number of the face used to highlight escape glyphs. */
350
351 Lisp_Object Qescape_glyph;
352
353 /* Name and number of the face used to highlight non-breaking spaces. */
354
355 Lisp_Object Qnobreak_space;
356
357 /* The symbol `image' which is the car of the lists used to represent
358 images in Lisp. */
359
360 Lisp_Object Qimage;
361
362 /* The image map types. */
363 Lisp_Object QCmap, QCpointer;
364 Lisp_Object Qrect, Qcircle, Qpoly;
365
366 /* Non-zero means print newline to stdout before next mini-buffer
367 message. */
368
369 int noninteractive_need_newline;
370
371 /* Non-zero means print newline to message log before next message. */
372
373 static int message_log_need_newline;
374
375 /* Three markers that message_dolog uses.
376 It could allocate them itself, but that causes trouble
377 in handling memory-full errors. */
378 static Lisp_Object message_dolog_marker1;
379 static Lisp_Object message_dolog_marker2;
380 static Lisp_Object message_dolog_marker3;
381 \f
382 /* The buffer position of the first character appearing entirely or
383 partially on the line of the selected window which contains the
384 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
385 redisplay optimization in redisplay_internal. */
386
387 static struct text_pos this_line_start_pos;
388
389 /* Number of characters past the end of the line above, including the
390 terminating newline. */
391
392 static struct text_pos this_line_end_pos;
393
394 /* The vertical positions and the height of this line. */
395
396 static int this_line_vpos;
397 static int this_line_y;
398 static int this_line_pixel_height;
399
400 /* X position at which this display line starts. Usually zero;
401 negative if first character is partially visible. */
402
403 static int this_line_start_x;
404
405 /* Buffer that this_line_.* variables are referring to. */
406
407 static struct buffer *this_line_buffer;
408
409 /* Nonzero means truncate lines in all windows less wide than the
410 frame. */
411
412 int truncate_partial_width_windows;
413
414 /* A flag to control how to display unibyte 8-bit character. */
415
416 int unibyte_display_via_language_environment;
417
418 /* Nonzero means we have more than one non-mini-buffer-only frame.
419 Not guaranteed to be accurate except while parsing
420 frame-title-format. */
421
422 int multiple_frames;
423
424 Lisp_Object Vglobal_mode_string;
425
426
427 /* List of variables (symbols) which hold markers for overlay arrows.
428 The symbols on this list are examined during redisplay to determine
429 where to display overlay arrows. */
430
431 Lisp_Object Voverlay_arrow_variable_list;
432
433 /* Marker for where to display an arrow on top of the buffer text. */
434
435 Lisp_Object Voverlay_arrow_position;
436
437 /* String to display for the arrow. Only used on terminal frames. */
438
439 Lisp_Object Voverlay_arrow_string;
440
441 /* Values of those variables at last redisplay are stored as
442 properties on `overlay-arrow-position' symbol. However, if
443 Voverlay_arrow_position is a marker, last-arrow-position is its
444 numerical position. */
445
446 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
447
448 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
449 properties on a symbol in overlay-arrow-variable-list. */
450
451 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
452
453 /* Like mode-line-format, but for the title bar on a visible frame. */
454
455 Lisp_Object Vframe_title_format;
456
457 /* Like mode-line-format, but for the title bar on an iconified frame. */
458
459 Lisp_Object Vicon_title_format;
460
461 /* List of functions to call when a window's size changes. These
462 functions get one arg, a frame on which one or more windows' sizes
463 have changed. */
464
465 static Lisp_Object Vwindow_size_change_functions;
466
467 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
468
469 /* Nonzero if an overlay arrow has been displayed in this window. */
470
471 static int overlay_arrow_seen;
472
473 /* Nonzero means highlight the region even in nonselected windows. */
474
475 int highlight_nonselected_windows;
476
477 /* If cursor motion alone moves point off frame, try scrolling this
478 many lines up or down if that will bring it back. */
479
480 static EMACS_INT scroll_step;
481
482 /* Nonzero means scroll just far enough to bring point back on the
483 screen, when appropriate. */
484
485 static EMACS_INT scroll_conservatively;
486
487 /* Recenter the window whenever point gets within this many lines of
488 the top or bottom of the window. This value is translated into a
489 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
490 that there is really a fixed pixel height scroll margin. */
491
492 EMACS_INT scroll_margin;
493
494 /* Number of windows showing the buffer of the selected window (or
495 another buffer with the same base buffer). keyboard.c refers to
496 this. */
497
498 int buffer_shared;
499
500 /* Vector containing glyphs for an ellipsis `...'. */
501
502 static Lisp_Object default_invis_vector[3];
503
504 /* Zero means display the mode-line/header-line/menu-bar in the default face
505 (this slightly odd definition is for compatibility with previous versions
506 of emacs), non-zero means display them using their respective faces.
507
508 This variable is deprecated. */
509
510 int mode_line_inverse_video;
511
512 /* Prompt to display in front of the mini-buffer contents. */
513
514 Lisp_Object minibuf_prompt;
515
516 /* Width of current mini-buffer prompt. Only set after display_line
517 of the line that contains the prompt. */
518
519 int minibuf_prompt_width;
520
521 /* This is the window where the echo area message was displayed. It
522 is always a mini-buffer window, but it may not be the same window
523 currently active as a mini-buffer. */
524
525 Lisp_Object echo_area_window;
526
527 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
528 pushes the current message and the value of
529 message_enable_multibyte on the stack, the function restore_message
530 pops the stack and displays MESSAGE again. */
531
532 Lisp_Object Vmessage_stack;
533
534 /* Nonzero means multibyte characters were enabled when the echo area
535 message was specified. */
536
537 int message_enable_multibyte;
538
539 /* Nonzero if we should redraw the mode lines on the next redisplay. */
540
541 int update_mode_lines;
542
543 /* Nonzero if window sizes or contents have changed since last
544 redisplay that finished. */
545
546 int windows_or_buffers_changed;
547
548 /* Nonzero means a frame's cursor type has been changed. */
549
550 int cursor_type_changed;
551
552 /* Nonzero after display_mode_line if %l was used and it displayed a
553 line number. */
554
555 int line_number_displayed;
556
557 /* Maximum buffer size for which to display line numbers. */
558
559 Lisp_Object Vline_number_display_limit;
560
561 /* Line width to consider when repositioning for line number display. */
562
563 static EMACS_INT line_number_display_limit_width;
564
565 /* Number of lines to keep in the message log buffer. t means
566 infinite. nil means don't log at all. */
567
568 Lisp_Object Vmessage_log_max;
569
570 /* The name of the *Messages* buffer, a string. */
571
572 static Lisp_Object Vmessages_buffer_name;
573
574 /* Index 0 is the buffer that holds the current (desired) echo area message,
575 or nil if none is desired right now.
576
577 Index 1 is the buffer that holds the previously displayed echo area message,
578 or nil to indicate no message. This is normally what's on the screen now.
579
580 These two can point to the same buffer. That happens when the last
581 message output by the user (or made by echoing) has been displayed. */
582
583 Lisp_Object echo_area_buffer[2];
584
585 /* Permanent pointers to the two buffers that are used for echo area
586 purposes. Once the two buffers are made, and their pointers are
587 placed here, these two slots remain unchanged unless those buffers
588 need to be created afresh. */
589
590 static Lisp_Object echo_buffer[2];
591
592 /* A vector saved used in with_area_buffer to reduce consing. */
593
594 static Lisp_Object Vwith_echo_area_save_vector;
595
596 /* Non-zero means display_echo_area should display the last echo area
597 message again. Set by redisplay_preserve_echo_area. */
598
599 static int display_last_displayed_message_p;
600
601 /* Nonzero if echo area is being used by print; zero if being used by
602 message. */
603
604 int message_buf_print;
605
606 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
607
608 Lisp_Object Qinhibit_menubar_update;
609 int inhibit_menubar_update;
610
611 /* Maximum height for resizing mini-windows. Either a float
612 specifying a fraction of the available height, or an integer
613 specifying a number of lines. */
614
615 Lisp_Object Vmax_mini_window_height;
616
617 /* Non-zero means messages should be displayed with truncated
618 lines instead of being continued. */
619
620 int message_truncate_lines;
621 Lisp_Object Qmessage_truncate_lines;
622
623 /* Set to 1 in clear_message to make redisplay_internal aware
624 of an emptied echo area. */
625
626 static int message_cleared_p;
627
628 /* How to blink the default frame cursor off. */
629 Lisp_Object Vblink_cursor_alist;
630
631 /* A scratch glyph row with contents used for generating truncation
632 glyphs. Also used in direct_output_for_insert. */
633
634 #define MAX_SCRATCH_GLYPHS 100
635 struct glyph_row scratch_glyph_row;
636 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
637
638 /* Ascent and height of the last line processed by move_it_to. */
639
640 static int last_max_ascent, last_height;
641
642 /* Non-zero if there's a help-echo in the echo area. */
643
644 int help_echo_showing_p;
645
646 /* If >= 0, computed, exact values of mode-line and header-line height
647 to use in the macros CURRENT_MODE_LINE_HEIGHT and
648 CURRENT_HEADER_LINE_HEIGHT. */
649
650 int current_mode_line_height, current_header_line_height;
651
652 /* The maximum distance to look ahead for text properties. Values
653 that are too small let us call compute_char_face and similar
654 functions too often which is expensive. Values that are too large
655 let us call compute_char_face and alike too often because we
656 might not be interested in text properties that far away. */
657
658 #define TEXT_PROP_DISTANCE_LIMIT 100
659
660 #if GLYPH_DEBUG
661
662 /* Variables to turn off display optimizations from Lisp. */
663
664 int inhibit_try_window_id, inhibit_try_window_reusing;
665 int inhibit_try_cursor_movement;
666
667 /* Non-zero means print traces of redisplay if compiled with
668 GLYPH_DEBUG != 0. */
669
670 int trace_redisplay_p;
671
672 #endif /* GLYPH_DEBUG */
673
674 #ifdef DEBUG_TRACE_MOVE
675 /* Non-zero means trace with TRACE_MOVE to stderr. */
676 int trace_move;
677
678 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
679 #else
680 #define TRACE_MOVE(x) (void) 0
681 #endif
682
683 /* Non-zero means automatically scroll windows horizontally to make
684 point visible. */
685
686 int automatic_hscrolling_p;
687
688 /* How close to the margin can point get before the window is scrolled
689 horizontally. */
690 EMACS_INT hscroll_margin;
691
692 /* How much to scroll horizontally when point is inside the above margin. */
693 Lisp_Object Vhscroll_step;
694
695 /* The variable `resize-mini-windows'. If nil, don't resize
696 mini-windows. If t, always resize them to fit the text they
697 display. If `grow-only', let mini-windows grow only until they
698 become empty. */
699
700 Lisp_Object Vresize_mini_windows;
701
702 /* Buffer being redisplayed -- for redisplay_window_error. */
703
704 struct buffer *displayed_buffer;
705
706 /* Value returned from text property handlers (see below). */
707
708 enum prop_handled
709 {
710 HANDLED_NORMALLY,
711 HANDLED_RECOMPUTE_PROPS,
712 HANDLED_OVERLAY_STRING_CONSUMED,
713 HANDLED_RETURN
714 };
715
716 /* A description of text properties that redisplay is interested
717 in. */
718
719 struct props
720 {
721 /* The name of the property. */
722 Lisp_Object *name;
723
724 /* A unique index for the property. */
725 enum prop_idx idx;
726
727 /* A handler function called to set up iterator IT from the property
728 at IT's current position. Value is used to steer handle_stop. */
729 enum prop_handled (*handler) P_ ((struct it *it));
730 };
731
732 static enum prop_handled handle_face_prop P_ ((struct it *));
733 static enum prop_handled handle_invisible_prop P_ ((struct it *));
734 static enum prop_handled handle_display_prop P_ ((struct it *));
735 static enum prop_handled handle_composition_prop P_ ((struct it *));
736 static enum prop_handled handle_overlay_change P_ ((struct it *));
737 static enum prop_handled handle_fontified_prop P_ ((struct it *));
738
739 /* Properties handled by iterators. */
740
741 static struct props it_props[] =
742 {
743 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
744 /* Handle `face' before `display' because some sub-properties of
745 `display' need to know the face. */
746 {&Qface, FACE_PROP_IDX, handle_face_prop},
747 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
748 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
749 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
750 {NULL, 0, NULL}
751 };
752
753 /* Value is the position described by X. If X is a marker, value is
754 the marker_position of X. Otherwise, value is X. */
755
756 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
757
758 /* Enumeration returned by some move_it_.* functions internally. */
759
760 enum move_it_result
761 {
762 /* Not used. Undefined value. */
763 MOVE_UNDEFINED,
764
765 /* Move ended at the requested buffer position or ZV. */
766 MOVE_POS_MATCH_OR_ZV,
767
768 /* Move ended at the requested X pixel position. */
769 MOVE_X_REACHED,
770
771 /* Move within a line ended at the end of a line that must be
772 continued. */
773 MOVE_LINE_CONTINUED,
774
775 /* Move within a line ended at the end of a line that would
776 be displayed truncated. */
777 MOVE_LINE_TRUNCATED,
778
779 /* Move within a line ended at a line end. */
780 MOVE_NEWLINE_OR_CR
781 };
782
783 /* This counter is used to clear the face cache every once in a while
784 in redisplay_internal. It is incremented for each redisplay.
785 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
786 cleared. */
787
788 #define CLEAR_FACE_CACHE_COUNT 500
789 static int clear_face_cache_count;
790
791 /* Similarly for the image cache. */
792
793 #ifdef HAVE_WINDOW_SYSTEM
794 #define CLEAR_IMAGE_CACHE_COUNT 101
795 static int clear_image_cache_count;
796 #endif
797
798 /* Record the previous terminal frame we displayed. */
799
800 static struct frame *previous_terminal_frame;
801
802 /* Non-zero while redisplay_internal is in progress. */
803
804 int redisplaying_p;
805
806 /* Non-zero means don't free realized faces. Bound while freeing
807 realized faces is dangerous because glyph matrices might still
808 reference them. */
809
810 int inhibit_free_realized_faces;
811 Lisp_Object Qinhibit_free_realized_faces;
812
813 /* If a string, XTread_socket generates an event to display that string.
814 (The display is done in read_char.) */
815
816 Lisp_Object help_echo_string;
817 Lisp_Object help_echo_window;
818 Lisp_Object help_echo_object;
819 int help_echo_pos;
820
821 /* Temporary variable for XTread_socket. */
822
823 Lisp_Object previous_help_echo_string;
824
825 /* Null glyph slice */
826
827 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
828
829 \f
830 /* Function prototypes. */
831
832 static void setup_for_ellipsis P_ ((struct it *, int));
833 static void mark_window_display_accurate_1 P_ ((struct window *, int));
834 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
835 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
836 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
837 static int redisplay_mode_lines P_ ((Lisp_Object, int));
838 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
839
840 #if 0
841 static int invisible_text_between_p P_ ((struct it *, int, int));
842 #endif
843
844 static void pint2str P_ ((char *, int, int));
845 static void pint2hrstr P_ ((char *, int, int));
846 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
847 struct text_pos));
848 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
849 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
850 static void store_mode_line_noprop_char P_ ((char));
851 static int store_mode_line_noprop P_ ((const unsigned char *, int, int));
852 static void x_consider_frame_title P_ ((Lisp_Object));
853 static void handle_stop P_ ((struct it *));
854 static int tool_bar_lines_needed P_ ((struct frame *));
855 static int single_display_spec_intangible_p P_ ((Lisp_Object));
856 static void ensure_echo_area_buffers P_ ((void));
857 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
858 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
859 static int with_echo_area_buffer P_ ((struct window *, int,
860 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
861 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
862 static void clear_garbaged_frames P_ ((void));
863 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
864 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
865 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
866 static int display_echo_area P_ ((struct window *));
867 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
868 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
869 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
870 static int string_char_and_length P_ ((const unsigned char *, int, int *));
871 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
872 struct text_pos));
873 static int compute_window_start_on_continuation_line P_ ((struct window *));
874 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
875 static void insert_left_trunc_glyphs P_ ((struct it *));
876 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
877 Lisp_Object));
878 static void extend_face_to_end_of_line P_ ((struct it *));
879 static int append_space_for_newline P_ ((struct it *, int));
880 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
881 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
882 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
883 static int trailing_whitespace_p P_ ((int));
884 static int message_log_check_duplicate P_ ((int, int, int, int));
885 static void push_it P_ ((struct it *));
886 static void pop_it P_ ((struct it *));
887 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
888 static void select_frame_for_redisplay P_ ((Lisp_Object));
889 static void redisplay_internal P_ ((int));
890 static int echo_area_display P_ ((int));
891 static void redisplay_windows P_ ((Lisp_Object));
892 static void redisplay_window P_ ((Lisp_Object, int));
893 static Lisp_Object redisplay_window_error ();
894 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
895 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
896 static void update_menu_bar P_ ((struct frame *, int));
897 static int try_window_reusing_current_matrix P_ ((struct window *));
898 static int try_window_id P_ ((struct window *));
899 static int display_line P_ ((struct it *));
900 static int display_mode_lines P_ ((struct window *));
901 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
902 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
903 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
904 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
905 static void display_menu_bar P_ ((struct window *));
906 static int display_count_lines P_ ((int, int, int, int, int *));
907 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
908 int, int, struct it *, int, int, int, int));
909 static void compute_line_metrics P_ ((struct it *));
910 static void run_redisplay_end_trigger_hook P_ ((struct it *));
911 static int get_overlay_strings P_ ((struct it *, int));
912 static void next_overlay_string P_ ((struct it *));
913 static void reseat P_ ((struct it *, struct text_pos, int));
914 static void reseat_1 P_ ((struct it *, struct text_pos, int));
915 static void back_to_previous_visible_line_start P_ ((struct it *));
916 void reseat_at_previous_visible_line_start P_ ((struct it *));
917 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
918 static int next_element_from_ellipsis P_ ((struct it *));
919 static int next_element_from_display_vector P_ ((struct it *));
920 static int next_element_from_string P_ ((struct it *));
921 static int next_element_from_c_string P_ ((struct it *));
922 static int next_element_from_buffer P_ ((struct it *));
923 static int next_element_from_composition P_ ((struct it *));
924 static int next_element_from_image P_ ((struct it *));
925 static int next_element_from_stretch P_ ((struct it *));
926 static void load_overlay_strings P_ ((struct it *, int));
927 static int init_from_display_pos P_ ((struct it *, struct window *,
928 struct display_pos *));
929 static void reseat_to_string P_ ((struct it *, unsigned char *,
930 Lisp_Object, int, int, int, int));
931 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
932 int, int, int));
933 void move_it_vertically_backward P_ ((struct it *, int));
934 static void init_to_row_start P_ ((struct it *, struct window *,
935 struct glyph_row *));
936 static int init_to_row_end P_ ((struct it *, struct window *,
937 struct glyph_row *));
938 static void back_to_previous_line_start P_ ((struct it *));
939 static int forward_to_next_line_start P_ ((struct it *, int *));
940 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
941 Lisp_Object, int));
942 static struct text_pos string_pos P_ ((int, Lisp_Object));
943 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
944 static int number_of_chars P_ ((unsigned char *, int));
945 static void compute_stop_pos P_ ((struct it *));
946 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
947 Lisp_Object));
948 static int face_before_or_after_it_pos P_ ((struct it *, int));
949 static int next_overlay_change P_ ((int));
950 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
951 Lisp_Object, struct text_pos *,
952 int));
953 static int underlying_face_id P_ ((struct it *));
954 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
955 struct window *));
956
957 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
958 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
959
960 #ifdef HAVE_WINDOW_SYSTEM
961
962 static void update_tool_bar P_ ((struct frame *, int));
963 static void build_desired_tool_bar_string P_ ((struct frame *f));
964 static int redisplay_tool_bar P_ ((struct frame *));
965 static void display_tool_bar_line P_ ((struct it *));
966 static void notice_overwritten_cursor P_ ((struct window *,
967 enum glyph_row_area,
968 int, int, int, int));
969
970
971
972 #endif /* HAVE_WINDOW_SYSTEM */
973
974 \f
975 /***********************************************************************
976 Window display dimensions
977 ***********************************************************************/
978
979 /* Return the bottom boundary y-position for text lines in window W.
980 This is the first y position at which a line cannot start.
981 It is relative to the top of the window.
982
983 This is the height of W minus the height of a mode line, if any. */
984
985 INLINE int
986 window_text_bottom_y (w)
987 struct window *w;
988 {
989 int height = WINDOW_TOTAL_HEIGHT (w);
990
991 if (WINDOW_WANTS_MODELINE_P (w))
992 height -= CURRENT_MODE_LINE_HEIGHT (w);
993 return height;
994 }
995
996 /* Return the pixel width of display area AREA of window W. AREA < 0
997 means return the total width of W, not including fringes to
998 the left and right of the window. */
999
1000 INLINE int
1001 window_box_width (w, area)
1002 struct window *w;
1003 int area;
1004 {
1005 int cols = XFASTINT (w->total_cols);
1006 int pixels = 0;
1007
1008 if (!w->pseudo_window_p)
1009 {
1010 cols -= WINDOW_SCROLL_BAR_COLS (w);
1011
1012 if (area == TEXT_AREA)
1013 {
1014 if (INTEGERP (w->left_margin_cols))
1015 cols -= XFASTINT (w->left_margin_cols);
1016 if (INTEGERP (w->right_margin_cols))
1017 cols -= XFASTINT (w->right_margin_cols);
1018 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1019 }
1020 else if (area == LEFT_MARGIN_AREA)
1021 {
1022 cols = (INTEGERP (w->left_margin_cols)
1023 ? XFASTINT (w->left_margin_cols) : 0);
1024 pixels = 0;
1025 }
1026 else if (area == RIGHT_MARGIN_AREA)
1027 {
1028 cols = (INTEGERP (w->right_margin_cols)
1029 ? XFASTINT (w->right_margin_cols) : 0);
1030 pixels = 0;
1031 }
1032 }
1033
1034 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1035 }
1036
1037
1038 /* Return the pixel height of the display area of window W, not
1039 including mode lines of W, if any. */
1040
1041 INLINE int
1042 window_box_height (w)
1043 struct window *w;
1044 {
1045 struct frame *f = XFRAME (w->frame);
1046 int height = WINDOW_TOTAL_HEIGHT (w);
1047
1048 xassert (height >= 0);
1049
1050 /* Note: the code below that determines the mode-line/header-line
1051 height is essentially the same as that contained in the macro
1052 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1053 the appropriate glyph row has its `mode_line_p' flag set,
1054 and if it doesn't, uses estimate_mode_line_height instead. */
1055
1056 if (WINDOW_WANTS_MODELINE_P (w))
1057 {
1058 struct glyph_row *ml_row
1059 = (w->current_matrix && w->current_matrix->rows
1060 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1061 : 0);
1062 if (ml_row && ml_row->mode_line_p)
1063 height -= ml_row->height;
1064 else
1065 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1066 }
1067
1068 if (WINDOW_WANTS_HEADER_LINE_P (w))
1069 {
1070 struct glyph_row *hl_row
1071 = (w->current_matrix && w->current_matrix->rows
1072 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1073 : 0);
1074 if (hl_row && hl_row->mode_line_p)
1075 height -= hl_row->height;
1076 else
1077 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1078 }
1079
1080 /* With a very small font and a mode-line that's taller than
1081 default, we might end up with a negative height. */
1082 return max (0, height);
1083 }
1084
1085 /* Return the window-relative coordinate of the left edge of display
1086 area AREA of window W. AREA < 0 means return the left edge of the
1087 whole window, to the right of the left fringe of W. */
1088
1089 INLINE int
1090 window_box_left_offset (w, area)
1091 struct window *w;
1092 int area;
1093 {
1094 int x;
1095
1096 if (w->pseudo_window_p)
1097 return 0;
1098
1099 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1100
1101 if (area == TEXT_AREA)
1102 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1103 + window_box_width (w, LEFT_MARGIN_AREA));
1104 else if (area == RIGHT_MARGIN_AREA)
1105 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1106 + window_box_width (w, LEFT_MARGIN_AREA)
1107 + window_box_width (w, TEXT_AREA)
1108 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1109 ? 0
1110 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1111 else if (area == LEFT_MARGIN_AREA
1112 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1113 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1114
1115 return x;
1116 }
1117
1118
1119 /* Return the window-relative coordinate of the right edge of display
1120 area AREA of window W. AREA < 0 means return the left edge of the
1121 whole window, to the left of the right fringe of W. */
1122
1123 INLINE int
1124 window_box_right_offset (w, area)
1125 struct window *w;
1126 int area;
1127 {
1128 return window_box_left_offset (w, area) + window_box_width (w, area);
1129 }
1130
1131 /* Return the frame-relative coordinate of the left edge of display
1132 area AREA of window W. AREA < 0 means return the left edge of the
1133 whole window, to the right of the left fringe of W. */
1134
1135 INLINE int
1136 window_box_left (w, area)
1137 struct window *w;
1138 int area;
1139 {
1140 struct frame *f = XFRAME (w->frame);
1141 int x;
1142
1143 if (w->pseudo_window_p)
1144 return FRAME_INTERNAL_BORDER_WIDTH (f);
1145
1146 x = (WINDOW_LEFT_EDGE_X (w)
1147 + window_box_left_offset (w, area));
1148
1149 return x;
1150 }
1151
1152
1153 /* Return the frame-relative coordinate of the right edge of display
1154 area AREA of window W. AREA < 0 means return the left edge of the
1155 whole window, to the left of the right fringe of W. */
1156
1157 INLINE int
1158 window_box_right (w, area)
1159 struct window *w;
1160 int area;
1161 {
1162 return window_box_left (w, area) + window_box_width (w, area);
1163 }
1164
1165 /* Get the bounding box of the display area AREA of window W, without
1166 mode lines, in frame-relative coordinates. AREA < 0 means the
1167 whole window, not including the left and right fringes of
1168 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1169 coordinates of the upper-left corner of the box. Return in
1170 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1171
1172 INLINE void
1173 window_box (w, area, box_x, box_y, box_width, box_height)
1174 struct window *w;
1175 int area;
1176 int *box_x, *box_y, *box_width, *box_height;
1177 {
1178 if (box_width)
1179 *box_width = window_box_width (w, area);
1180 if (box_height)
1181 *box_height = window_box_height (w);
1182 if (box_x)
1183 *box_x = window_box_left (w, area);
1184 if (box_y)
1185 {
1186 *box_y = WINDOW_TOP_EDGE_Y (w);
1187 if (WINDOW_WANTS_HEADER_LINE_P (w))
1188 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1189 }
1190 }
1191
1192
1193 /* Get the bounding box of the display area AREA of window W, without
1194 mode lines. AREA < 0 means the whole window, not including the
1195 left and right fringe of the window. Return in *TOP_LEFT_X
1196 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1197 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1198 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1199 box. */
1200
1201 INLINE void
1202 window_box_edges (w, area, top_left_x, top_left_y,
1203 bottom_right_x, bottom_right_y)
1204 struct window *w;
1205 int area;
1206 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1207 {
1208 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1209 bottom_right_y);
1210 *bottom_right_x += *top_left_x;
1211 *bottom_right_y += *top_left_y;
1212 }
1213
1214
1215 \f
1216 /***********************************************************************
1217 Utilities
1218 ***********************************************************************/
1219
1220 /* Return the bottom y-position of the line the iterator IT is in.
1221 This can modify IT's settings. */
1222
1223 int
1224 line_bottom_y (it)
1225 struct it *it;
1226 {
1227 int line_height = it->max_ascent + it->max_descent;
1228 int line_top_y = it->current_y;
1229
1230 if (line_height == 0)
1231 {
1232 if (last_height)
1233 line_height = last_height;
1234 else if (IT_CHARPOS (*it) < ZV)
1235 {
1236 move_it_by_lines (it, 1, 1);
1237 line_height = (it->max_ascent || it->max_descent
1238 ? it->max_ascent + it->max_descent
1239 : last_height);
1240 }
1241 else
1242 {
1243 struct glyph_row *row = it->glyph_row;
1244
1245 /* Use the default character height. */
1246 it->glyph_row = NULL;
1247 it->what = IT_CHARACTER;
1248 it->c = ' ';
1249 it->len = 1;
1250 PRODUCE_GLYPHS (it);
1251 line_height = it->ascent + it->descent;
1252 it->glyph_row = row;
1253 }
1254 }
1255
1256 return line_top_y + line_height;
1257 }
1258
1259
1260 /* Return 1 if position CHARPOS is visible in window W.
1261 If visible, set *X and *Y to pixel coordinates of top left corner.
1262 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1263 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1264 and header-lines heights. */
1265
1266 int
1267 pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1268 struct window *w;
1269 int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
1270 {
1271 struct it it;
1272 struct text_pos top;
1273 int visible_p = 0;
1274 struct buffer *old_buffer = NULL;
1275
1276 if (noninteractive)
1277 return visible_p;
1278
1279 if (XBUFFER (w->buffer) != current_buffer)
1280 {
1281 old_buffer = current_buffer;
1282 set_buffer_internal_1 (XBUFFER (w->buffer));
1283 }
1284
1285 SET_TEXT_POS_FROM_MARKER (top, w->start);
1286
1287 /* Compute exact mode line heights, if requested. */
1288 if (exact_mode_line_heights_p)
1289 {
1290 if (WINDOW_WANTS_MODELINE_P (w))
1291 current_mode_line_height
1292 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1293 current_buffer->mode_line_format);
1294
1295 if (WINDOW_WANTS_HEADER_LINE_P (w))
1296 current_header_line_height
1297 = display_mode_line (w, HEADER_LINE_FACE_ID,
1298 current_buffer->header_line_format);
1299 }
1300
1301 start_display (&it, w, top);
1302 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1303 MOVE_TO_POS | MOVE_TO_Y);
1304
1305 /* Note that we may overshoot because of invisible text. */
1306 if (IT_CHARPOS (it) >= charpos)
1307 {
1308 int top_x = it.current_x;
1309 int top_y = it.current_y;
1310 int bottom_y = (last_height = 0, line_bottom_y (&it));
1311 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1312
1313 if (top_y < window_top_y)
1314 visible_p = bottom_y > window_top_y;
1315 else if (top_y < it.last_visible_y)
1316 visible_p = 1;
1317 if (visible_p)
1318 {
1319 *x = top_x;
1320 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1321 *rtop = max (0, window_top_y - top_y);
1322 *rbot = max (0, bottom_y - it.last_visible_y);
1323 }
1324 }
1325 else
1326 {
1327 struct it it2;
1328
1329 it2 = it;
1330 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1331 move_it_by_lines (&it, 1, 0);
1332 if (charpos < IT_CHARPOS (it))
1333 {
1334 visible_p = 1;
1335 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1336 *x = it2.current_x;
1337 *y = it2.current_y + it2.max_ascent - it2.ascent;
1338 *rtop = max (0, -it2.current_y);
1339 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1340 - it.last_visible_y));
1341 }
1342 }
1343
1344 if (old_buffer)
1345 set_buffer_internal_1 (old_buffer);
1346
1347 current_header_line_height = current_mode_line_height = -1;
1348
1349 return visible_p;
1350 }
1351
1352
1353 /* Return the next character from STR which is MAXLEN bytes long.
1354 Return in *LEN the length of the character. This is like
1355 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1356 we find one, we return a `?', but with the length of the invalid
1357 character. */
1358
1359 static INLINE int
1360 string_char_and_length (str, maxlen, len)
1361 const unsigned char *str;
1362 int maxlen, *len;
1363 {
1364 int c;
1365
1366 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1367 if (!CHAR_VALID_P (c, 1))
1368 /* We may not change the length here because other places in Emacs
1369 don't use this function, i.e. they silently accept invalid
1370 characters. */
1371 c = '?';
1372
1373 return c;
1374 }
1375
1376
1377
1378 /* Given a position POS containing a valid character and byte position
1379 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1380
1381 static struct text_pos
1382 string_pos_nchars_ahead (pos, string, nchars)
1383 struct text_pos pos;
1384 Lisp_Object string;
1385 int nchars;
1386 {
1387 xassert (STRINGP (string) && nchars >= 0);
1388
1389 if (STRING_MULTIBYTE (string))
1390 {
1391 int rest = SBYTES (string) - BYTEPOS (pos);
1392 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1393 int len;
1394
1395 while (nchars--)
1396 {
1397 string_char_and_length (p, rest, &len);
1398 p += len, rest -= len;
1399 xassert (rest >= 0);
1400 CHARPOS (pos) += 1;
1401 BYTEPOS (pos) += len;
1402 }
1403 }
1404 else
1405 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1406
1407 return pos;
1408 }
1409
1410
1411 /* Value is the text position, i.e. character and byte position,
1412 for character position CHARPOS in STRING. */
1413
1414 static INLINE struct text_pos
1415 string_pos (charpos, string)
1416 int charpos;
1417 Lisp_Object string;
1418 {
1419 struct text_pos pos;
1420 xassert (STRINGP (string));
1421 xassert (charpos >= 0);
1422 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1423 return pos;
1424 }
1425
1426
1427 /* Value is a text position, i.e. character and byte position, for
1428 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1429 means recognize multibyte characters. */
1430
1431 static struct text_pos
1432 c_string_pos (charpos, s, multibyte_p)
1433 int charpos;
1434 unsigned char *s;
1435 int multibyte_p;
1436 {
1437 struct text_pos pos;
1438
1439 xassert (s != NULL);
1440 xassert (charpos >= 0);
1441
1442 if (multibyte_p)
1443 {
1444 int rest = strlen (s), len;
1445
1446 SET_TEXT_POS (pos, 0, 0);
1447 while (charpos--)
1448 {
1449 string_char_and_length (s, rest, &len);
1450 s += len, rest -= len;
1451 xassert (rest >= 0);
1452 CHARPOS (pos) += 1;
1453 BYTEPOS (pos) += len;
1454 }
1455 }
1456 else
1457 SET_TEXT_POS (pos, charpos, charpos);
1458
1459 return pos;
1460 }
1461
1462
1463 /* Value is the number of characters in C string S. MULTIBYTE_P
1464 non-zero means recognize multibyte characters. */
1465
1466 static int
1467 number_of_chars (s, multibyte_p)
1468 unsigned char *s;
1469 int multibyte_p;
1470 {
1471 int nchars;
1472
1473 if (multibyte_p)
1474 {
1475 int rest = strlen (s), len;
1476 unsigned char *p = (unsigned char *) s;
1477
1478 for (nchars = 0; rest > 0; ++nchars)
1479 {
1480 string_char_and_length (p, rest, &len);
1481 rest -= len, p += len;
1482 }
1483 }
1484 else
1485 nchars = strlen (s);
1486
1487 return nchars;
1488 }
1489
1490
1491 /* Compute byte position NEWPOS->bytepos corresponding to
1492 NEWPOS->charpos. POS is a known position in string STRING.
1493 NEWPOS->charpos must be >= POS.charpos. */
1494
1495 static void
1496 compute_string_pos (newpos, pos, string)
1497 struct text_pos *newpos, pos;
1498 Lisp_Object string;
1499 {
1500 xassert (STRINGP (string));
1501 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1502
1503 if (STRING_MULTIBYTE (string))
1504 *newpos = string_pos_nchars_ahead (pos, string,
1505 CHARPOS (*newpos) - CHARPOS (pos));
1506 else
1507 BYTEPOS (*newpos) = CHARPOS (*newpos);
1508 }
1509
1510 /* EXPORT:
1511 Return an estimation of the pixel height of mode or top lines on
1512 frame F. FACE_ID specifies what line's height to estimate. */
1513
1514 int
1515 estimate_mode_line_height (f, face_id)
1516 struct frame *f;
1517 enum face_id face_id;
1518 {
1519 #ifdef HAVE_WINDOW_SYSTEM
1520 if (FRAME_WINDOW_P (f))
1521 {
1522 int height = FONT_HEIGHT (FRAME_FONT (f));
1523
1524 /* This function is called so early when Emacs starts that the face
1525 cache and mode line face are not yet initialized. */
1526 if (FRAME_FACE_CACHE (f))
1527 {
1528 struct face *face = FACE_FROM_ID (f, face_id);
1529 if (face)
1530 {
1531 if (face->font)
1532 height = FONT_HEIGHT (face->font);
1533 if (face->box_line_width > 0)
1534 height += 2 * face->box_line_width;
1535 }
1536 }
1537
1538 return height;
1539 }
1540 #endif
1541
1542 return 1;
1543 }
1544
1545 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1546 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1547 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1548 not force the value into range. */
1549
1550 void
1551 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1552 FRAME_PTR f;
1553 register int pix_x, pix_y;
1554 int *x, *y;
1555 NativeRectangle *bounds;
1556 int noclip;
1557 {
1558
1559 #ifdef HAVE_WINDOW_SYSTEM
1560 if (FRAME_WINDOW_P (f))
1561 {
1562 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1563 even for negative values. */
1564 if (pix_x < 0)
1565 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1566 if (pix_y < 0)
1567 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1568
1569 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1570 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1571
1572 if (bounds)
1573 STORE_NATIVE_RECT (*bounds,
1574 FRAME_COL_TO_PIXEL_X (f, pix_x),
1575 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1576 FRAME_COLUMN_WIDTH (f) - 1,
1577 FRAME_LINE_HEIGHT (f) - 1);
1578
1579 if (!noclip)
1580 {
1581 if (pix_x < 0)
1582 pix_x = 0;
1583 else if (pix_x > FRAME_TOTAL_COLS (f))
1584 pix_x = FRAME_TOTAL_COLS (f);
1585
1586 if (pix_y < 0)
1587 pix_y = 0;
1588 else if (pix_y > FRAME_LINES (f))
1589 pix_y = FRAME_LINES (f);
1590 }
1591 }
1592 #endif
1593
1594 *x = pix_x;
1595 *y = pix_y;
1596 }
1597
1598
1599 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1600 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1601 can't tell the positions because W's display is not up to date,
1602 return 0. */
1603
1604 int
1605 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1606 struct window *w;
1607 int hpos, vpos;
1608 int *frame_x, *frame_y;
1609 {
1610 #ifdef HAVE_WINDOW_SYSTEM
1611 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1612 {
1613 int success_p;
1614
1615 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1616 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1617
1618 if (display_completed)
1619 {
1620 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1621 struct glyph *glyph = row->glyphs[TEXT_AREA];
1622 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1623
1624 hpos = row->x;
1625 vpos = row->y;
1626 while (glyph < end)
1627 {
1628 hpos += glyph->pixel_width;
1629 ++glyph;
1630 }
1631
1632 /* If first glyph is partially visible, its first visible position is still 0. */
1633 if (hpos < 0)
1634 hpos = 0;
1635
1636 success_p = 1;
1637 }
1638 else
1639 {
1640 hpos = vpos = 0;
1641 success_p = 0;
1642 }
1643
1644 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1645 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1646 return success_p;
1647 }
1648 #endif
1649
1650 *frame_x = hpos;
1651 *frame_y = vpos;
1652 return 1;
1653 }
1654
1655
1656 #ifdef HAVE_WINDOW_SYSTEM
1657
1658 /* Find the glyph under window-relative coordinates X/Y in window W.
1659 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1660 strings. Return in *HPOS and *VPOS the row and column number of
1661 the glyph found. Return in *AREA the glyph area containing X.
1662 Value is a pointer to the glyph found or null if X/Y is not on
1663 text, or we can't tell because W's current matrix is not up to
1664 date. */
1665
1666 static struct glyph *
1667 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1668 struct window *w;
1669 int x, y;
1670 int *hpos, *vpos, *dx, *dy, *area;
1671 {
1672 struct glyph *glyph, *end;
1673 struct glyph_row *row = NULL;
1674 int x0, i;
1675
1676 /* Find row containing Y. Give up if some row is not enabled. */
1677 for (i = 0; i < w->current_matrix->nrows; ++i)
1678 {
1679 row = MATRIX_ROW (w->current_matrix, i);
1680 if (!row->enabled_p)
1681 return NULL;
1682 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1683 break;
1684 }
1685
1686 *vpos = i;
1687 *hpos = 0;
1688
1689 /* Give up if Y is not in the window. */
1690 if (i == w->current_matrix->nrows)
1691 return NULL;
1692
1693 /* Get the glyph area containing X. */
1694 if (w->pseudo_window_p)
1695 {
1696 *area = TEXT_AREA;
1697 x0 = 0;
1698 }
1699 else
1700 {
1701 if (x < window_box_left_offset (w, TEXT_AREA))
1702 {
1703 *area = LEFT_MARGIN_AREA;
1704 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1705 }
1706 else if (x < window_box_right_offset (w, TEXT_AREA))
1707 {
1708 *area = TEXT_AREA;
1709 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1710 }
1711 else
1712 {
1713 *area = RIGHT_MARGIN_AREA;
1714 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1715 }
1716 }
1717
1718 /* Find glyph containing X. */
1719 glyph = row->glyphs[*area];
1720 end = glyph + row->used[*area];
1721 x -= x0;
1722 while (glyph < end && x >= glyph->pixel_width)
1723 {
1724 x -= glyph->pixel_width;
1725 ++glyph;
1726 }
1727
1728 if (glyph == end)
1729 return NULL;
1730
1731 if (dx)
1732 {
1733 *dx = x;
1734 *dy = y - (row->y + row->ascent - glyph->ascent);
1735 }
1736
1737 *hpos = glyph - row->glyphs[*area];
1738 return glyph;
1739 }
1740
1741
1742 /* EXPORT:
1743 Convert frame-relative x/y to coordinates relative to window W.
1744 Takes pseudo-windows into account. */
1745
1746 void
1747 frame_to_window_pixel_xy (w, x, y)
1748 struct window *w;
1749 int *x, *y;
1750 {
1751 if (w->pseudo_window_p)
1752 {
1753 /* A pseudo-window is always full-width, and starts at the
1754 left edge of the frame, plus a frame border. */
1755 struct frame *f = XFRAME (w->frame);
1756 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1757 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1758 }
1759 else
1760 {
1761 *x -= WINDOW_LEFT_EDGE_X (w);
1762 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1763 }
1764 }
1765
1766 /* EXPORT:
1767 Return in *R the clipping rectangle for glyph string S. */
1768
1769 void
1770 get_glyph_string_clip_rect (s, nr)
1771 struct glyph_string *s;
1772 NativeRectangle *nr;
1773 {
1774 XRectangle r;
1775
1776 if (s->row->full_width_p)
1777 {
1778 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1779 r.x = WINDOW_LEFT_EDGE_X (s->w);
1780 r.width = WINDOW_TOTAL_WIDTH (s->w);
1781
1782 /* Unless displaying a mode or menu bar line, which are always
1783 fully visible, clip to the visible part of the row. */
1784 if (s->w->pseudo_window_p)
1785 r.height = s->row->visible_height;
1786 else
1787 r.height = s->height;
1788 }
1789 else
1790 {
1791 /* This is a text line that may be partially visible. */
1792 r.x = window_box_left (s->w, s->area);
1793 r.width = window_box_width (s->w, s->area);
1794 r.height = s->row->visible_height;
1795 }
1796
1797 if (s->clip_head)
1798 if (r.x < s->clip_head->x)
1799 {
1800 if (r.width >= s->clip_head->x - r.x)
1801 r.width -= s->clip_head->x - r.x;
1802 else
1803 r.width = 0;
1804 r.x = s->clip_head->x;
1805 }
1806 if (s->clip_tail)
1807 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1808 {
1809 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1810 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1811 else
1812 r.width = 0;
1813 }
1814
1815 /* If S draws overlapping rows, it's sufficient to use the top and
1816 bottom of the window for clipping because this glyph string
1817 intentionally draws over other lines. */
1818 if (s->for_overlaps_p)
1819 {
1820 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1821 r.height = window_text_bottom_y (s->w) - r.y;
1822 }
1823 else
1824 {
1825 /* Don't use S->y for clipping because it doesn't take partially
1826 visible lines into account. For example, it can be negative for
1827 partially visible lines at the top of a window. */
1828 if (!s->row->full_width_p
1829 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1830 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1831 else
1832 r.y = max (0, s->row->y);
1833
1834 /* If drawing a tool-bar window, draw it over the internal border
1835 at the top of the window. */
1836 if (WINDOWP (s->f->tool_bar_window)
1837 && s->w == XWINDOW (s->f->tool_bar_window))
1838 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1839 }
1840
1841 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1842
1843 /* If drawing the cursor, don't let glyph draw outside its
1844 advertised boundaries. Cleartype does this under some circumstances. */
1845 if (s->hl == DRAW_CURSOR)
1846 {
1847 struct glyph *glyph = s->first_glyph;
1848 int height, max_y;
1849
1850 if (s->x > r.x)
1851 {
1852 r.width -= s->x - r.x;
1853 r.x = s->x;
1854 }
1855 r.width = min (r.width, glyph->pixel_width);
1856
1857 /* If r.y is below window bottom, ensure that we still see a cursor. */
1858 height = min (glyph->ascent + glyph->descent,
1859 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1860 max_y = window_text_bottom_y (s->w) - height;
1861 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1862 if (s->ybase - glyph->ascent > max_y)
1863 {
1864 r.y = max_y;
1865 r.height = height;
1866 }
1867 else
1868 {
1869 /* Don't draw cursor glyph taller than our actual glyph. */
1870 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1871 if (height < r.height)
1872 {
1873 max_y = r.y + r.height;
1874 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1875 r.height = min (max_y - r.y, height);
1876 }
1877 }
1878 }
1879
1880 #ifdef CONVERT_FROM_XRECT
1881 CONVERT_FROM_XRECT (r, *nr);
1882 #else
1883 *nr = r;
1884 #endif
1885 }
1886
1887
1888 /* EXPORT:
1889 Return the position and height of the phys cursor in window W.
1890 Set w->phys_cursor_width to width of phys cursor.
1891 */
1892
1893 int
1894 get_phys_cursor_geometry (w, row, glyph, heightp)
1895 struct window *w;
1896 struct glyph_row *row;
1897 struct glyph *glyph;
1898 int *heightp;
1899 {
1900 struct frame *f = XFRAME (WINDOW_FRAME (w));
1901 int y, wd, h, h0, y0;
1902
1903 /* Compute the width of the rectangle to draw. If on a stretch
1904 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1905 rectangle as wide as the glyph, but use a canonical character
1906 width instead. */
1907 wd = glyph->pixel_width - 1;
1908 #ifdef HAVE_NTGUI
1909 wd++; /* Why? */
1910 #endif
1911 if (glyph->type == STRETCH_GLYPH
1912 && !x_stretch_cursor_p)
1913 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1914 w->phys_cursor_width = wd;
1915
1916 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1917
1918 /* If y is below window bottom, ensure that we still see a cursor. */
1919 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1920
1921 h = max (h0, glyph->ascent + glyph->descent);
1922 h0 = min (h0, glyph->ascent + glyph->descent);
1923
1924 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1925 if (y < y0)
1926 {
1927 h = max (h - (y0 - y) + 1, h0);
1928 y = y0 - 1;
1929 }
1930 else
1931 {
1932 y0 = window_text_bottom_y (w) - h0;
1933 if (y > y0)
1934 {
1935 h += y - y0;
1936 y = y0;
1937 }
1938 }
1939
1940 *heightp = h - 1;
1941 return WINDOW_TO_FRAME_PIXEL_Y (w, y);
1942 }
1943
1944
1945 #endif /* HAVE_WINDOW_SYSTEM */
1946
1947 \f
1948 /***********************************************************************
1949 Lisp form evaluation
1950 ***********************************************************************/
1951
1952 /* Error handler for safe_eval and safe_call. */
1953
1954 static Lisp_Object
1955 safe_eval_handler (arg)
1956 Lisp_Object arg;
1957 {
1958 add_to_log ("Error during redisplay: %s", arg, Qnil);
1959 return Qnil;
1960 }
1961
1962
1963 /* Evaluate SEXPR and return the result, or nil if something went
1964 wrong. Prevent redisplay during the evaluation. */
1965
1966 Lisp_Object
1967 safe_eval (sexpr)
1968 Lisp_Object sexpr;
1969 {
1970 Lisp_Object val;
1971
1972 if (inhibit_eval_during_redisplay)
1973 val = Qnil;
1974 else
1975 {
1976 int count = SPECPDL_INDEX ();
1977 struct gcpro gcpro1;
1978
1979 GCPRO1 (sexpr);
1980 specbind (Qinhibit_redisplay, Qt);
1981 /* Use Qt to ensure debugger does not run,
1982 so there is no possibility of wanting to redisplay. */
1983 val = internal_condition_case_1 (Feval, sexpr, Qt,
1984 safe_eval_handler);
1985 UNGCPRO;
1986 val = unbind_to (count, val);
1987 }
1988
1989 return val;
1990 }
1991
1992
1993 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1994 Return the result, or nil if something went wrong. Prevent
1995 redisplay during the evaluation. */
1996
1997 Lisp_Object
1998 safe_call (nargs, args)
1999 int nargs;
2000 Lisp_Object *args;
2001 {
2002 Lisp_Object val;
2003
2004 if (inhibit_eval_during_redisplay)
2005 val = Qnil;
2006 else
2007 {
2008 int count = SPECPDL_INDEX ();
2009 struct gcpro gcpro1;
2010
2011 GCPRO1 (args[0]);
2012 gcpro1.nvars = nargs;
2013 specbind (Qinhibit_redisplay, Qt);
2014 /* Use Qt to ensure debugger does not run,
2015 so there is no possibility of wanting to redisplay. */
2016 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2017 safe_eval_handler);
2018 UNGCPRO;
2019 val = unbind_to (count, val);
2020 }
2021
2022 return val;
2023 }
2024
2025
2026 /* Call function FN with one argument ARG.
2027 Return the result, or nil if something went wrong. */
2028
2029 Lisp_Object
2030 safe_call1 (fn, arg)
2031 Lisp_Object fn, arg;
2032 {
2033 Lisp_Object args[2];
2034 args[0] = fn;
2035 args[1] = arg;
2036 return safe_call (2, args);
2037 }
2038
2039
2040 \f
2041 /***********************************************************************
2042 Debugging
2043 ***********************************************************************/
2044
2045 #if 0
2046
2047 /* Define CHECK_IT to perform sanity checks on iterators.
2048 This is for debugging. It is too slow to do unconditionally. */
2049
2050 static void
2051 check_it (it)
2052 struct it *it;
2053 {
2054 if (it->method == GET_FROM_STRING)
2055 {
2056 xassert (STRINGP (it->string));
2057 xassert (IT_STRING_CHARPOS (*it) >= 0);
2058 }
2059 else
2060 {
2061 xassert (IT_STRING_CHARPOS (*it) < 0);
2062 if (it->method == GET_FROM_BUFFER)
2063 {
2064 /* Check that character and byte positions agree. */
2065 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2066 }
2067 }
2068
2069 if (it->dpvec)
2070 xassert (it->current.dpvec_index >= 0);
2071 else
2072 xassert (it->current.dpvec_index < 0);
2073 }
2074
2075 #define CHECK_IT(IT) check_it ((IT))
2076
2077 #else /* not 0 */
2078
2079 #define CHECK_IT(IT) (void) 0
2080
2081 #endif /* not 0 */
2082
2083
2084 #if GLYPH_DEBUG
2085
2086 /* Check that the window end of window W is what we expect it
2087 to be---the last row in the current matrix displaying text. */
2088
2089 static void
2090 check_window_end (w)
2091 struct window *w;
2092 {
2093 if (!MINI_WINDOW_P (w)
2094 && !NILP (w->window_end_valid))
2095 {
2096 struct glyph_row *row;
2097 xassert ((row = MATRIX_ROW (w->current_matrix,
2098 XFASTINT (w->window_end_vpos)),
2099 !row->enabled_p
2100 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2101 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2102 }
2103 }
2104
2105 #define CHECK_WINDOW_END(W) check_window_end ((W))
2106
2107 #else /* not GLYPH_DEBUG */
2108
2109 #define CHECK_WINDOW_END(W) (void) 0
2110
2111 #endif /* not GLYPH_DEBUG */
2112
2113
2114 \f
2115 /***********************************************************************
2116 Iterator initialization
2117 ***********************************************************************/
2118
2119 /* Initialize IT for displaying current_buffer in window W, starting
2120 at character position CHARPOS. CHARPOS < 0 means that no buffer
2121 position is specified which is useful when the iterator is assigned
2122 a position later. BYTEPOS is the byte position corresponding to
2123 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2124
2125 If ROW is not null, calls to produce_glyphs with IT as parameter
2126 will produce glyphs in that row.
2127
2128 BASE_FACE_ID is the id of a base face to use. It must be one of
2129 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2130 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2131 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2132
2133 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2134 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2135 will be initialized to use the corresponding mode line glyph row of
2136 the desired matrix of W. */
2137
2138 void
2139 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2140 struct it *it;
2141 struct window *w;
2142 int charpos, bytepos;
2143 struct glyph_row *row;
2144 enum face_id base_face_id;
2145 {
2146 int highlight_region_p;
2147
2148 /* Some precondition checks. */
2149 xassert (w != NULL && it != NULL);
2150 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2151 && charpos <= ZV));
2152
2153 /* If face attributes have been changed since the last redisplay,
2154 free realized faces now because they depend on face definitions
2155 that might have changed. Don't free faces while there might be
2156 desired matrices pending which reference these faces. */
2157 if (face_change_count && !inhibit_free_realized_faces)
2158 {
2159 face_change_count = 0;
2160 free_all_realized_faces (Qnil);
2161 }
2162
2163 /* Use one of the mode line rows of W's desired matrix if
2164 appropriate. */
2165 if (row == NULL)
2166 {
2167 if (base_face_id == MODE_LINE_FACE_ID
2168 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2169 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2170 else if (base_face_id == HEADER_LINE_FACE_ID)
2171 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2172 }
2173
2174 /* Clear IT. */
2175 bzero (it, sizeof *it);
2176 it->current.overlay_string_index = -1;
2177 it->current.dpvec_index = -1;
2178 it->base_face_id = base_face_id;
2179 it->string = Qnil;
2180 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2181
2182 /* The window in which we iterate over current_buffer: */
2183 XSETWINDOW (it->window, w);
2184 it->w = w;
2185 it->f = XFRAME (w->frame);
2186
2187 /* Extra space between lines (on window systems only). */
2188 if (base_face_id == DEFAULT_FACE_ID
2189 && FRAME_WINDOW_P (it->f))
2190 {
2191 if (NATNUMP (current_buffer->extra_line_spacing))
2192 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2193 else if (FLOATP (current_buffer->extra_line_spacing))
2194 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2195 * FRAME_LINE_HEIGHT (it->f));
2196 else if (it->f->extra_line_spacing > 0)
2197 it->extra_line_spacing = it->f->extra_line_spacing;
2198 it->max_extra_line_spacing = 0;
2199 }
2200
2201 /* If realized faces have been removed, e.g. because of face
2202 attribute changes of named faces, recompute them. When running
2203 in batch mode, the face cache of Vterminal_frame is null. If
2204 we happen to get called, make a dummy face cache. */
2205 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2206 init_frame_faces (it->f);
2207 if (FRAME_FACE_CACHE (it->f)->used == 0)
2208 recompute_basic_faces (it->f);
2209
2210 /* Current value of the `slice', `space-width', and 'height' properties. */
2211 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2212 it->space_width = Qnil;
2213 it->font_height = Qnil;
2214 it->override_ascent = -1;
2215
2216 /* Are control characters displayed as `^C'? */
2217 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2218
2219 /* -1 means everything between a CR and the following line end
2220 is invisible. >0 means lines indented more than this value are
2221 invisible. */
2222 it->selective = (INTEGERP (current_buffer->selective_display)
2223 ? XFASTINT (current_buffer->selective_display)
2224 : (!NILP (current_buffer->selective_display)
2225 ? -1 : 0));
2226 it->selective_display_ellipsis_p
2227 = !NILP (current_buffer->selective_display_ellipses);
2228
2229 /* Display table to use. */
2230 it->dp = window_display_table (w);
2231
2232 /* Are multibyte characters enabled in current_buffer? */
2233 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2234
2235 /* Non-zero if we should highlight the region. */
2236 highlight_region_p
2237 = (!NILP (Vtransient_mark_mode)
2238 && !NILP (current_buffer->mark_active)
2239 && XMARKER (current_buffer->mark)->buffer != 0);
2240
2241 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2242 start and end of a visible region in window IT->w. Set both to
2243 -1 to indicate no region. */
2244 if (highlight_region_p
2245 /* Maybe highlight only in selected window. */
2246 && (/* Either show region everywhere. */
2247 highlight_nonselected_windows
2248 /* Or show region in the selected window. */
2249 || w == XWINDOW (selected_window)
2250 /* Or show the region if we are in the mini-buffer and W is
2251 the window the mini-buffer refers to. */
2252 || (MINI_WINDOW_P (XWINDOW (selected_window))
2253 && WINDOWP (minibuf_selected_window)
2254 && w == XWINDOW (minibuf_selected_window))))
2255 {
2256 int charpos = marker_position (current_buffer->mark);
2257 it->region_beg_charpos = min (PT, charpos);
2258 it->region_end_charpos = max (PT, charpos);
2259 }
2260 else
2261 it->region_beg_charpos = it->region_end_charpos = -1;
2262
2263 /* Get the position at which the redisplay_end_trigger hook should
2264 be run, if it is to be run at all. */
2265 if (MARKERP (w->redisplay_end_trigger)
2266 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2267 it->redisplay_end_trigger_charpos
2268 = marker_position (w->redisplay_end_trigger);
2269 else if (INTEGERP (w->redisplay_end_trigger))
2270 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2271
2272 /* Correct bogus values of tab_width. */
2273 it->tab_width = XINT (current_buffer->tab_width);
2274 if (it->tab_width <= 0 || it->tab_width > 1000)
2275 it->tab_width = 8;
2276
2277 /* Are lines in the display truncated? */
2278 it->truncate_lines_p
2279 = (base_face_id != DEFAULT_FACE_ID
2280 || XINT (it->w->hscroll)
2281 || (truncate_partial_width_windows
2282 && !WINDOW_FULL_WIDTH_P (it->w))
2283 || !NILP (current_buffer->truncate_lines));
2284
2285 /* Get dimensions of truncation and continuation glyphs. These are
2286 displayed as fringe bitmaps under X, so we don't need them for such
2287 frames. */
2288 if (!FRAME_WINDOW_P (it->f))
2289 {
2290 if (it->truncate_lines_p)
2291 {
2292 /* We will need the truncation glyph. */
2293 xassert (it->glyph_row == NULL);
2294 produce_special_glyphs (it, IT_TRUNCATION);
2295 it->truncation_pixel_width = it->pixel_width;
2296 }
2297 else
2298 {
2299 /* We will need the continuation glyph. */
2300 xassert (it->glyph_row == NULL);
2301 produce_special_glyphs (it, IT_CONTINUATION);
2302 it->continuation_pixel_width = it->pixel_width;
2303 }
2304
2305 /* Reset these values to zero because the produce_special_glyphs
2306 above has changed them. */
2307 it->pixel_width = it->ascent = it->descent = 0;
2308 it->phys_ascent = it->phys_descent = 0;
2309 }
2310
2311 /* Set this after getting the dimensions of truncation and
2312 continuation glyphs, so that we don't produce glyphs when calling
2313 produce_special_glyphs, above. */
2314 it->glyph_row = row;
2315 it->area = TEXT_AREA;
2316
2317 /* Get the dimensions of the display area. The display area
2318 consists of the visible window area plus a horizontally scrolled
2319 part to the left of the window. All x-values are relative to the
2320 start of this total display area. */
2321 if (base_face_id != DEFAULT_FACE_ID)
2322 {
2323 /* Mode lines, menu bar in terminal frames. */
2324 it->first_visible_x = 0;
2325 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2326 }
2327 else
2328 {
2329 it->first_visible_x
2330 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2331 it->last_visible_x = (it->first_visible_x
2332 + window_box_width (w, TEXT_AREA));
2333
2334 /* If we truncate lines, leave room for the truncator glyph(s) at
2335 the right margin. Otherwise, leave room for the continuation
2336 glyph(s). Truncation and continuation glyphs are not inserted
2337 for window-based redisplay. */
2338 if (!FRAME_WINDOW_P (it->f))
2339 {
2340 if (it->truncate_lines_p)
2341 it->last_visible_x -= it->truncation_pixel_width;
2342 else
2343 it->last_visible_x -= it->continuation_pixel_width;
2344 }
2345
2346 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2347 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2348 }
2349
2350 /* Leave room for a border glyph. */
2351 if (!FRAME_WINDOW_P (it->f)
2352 && !WINDOW_RIGHTMOST_P (it->w))
2353 it->last_visible_x -= 1;
2354
2355 it->last_visible_y = window_text_bottom_y (w);
2356
2357 /* For mode lines and alike, arrange for the first glyph having a
2358 left box line if the face specifies a box. */
2359 if (base_face_id != DEFAULT_FACE_ID)
2360 {
2361 struct face *face;
2362
2363 it->face_id = base_face_id;
2364
2365 /* If we have a boxed mode line, make the first character appear
2366 with a left box line. */
2367 face = FACE_FROM_ID (it->f, base_face_id);
2368 if (face->box != FACE_NO_BOX)
2369 it->start_of_box_run_p = 1;
2370 }
2371
2372 /* If a buffer position was specified, set the iterator there,
2373 getting overlays and face properties from that position. */
2374 if (charpos >= BUF_BEG (current_buffer))
2375 {
2376 it->end_charpos = ZV;
2377 it->face_id = -1;
2378 IT_CHARPOS (*it) = charpos;
2379
2380 /* Compute byte position if not specified. */
2381 if (bytepos < charpos)
2382 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2383 else
2384 IT_BYTEPOS (*it) = bytepos;
2385
2386 it->start = it->current;
2387
2388 /* Compute faces etc. */
2389 reseat (it, it->current.pos, 1);
2390 }
2391
2392 CHECK_IT (it);
2393 }
2394
2395
2396 /* Initialize IT for the display of window W with window start POS. */
2397
2398 void
2399 start_display (it, w, pos)
2400 struct it *it;
2401 struct window *w;
2402 struct text_pos pos;
2403 {
2404 struct glyph_row *row;
2405 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2406
2407 row = w->desired_matrix->rows + first_vpos;
2408 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2409 it->first_vpos = first_vpos;
2410
2411 /* Don't reseat to previous visible line start if current start
2412 position is in a string or image. */
2413 if (it->method == GET_FROM_BUFFER && !it->truncate_lines_p)
2414 {
2415 int start_at_line_beg_p;
2416 int first_y = it->current_y;
2417
2418 /* If window start is not at a line start, skip forward to POS to
2419 get the correct continuation lines width. */
2420 start_at_line_beg_p = (CHARPOS (pos) == BEGV
2421 || FETCH_BYTE (BYTEPOS (pos) - 1) == '\n');
2422 if (!start_at_line_beg_p)
2423 {
2424 int new_x;
2425
2426 reseat_at_previous_visible_line_start (it);
2427 move_it_to (it, CHARPOS (pos), -1, -1, -1, MOVE_TO_POS);
2428
2429 new_x = it->current_x + it->pixel_width;
2430
2431 /* If lines are continued, this line may end in the middle
2432 of a multi-glyph character (e.g. a control character
2433 displayed as \003, or in the middle of an overlay
2434 string). In this case move_it_to above will not have
2435 taken us to the start of the continuation line but to the
2436 end of the continued line. */
2437 if (it->current_x > 0
2438 && !it->truncate_lines_p /* Lines are continued. */
2439 && (/* And glyph doesn't fit on the line. */
2440 new_x > it->last_visible_x
2441 /* Or it fits exactly and we're on a window
2442 system frame. */
2443 || (new_x == it->last_visible_x
2444 && FRAME_WINDOW_P (it->f))))
2445 {
2446 if (it->current.dpvec_index >= 0
2447 || it->current.overlay_string_index >= 0)
2448 {
2449 set_iterator_to_next (it, 1);
2450 move_it_in_display_line_to (it, -1, -1, 0);
2451 }
2452
2453 it->continuation_lines_width += it->current_x;
2454 }
2455
2456 /* We're starting a new display line, not affected by the
2457 height of the continued line, so clear the appropriate
2458 fields in the iterator structure. */
2459 it->max_ascent = it->max_descent = 0;
2460 it->max_phys_ascent = it->max_phys_descent = 0;
2461
2462 it->current_y = first_y;
2463 it->vpos = 0;
2464 it->current_x = it->hpos = 0;
2465 }
2466 }
2467
2468 #if 0 /* Don't assert the following because start_display is sometimes
2469 called intentionally with a window start that is not at a
2470 line start. Please leave this code in as a comment. */
2471
2472 /* Window start should be on a line start, now. */
2473 xassert (it->continuation_lines_width
2474 || IT_CHARPOS (it) == BEGV
2475 || FETCH_BYTE (IT_BYTEPOS (it) - 1) == '\n');
2476 #endif /* 0 */
2477 }
2478
2479
2480 /* Return 1 if POS is a position in ellipses displayed for invisible
2481 text. W is the window we display, for text property lookup. */
2482
2483 static int
2484 in_ellipses_for_invisible_text_p (pos, w)
2485 struct display_pos *pos;
2486 struct window *w;
2487 {
2488 Lisp_Object prop, window;
2489 int ellipses_p = 0;
2490 int charpos = CHARPOS (pos->pos);
2491
2492 /* If POS specifies a position in a display vector, this might
2493 be for an ellipsis displayed for invisible text. We won't
2494 get the iterator set up for delivering that ellipsis unless
2495 we make sure that it gets aware of the invisible text. */
2496 if (pos->dpvec_index >= 0
2497 && pos->overlay_string_index < 0
2498 && CHARPOS (pos->string_pos) < 0
2499 && charpos > BEGV
2500 && (XSETWINDOW (window, w),
2501 prop = Fget_char_property (make_number (charpos),
2502 Qinvisible, window),
2503 !TEXT_PROP_MEANS_INVISIBLE (prop)))
2504 {
2505 prop = Fget_char_property (make_number (charpos - 1), Qinvisible,
2506 window);
2507 ellipses_p = 2 == TEXT_PROP_MEANS_INVISIBLE (prop);
2508 }
2509
2510 return ellipses_p;
2511 }
2512
2513
2514 /* Initialize IT for stepping through current_buffer in window W,
2515 starting at position POS that includes overlay string and display
2516 vector/ control character translation position information. Value
2517 is zero if there are overlay strings with newlines at POS. */
2518
2519 static int
2520 init_from_display_pos (it, w, pos)
2521 struct it *it;
2522 struct window *w;
2523 struct display_pos *pos;
2524 {
2525 int charpos = CHARPOS (pos->pos), bytepos = BYTEPOS (pos->pos);
2526 int i, overlay_strings_with_newlines = 0;
2527
2528 /* If POS specifies a position in a display vector, this might
2529 be for an ellipsis displayed for invisible text. We won't
2530 get the iterator set up for delivering that ellipsis unless
2531 we make sure that it gets aware of the invisible text. */
2532 if (in_ellipses_for_invisible_text_p (pos, w))
2533 {
2534 --charpos;
2535 bytepos = 0;
2536 }
2537
2538 /* Keep in mind: the call to reseat in init_iterator skips invisible
2539 text, so we might end up at a position different from POS. This
2540 is only a problem when POS is a row start after a newline and an
2541 overlay starts there with an after-string, and the overlay has an
2542 invisible property. Since we don't skip invisible text in
2543 display_line and elsewhere immediately after consuming the
2544 newline before the row start, such a POS will not be in a string,
2545 but the call to init_iterator below will move us to the
2546 after-string. */
2547 init_iterator (it, w, charpos, bytepos, NULL, DEFAULT_FACE_ID);
2548
2549 /* This only scans the current chunk -- it should scan all chunks.
2550 However, OVERLAY_STRING_CHUNK_SIZE has been increased from 3 in 21.1
2551 to 16 in 22.1 to make this a lesser problem. */
2552 for (i = 0; i < it->n_overlay_strings && i < OVERLAY_STRING_CHUNK_SIZE; ++i)
2553 {
2554 const char *s = SDATA (it->overlay_strings[i]);
2555 const char *e = s + SBYTES (it->overlay_strings[i]);
2556
2557 while (s < e && *s != '\n')
2558 ++s;
2559
2560 if (s < e)
2561 {
2562 overlay_strings_with_newlines = 1;
2563 break;
2564 }
2565 }
2566
2567 /* If position is within an overlay string, set up IT to the right
2568 overlay string. */
2569 if (pos->overlay_string_index >= 0)
2570 {
2571 int relative_index;
2572
2573 /* If the first overlay string happens to have a `display'
2574 property for an image, the iterator will be set up for that
2575 image, and we have to undo that setup first before we can
2576 correct the overlay string index. */
2577 if (it->method == GET_FROM_IMAGE)
2578 pop_it (it);
2579
2580 /* We already have the first chunk of overlay strings in
2581 IT->overlay_strings. Load more until the one for
2582 pos->overlay_string_index is in IT->overlay_strings. */
2583 if (pos->overlay_string_index >= OVERLAY_STRING_CHUNK_SIZE)
2584 {
2585 int n = pos->overlay_string_index / OVERLAY_STRING_CHUNK_SIZE;
2586 it->current.overlay_string_index = 0;
2587 while (n--)
2588 {
2589 load_overlay_strings (it, 0);
2590 it->current.overlay_string_index += OVERLAY_STRING_CHUNK_SIZE;
2591 }
2592 }
2593
2594 it->current.overlay_string_index = pos->overlay_string_index;
2595 relative_index = (it->current.overlay_string_index
2596 % OVERLAY_STRING_CHUNK_SIZE);
2597 it->string = it->overlay_strings[relative_index];
2598 xassert (STRINGP (it->string));
2599 it->current.string_pos = pos->string_pos;
2600 it->method = GET_FROM_STRING;
2601 }
2602
2603 #if 0 /* This is bogus because POS not having an overlay string
2604 position does not mean it's after the string. Example: A
2605 line starting with a before-string and initialization of IT
2606 to the previous row's end position. */
2607 else if (it->current.overlay_string_index >= 0)
2608 {
2609 /* If POS says we're already after an overlay string ending at
2610 POS, make sure to pop the iterator because it will be in
2611 front of that overlay string. When POS is ZV, we've thereby
2612 also ``processed'' overlay strings at ZV. */
2613 while (it->sp)
2614 pop_it (it);
2615 it->current.overlay_string_index = -1;
2616 it->method = GET_FROM_BUFFER;
2617 if (CHARPOS (pos->pos) == ZV)
2618 it->overlay_strings_at_end_processed_p = 1;
2619 }
2620 #endif /* 0 */
2621
2622 if (CHARPOS (pos->string_pos) >= 0)
2623 {
2624 /* Recorded position is not in an overlay string, but in another
2625 string. This can only be a string from a `display' property.
2626 IT should already be filled with that string. */
2627 it->current.string_pos = pos->string_pos;
2628 xassert (STRINGP (it->string));
2629 }
2630
2631 /* Restore position in display vector translations, control
2632 character translations or ellipses. */
2633 if (pos->dpvec_index >= 0)
2634 {
2635 if (it->dpvec == NULL)
2636 get_next_display_element (it);
2637 xassert (it->dpvec && it->current.dpvec_index == 0);
2638 it->current.dpvec_index = pos->dpvec_index;
2639 }
2640
2641 CHECK_IT (it);
2642 return !overlay_strings_with_newlines;
2643 }
2644
2645
2646 /* Initialize IT for stepping through current_buffer in window W
2647 starting at ROW->start. */
2648
2649 static void
2650 init_to_row_start (it, w, row)
2651 struct it *it;
2652 struct window *w;
2653 struct glyph_row *row;
2654 {
2655 init_from_display_pos (it, w, &row->start);
2656 it->start = row->start;
2657 it->continuation_lines_width = row->continuation_lines_width;
2658 CHECK_IT (it);
2659 }
2660
2661
2662 /* Initialize IT for stepping through current_buffer in window W
2663 starting in the line following ROW, i.e. starting at ROW->end.
2664 Value is zero if there are overlay strings with newlines at ROW's
2665 end position. */
2666
2667 static int
2668 init_to_row_end (it, w, row)
2669 struct it *it;
2670 struct window *w;
2671 struct glyph_row *row;
2672 {
2673 int success = 0;
2674
2675 if (init_from_display_pos (it, w, &row->end))
2676 {
2677 if (row->continued_p)
2678 it->continuation_lines_width
2679 = row->continuation_lines_width + row->pixel_width;
2680 CHECK_IT (it);
2681 success = 1;
2682 }
2683
2684 return success;
2685 }
2686
2687
2688
2689 \f
2690 /***********************************************************************
2691 Text properties
2692 ***********************************************************************/
2693
2694 /* Called when IT reaches IT->stop_charpos. Handle text property and
2695 overlay changes. Set IT->stop_charpos to the next position where
2696 to stop. */
2697
2698 static void
2699 handle_stop (it)
2700 struct it *it;
2701 {
2702 enum prop_handled handled;
2703 int handle_overlay_change_p = 1;
2704 struct props *p;
2705
2706 it->dpvec = NULL;
2707 it->current.dpvec_index = -1;
2708
2709 /* Use face of preceding text for ellipsis (if invisible) */
2710 if (it->selective_display_ellipsis_p)
2711 it->saved_face_id = it->face_id;
2712
2713 do
2714 {
2715 handled = HANDLED_NORMALLY;
2716
2717 /* Call text property handlers. */
2718 for (p = it_props; p->handler; ++p)
2719 {
2720 handled = p->handler (it);
2721
2722 if (handled == HANDLED_RECOMPUTE_PROPS)
2723 break;
2724 else if (handled == HANDLED_RETURN)
2725 return;
2726 else if (handled == HANDLED_OVERLAY_STRING_CONSUMED)
2727 handle_overlay_change_p = 0;
2728 }
2729
2730 if (handled != HANDLED_RECOMPUTE_PROPS)
2731 {
2732 /* Don't check for overlay strings below when set to deliver
2733 characters from a display vector. */
2734 if (it->method == GET_FROM_DISPLAY_VECTOR)
2735 handle_overlay_change_p = 0;
2736
2737 /* Handle overlay changes. */
2738 if (handle_overlay_change_p)
2739 handled = handle_overlay_change (it);
2740
2741 /* Determine where to stop next. */
2742 if (handled == HANDLED_NORMALLY)
2743 compute_stop_pos (it);
2744 }
2745 }
2746 while (handled == HANDLED_RECOMPUTE_PROPS);
2747 }
2748
2749
2750 /* Compute IT->stop_charpos from text property and overlay change
2751 information for IT's current position. */
2752
2753 static void
2754 compute_stop_pos (it)
2755 struct it *it;
2756 {
2757 register INTERVAL iv, next_iv;
2758 Lisp_Object object, limit, position;
2759
2760 /* If nowhere else, stop at the end. */
2761 it->stop_charpos = it->end_charpos;
2762
2763 if (STRINGP (it->string))
2764 {
2765 /* Strings are usually short, so don't limit the search for
2766 properties. */
2767 object = it->string;
2768 limit = Qnil;
2769 position = make_number (IT_STRING_CHARPOS (*it));
2770 }
2771 else
2772 {
2773 int charpos;
2774
2775 /* If next overlay change is in front of the current stop pos
2776 (which is IT->end_charpos), stop there. Note: value of
2777 next_overlay_change is point-max if no overlay change
2778 follows. */
2779 charpos = next_overlay_change (IT_CHARPOS (*it));
2780 if (charpos < it->stop_charpos)
2781 it->stop_charpos = charpos;
2782
2783 /* If showing the region, we have to stop at the region
2784 start or end because the face might change there. */
2785 if (it->region_beg_charpos > 0)
2786 {
2787 if (IT_CHARPOS (*it) < it->region_beg_charpos)
2788 it->stop_charpos = min (it->stop_charpos, it->region_beg_charpos);
2789 else if (IT_CHARPOS (*it) < it->region_end_charpos)
2790 it->stop_charpos = min (it->stop_charpos, it->region_end_charpos);
2791 }
2792
2793 /* Set up variables for computing the stop position from text
2794 property changes. */
2795 XSETBUFFER (object, current_buffer);
2796 limit = make_number (IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT);
2797 position = make_number (IT_CHARPOS (*it));
2798
2799 }
2800
2801 /* Get the interval containing IT's position. Value is a null
2802 interval if there isn't such an interval. */
2803 iv = validate_interval_range (object, &position, &position, 0);
2804 if (!NULL_INTERVAL_P (iv))
2805 {
2806 Lisp_Object values_here[LAST_PROP_IDX];
2807 struct props *p;
2808
2809 /* Get properties here. */
2810 for (p = it_props; p->handler; ++p)
2811 values_here[p->idx] = textget (iv->plist, *p->name);
2812
2813 /* Look for an interval following iv that has different
2814 properties. */
2815 for (next_iv = next_interval (iv);
2816 (!NULL_INTERVAL_P (next_iv)
2817 && (NILP (limit)
2818 || XFASTINT (limit) > next_iv->position));
2819 next_iv = next_interval (next_iv))
2820 {
2821 for (p = it_props; p->handler; ++p)
2822 {
2823 Lisp_Object new_value;
2824
2825 new_value = textget (next_iv->plist, *p->name);
2826 if (!EQ (values_here[p->idx], new_value))
2827 break;
2828 }
2829
2830 if (p->handler)
2831 break;
2832 }
2833
2834 if (!NULL_INTERVAL_P (next_iv))
2835 {
2836 if (INTEGERP (limit)
2837 && next_iv->position >= XFASTINT (limit))
2838 /* No text property change up to limit. */
2839 it->stop_charpos = min (XFASTINT (limit), it->stop_charpos);
2840 else
2841 /* Text properties change in next_iv. */
2842 it->stop_charpos = min (it->stop_charpos, next_iv->position);
2843 }
2844 }
2845
2846 xassert (STRINGP (it->string)
2847 || (it->stop_charpos >= BEGV
2848 && it->stop_charpos >= IT_CHARPOS (*it)));
2849 }
2850
2851
2852 /* Return the position of the next overlay change after POS in
2853 current_buffer. Value is point-max if no overlay change
2854 follows. This is like `next-overlay-change' but doesn't use
2855 xmalloc. */
2856
2857 static int
2858 next_overlay_change (pos)
2859 int pos;
2860 {
2861 int noverlays;
2862 int endpos;
2863 Lisp_Object *overlays;
2864 int i;
2865
2866 /* Get all overlays at the given position. */
2867 GET_OVERLAYS_AT (pos, overlays, noverlays, &endpos, 1);
2868
2869 /* If any of these overlays ends before endpos,
2870 use its ending point instead. */
2871 for (i = 0; i < noverlays; ++i)
2872 {
2873 Lisp_Object oend;
2874 int oendpos;
2875
2876 oend = OVERLAY_END (overlays[i]);
2877 oendpos = OVERLAY_POSITION (oend);
2878 endpos = min (endpos, oendpos);
2879 }
2880
2881 return endpos;
2882 }
2883
2884
2885 \f
2886 /***********************************************************************
2887 Fontification
2888 ***********************************************************************/
2889
2890 /* Handle changes in the `fontified' property of the current buffer by
2891 calling hook functions from Qfontification_functions to fontify
2892 regions of text. */
2893
2894 static enum prop_handled
2895 handle_fontified_prop (it)
2896 struct it *it;
2897 {
2898 Lisp_Object prop, pos;
2899 enum prop_handled handled = HANDLED_NORMALLY;
2900
2901 /* Get the value of the `fontified' property at IT's current buffer
2902 position. (The `fontified' property doesn't have a special
2903 meaning in strings.) If the value is nil, call functions from
2904 Qfontification_functions. */
2905 if (!STRINGP (it->string)
2906 && it->s == NULL
2907 && !NILP (Vfontification_functions)
2908 && !NILP (Vrun_hooks)
2909 && (pos = make_number (IT_CHARPOS (*it)),
2910 prop = Fget_char_property (pos, Qfontified, Qnil),
2911 NILP (prop)))
2912 {
2913 int count = SPECPDL_INDEX ();
2914 Lisp_Object val;
2915
2916 val = Vfontification_functions;
2917 specbind (Qfontification_functions, Qnil);
2918
2919 if (!CONSP (val) || EQ (XCAR (val), Qlambda))
2920 safe_call1 (val, pos);
2921 else
2922 {
2923 Lisp_Object globals, fn;
2924 struct gcpro gcpro1, gcpro2;
2925
2926 globals = Qnil;
2927 GCPRO2 (val, globals);
2928
2929 for (; CONSP (val); val = XCDR (val))
2930 {
2931 fn = XCAR (val);
2932
2933 if (EQ (fn, Qt))
2934 {
2935 /* A value of t indicates this hook has a local
2936 binding; it means to run the global binding too.
2937 In a global value, t should not occur. If it
2938 does, we must ignore it to avoid an endless
2939 loop. */
2940 for (globals = Fdefault_value (Qfontification_functions);
2941 CONSP (globals);
2942 globals = XCDR (globals))
2943 {
2944 fn = XCAR (globals);
2945 if (!EQ (fn, Qt))
2946 safe_call1 (fn, pos);
2947 }
2948 }
2949 else
2950 safe_call1 (fn, pos);
2951 }
2952
2953 UNGCPRO;
2954 }
2955
2956 unbind_to (count, Qnil);
2957
2958 /* Return HANDLED_RECOMPUTE_PROPS only if function fontified
2959 something. This avoids an endless loop if they failed to
2960 fontify the text for which reason ever. */
2961 if (!NILP (Fget_char_property (pos, Qfontified, Qnil)))
2962 handled = HANDLED_RECOMPUTE_PROPS;
2963 }
2964
2965 return handled;
2966 }
2967
2968
2969 \f
2970 /***********************************************************************
2971 Faces
2972 ***********************************************************************/
2973
2974 /* Set up iterator IT from face properties at its current position.
2975 Called from handle_stop. */
2976
2977 static enum prop_handled
2978 handle_face_prop (it)
2979 struct it *it;
2980 {
2981 int new_face_id, next_stop;
2982
2983 if (!STRINGP (it->string))
2984 {
2985 new_face_id
2986 = face_at_buffer_position (it->w,
2987 IT_CHARPOS (*it),
2988 it->region_beg_charpos,
2989 it->region_end_charpos,
2990 &next_stop,
2991 (IT_CHARPOS (*it)
2992 + TEXT_PROP_DISTANCE_LIMIT),
2993 0);
2994
2995 /* Is this a start of a run of characters with box face?
2996 Caveat: this can be called for a freshly initialized
2997 iterator; face_id is -1 in this case. We know that the new
2998 face will not change until limit, i.e. if the new face has a
2999 box, all characters up to limit will have one. But, as
3000 usual, we don't know whether limit is really the end. */
3001 if (new_face_id != it->face_id)
3002 {
3003 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3004
3005 /* If new face has a box but old face has not, this is
3006 the start of a run of characters with box, i.e. it has
3007 a shadow on the left side. The value of face_id of the
3008 iterator will be -1 if this is the initial call that gets
3009 the face. In this case, we have to look in front of IT's
3010 position and see whether there is a face != new_face_id. */
3011 it->start_of_box_run_p
3012 = (new_face->box != FACE_NO_BOX
3013 && (it->face_id >= 0
3014 || IT_CHARPOS (*it) == BEG
3015 || new_face_id != face_before_it_pos (it)));
3016 it->face_box_p = new_face->box != FACE_NO_BOX;
3017 }
3018 }
3019 else
3020 {
3021 int base_face_id, bufpos;
3022
3023 if (it->current.overlay_string_index >= 0)
3024 bufpos = IT_CHARPOS (*it);
3025 else
3026 bufpos = 0;
3027
3028 /* For strings from a buffer, i.e. overlay strings or strings
3029 from a `display' property, use the face at IT's current
3030 buffer position as the base face to merge with, so that
3031 overlay strings appear in the same face as surrounding
3032 text, unless they specify their own faces. */
3033 base_face_id = underlying_face_id (it);
3034
3035 new_face_id = face_at_string_position (it->w,
3036 it->string,
3037 IT_STRING_CHARPOS (*it),
3038 bufpos,
3039 it->region_beg_charpos,
3040 it->region_end_charpos,
3041 &next_stop,
3042 base_face_id, 0);
3043
3044 #if 0 /* This shouldn't be neccessary. Let's check it. */
3045 /* If IT is used to display a mode line we would really like to
3046 use the mode line face instead of the frame's default face. */
3047 if (it->glyph_row == MATRIX_MODE_LINE_ROW (it->w->desired_matrix)
3048 && new_face_id == DEFAULT_FACE_ID)
3049 new_face_id = CURRENT_MODE_LINE_FACE_ID (it->w);
3050 #endif
3051
3052 /* Is this a start of a run of characters with box? Caveat:
3053 this can be called for a freshly allocated iterator; face_id
3054 is -1 is this case. We know that the new face will not
3055 change until the next check pos, i.e. if the new face has a
3056 box, all characters up to that position will have a
3057 box. But, as usual, we don't know whether that position
3058 is really the end. */
3059 if (new_face_id != it->face_id)
3060 {
3061 struct face *new_face = FACE_FROM_ID (it->f, new_face_id);
3062 struct face *old_face = FACE_FROM_ID (it->f, it->face_id);
3063
3064 /* If new face has a box but old face hasn't, this is the
3065 start of a run of characters with box, i.e. it has a
3066 shadow on the left side. */
3067 it->start_of_box_run_p
3068 = new_face->box && (old_face == NULL || !old_face->box);
3069 it->face_box_p = new_face->box != FACE_NO_BOX;
3070 }
3071 }
3072
3073 it->face_id = new_face_id;
3074 return HANDLED_NORMALLY;
3075 }
3076
3077
3078 /* Return the ID of the face ``underlying'' IT's current position,
3079 which is in a string. If the iterator is associated with a
3080 buffer, return the face at IT's current buffer position.
3081 Otherwise, use the iterator's base_face_id. */
3082
3083 static int
3084 underlying_face_id (it)
3085 struct it *it;
3086 {
3087 int face_id = it->base_face_id, i;
3088
3089 xassert (STRINGP (it->string));
3090
3091 for (i = it->sp - 1; i >= 0; --i)
3092 if (NILP (it->stack[i].string))
3093 face_id = it->stack[i].face_id;
3094
3095 return face_id;
3096 }
3097
3098
3099 /* Compute the face one character before or after the current position
3100 of IT. BEFORE_P non-zero means get the face in front of IT's
3101 position. Value is the id of the face. */
3102
3103 static int
3104 face_before_or_after_it_pos (it, before_p)
3105 struct it *it;
3106 int before_p;
3107 {
3108 int face_id, limit;
3109 int next_check_charpos;
3110 struct text_pos pos;
3111
3112 xassert (it->s == NULL);
3113
3114 if (STRINGP (it->string))
3115 {
3116 int bufpos, base_face_id;
3117
3118 /* No face change past the end of the string (for the case
3119 we are padding with spaces). No face change before the
3120 string start. */
3121 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string)
3122 || (IT_STRING_CHARPOS (*it) == 0 && before_p))
3123 return it->face_id;
3124
3125 /* Set pos to the position before or after IT's current position. */
3126 if (before_p)
3127 pos = string_pos (IT_STRING_CHARPOS (*it) - 1, it->string);
3128 else
3129 /* For composition, we must check the character after the
3130 composition. */
3131 pos = (it->what == IT_COMPOSITION
3132 ? string_pos (IT_STRING_CHARPOS (*it) + it->cmp_len, it->string)
3133 : string_pos (IT_STRING_CHARPOS (*it) + 1, it->string));
3134
3135 if (it->current.overlay_string_index >= 0)
3136 bufpos = IT_CHARPOS (*it);
3137 else
3138 bufpos = 0;
3139
3140 base_face_id = underlying_face_id (it);
3141
3142 /* Get the face for ASCII, or unibyte. */
3143 face_id = face_at_string_position (it->w,
3144 it->string,
3145 CHARPOS (pos),
3146 bufpos,
3147 it->region_beg_charpos,
3148 it->region_end_charpos,
3149 &next_check_charpos,
3150 base_face_id, 0);
3151
3152 /* Correct the face for charsets different from ASCII. Do it
3153 for the multibyte case only. The face returned above is
3154 suitable for unibyte text if IT->string is unibyte. */
3155 if (STRING_MULTIBYTE (it->string))
3156 {
3157 const unsigned char *p = SDATA (it->string) + BYTEPOS (pos);
3158 int rest = SBYTES (it->string) - BYTEPOS (pos);
3159 int c, len;
3160 struct face *face = FACE_FROM_ID (it->f, face_id);
3161
3162 c = string_char_and_length (p, rest, &len);
3163 face_id = FACE_FOR_CHAR (it->f, face, c);
3164 }
3165 }
3166 else
3167 {
3168 if ((IT_CHARPOS (*it) >= ZV && !before_p)
3169 || (IT_CHARPOS (*it) <= BEGV && before_p))
3170 return it->face_id;
3171
3172 limit = IT_CHARPOS (*it) + TEXT_PROP_DISTANCE_LIMIT;
3173 pos = it->current.pos;
3174
3175 if (before_p)
3176 DEC_TEXT_POS (pos, it->multibyte_p);
3177 else
3178 {
3179 if (it->what == IT_COMPOSITION)
3180 /* For composition, we must check the position after the
3181 composition. */
3182 pos.charpos += it->cmp_len, pos.bytepos += it->len;
3183 else
3184 INC_TEXT_POS (pos, it->multibyte_p);
3185 }
3186
3187 /* Determine face for CHARSET_ASCII, or unibyte. */
3188 face_id = face_at_buffer_position (it->w,
3189 CHARPOS (pos),
3190 it->region_beg_charpos,
3191 it->region_end_charpos,
3192 &next_check_charpos,
3193 limit, 0);
3194
3195 /* Correct the face for charsets different from ASCII. Do it
3196 for the multibyte case only. The face returned above is
3197 suitable for unibyte text if current_buffer is unibyte. */
3198 if (it->multibyte_p)
3199 {
3200 int c = FETCH_MULTIBYTE_CHAR (BYTEPOS (pos));
3201 struct face *face = FACE_FROM_ID (it->f, face_id);
3202 face_id = FACE_FOR_CHAR (it->f, face, c);
3203 }
3204 }
3205
3206 return face_id;
3207 }
3208
3209
3210 \f
3211 /***********************************************************************
3212 Invisible text
3213 ***********************************************************************/
3214
3215 /* Set up iterator IT from invisible properties at its current
3216 position. Called from handle_stop. */
3217
3218 static enum prop_handled
3219 handle_invisible_prop (it)
3220 struct it *it;
3221 {
3222 enum prop_handled handled = HANDLED_NORMALLY;
3223
3224 if (STRINGP (it->string))
3225 {
3226 extern Lisp_Object Qinvisible;
3227 Lisp_Object prop, end_charpos, limit, charpos;
3228
3229 /* Get the value of the invisible text property at the
3230 current position. Value will be nil if there is no such
3231 property. */
3232 charpos = make_number (IT_STRING_CHARPOS (*it));
3233 prop = Fget_text_property (charpos, Qinvisible, it->string);
3234
3235 if (!NILP (prop)
3236 && IT_STRING_CHARPOS (*it) < it->end_charpos)
3237 {
3238 handled = HANDLED_RECOMPUTE_PROPS;
3239
3240 /* Get the position at which the next change of the
3241 invisible text property can be found in IT->string.
3242 Value will be nil if the property value is the same for
3243 all the rest of IT->string. */
3244 XSETINT (limit, SCHARS (it->string));
3245 end_charpos = Fnext_single_property_change (charpos, Qinvisible,
3246 it->string, limit);
3247
3248 /* Text at current position is invisible. The next
3249 change in the property is at position end_charpos.
3250 Move IT's current position to that position. */
3251 if (INTEGERP (end_charpos)
3252 && XFASTINT (end_charpos) < XFASTINT (limit))
3253 {
3254 struct text_pos old;
3255 old = it->current.string_pos;
3256 IT_STRING_CHARPOS (*it) = XFASTINT (end_charpos);
3257 compute_string_pos (&it->current.string_pos, old, it->string);
3258 }
3259 else
3260 {
3261 /* The rest of the string is invisible. If this is an
3262 overlay string, proceed with the next overlay string
3263 or whatever comes and return a character from there. */
3264 if (it->current.overlay_string_index >= 0)
3265 {
3266 next_overlay_string (it);
3267 /* Don't check for overlay strings when we just
3268 finished processing them. */
3269 handled = HANDLED_OVERLAY_STRING_CONSUMED;
3270 }
3271 else
3272 {
3273 IT_STRING_CHARPOS (*it) = SCHARS (it->string);
3274 IT_STRING_BYTEPOS (*it) = SBYTES (it->string);
3275 }
3276 }
3277 }
3278 }
3279 else
3280 {
3281 int invis_p, newpos, next_stop, start_charpos;
3282 Lisp_Object pos, prop, overlay;
3283
3284 /* First of all, is there invisible text at this position? */
3285 start_charpos = IT_CHARPOS (*it);
3286 pos = make_number (IT_CHARPOS (*it));
3287 prop = get_char_property_and_overlay (pos, Qinvisible, it->window,
3288 &overlay);
3289 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3290
3291 /* If we are on invisible text, skip over it. */
3292 if (invis_p && IT_CHARPOS (*it) < it->end_charpos)
3293 {
3294 /* Record whether we have to display an ellipsis for the
3295 invisible text. */
3296 int display_ellipsis_p = invis_p == 2;
3297
3298 handled = HANDLED_RECOMPUTE_PROPS;
3299
3300 /* Loop skipping over invisible text. The loop is left at
3301 ZV or with IT on the first char being visible again. */
3302 do
3303 {
3304 /* Try to skip some invisible text. Return value is the
3305 position reached which can be equal to IT's position
3306 if there is nothing invisible here. This skips both
3307 over invisible text properties and overlays with
3308 invisible property. */
3309 newpos = skip_invisible (IT_CHARPOS (*it),
3310 &next_stop, ZV, it->window);
3311
3312 /* If we skipped nothing at all we weren't at invisible
3313 text in the first place. If everything to the end of
3314 the buffer was skipped, end the loop. */
3315 if (newpos == IT_CHARPOS (*it) || newpos >= ZV)
3316 invis_p = 0;
3317 else
3318 {
3319 /* We skipped some characters but not necessarily
3320 all there are. Check if we ended up on visible
3321 text. Fget_char_property returns the property of
3322 the char before the given position, i.e. if we
3323 get invis_p = 0, this means that the char at
3324 newpos is visible. */
3325 pos = make_number (newpos);
3326 prop = Fget_char_property (pos, Qinvisible, it->window);
3327 invis_p = TEXT_PROP_MEANS_INVISIBLE (prop);
3328 }
3329
3330 /* If we ended up on invisible text, proceed to
3331 skip starting with next_stop. */
3332 if (invis_p)
3333 IT_CHARPOS (*it) = next_stop;
3334 }
3335 while (invis_p);
3336
3337 /* The position newpos is now either ZV or on visible text. */
3338 IT_CHARPOS (*it) = newpos;
3339 IT_BYTEPOS (*it) = CHAR_TO_BYTE (newpos);
3340
3341 /* If there are before-strings at the start of invisible
3342 text, and the text is invisible because of a text
3343 property, arrange to show before-strings because 20.x did
3344 it that way. (If the text is invisible because of an
3345 overlay property instead of a text property, this is
3346 already handled in the overlay code.) */
3347 if (NILP (overlay)
3348 && get_overlay_strings (it, start_charpos))
3349 {
3350 handled = HANDLED_RECOMPUTE_PROPS;
3351 it->stack[it->sp - 1].display_ellipsis_p = display_ellipsis_p;
3352 }
3353 else if (display_ellipsis_p)
3354 setup_for_ellipsis (it, 0);
3355 }
3356 }
3357
3358 return handled;
3359 }
3360
3361
3362 /* Make iterator IT return `...' next.
3363 Replaces LEN characters from buffer. */
3364
3365 static void
3366 setup_for_ellipsis (it, len)
3367 struct it *it;
3368 int len;
3369 {
3370 /* Use the display table definition for `...'. Invalid glyphs
3371 will be handled by the method returning elements from dpvec. */
3372 if (it->dp && VECTORP (DISP_INVIS_VECTOR (it->dp)))
3373 {
3374 struct Lisp_Vector *v = XVECTOR (DISP_INVIS_VECTOR (it->dp));
3375 it->dpvec = v->contents;
3376 it->dpend = v->contents + v->size;
3377 }
3378 else
3379 {
3380 /* Default `...'. */
3381 it->dpvec = default_invis_vector;
3382 it->dpend = default_invis_vector + 3;
3383 }
3384
3385 it->dpvec_char_len = len;
3386 it->current.dpvec_index = 0;
3387 it->dpvec_face_id = -1;
3388
3389 /* Remember the current face id in case glyphs specify faces.
3390 IT's face is restored in set_iterator_to_next.
3391 saved_face_id was set to preceding char's face in handle_stop. */
3392 if (it->saved_face_id < 0 || it->saved_face_id != it->face_id)
3393 it->saved_face_id = it->face_id = DEFAULT_FACE_ID;
3394
3395 it->method = GET_FROM_DISPLAY_VECTOR;
3396 it->ellipsis_p = 1;
3397 }
3398
3399
3400 \f
3401 /***********************************************************************
3402 'display' property
3403 ***********************************************************************/
3404
3405 /* Set up iterator IT from `display' property at its current position.
3406 Called from handle_stop.
3407 We return HANDLED_RETURN if some part of the display property
3408 overrides the display of the buffer text itself.
3409 Otherwise we return HANDLED_NORMALLY. */
3410
3411 static enum prop_handled
3412 handle_display_prop (it)
3413 struct it *it;
3414 {
3415 Lisp_Object prop, object;
3416 struct text_pos *position;
3417 /* Nonzero if some property replaces the display of the text itself. */
3418 int display_replaced_p = 0;
3419
3420 if (STRINGP (it->string))
3421 {
3422 object = it->string;
3423 position = &it->current.string_pos;
3424 }
3425 else
3426 {
3427 object = it->w->buffer;
3428 position = &it->current.pos;
3429 }
3430
3431 /* Reset those iterator values set from display property values. */
3432 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
3433 it->space_width = Qnil;
3434 it->font_height = Qnil;
3435 it->voffset = 0;
3436
3437 /* We don't support recursive `display' properties, i.e. string
3438 values that have a string `display' property, that have a string
3439 `display' property etc. */
3440 if (!it->string_from_display_prop_p)
3441 it->area = TEXT_AREA;
3442
3443 prop = Fget_char_property (make_number (position->charpos),
3444 Qdisplay, object);
3445 if (NILP (prop))
3446 return HANDLED_NORMALLY;
3447
3448 if (CONSP (prop)
3449 /* Simple properties. */
3450 && !EQ (XCAR (prop), Qimage)
3451 && !EQ (XCAR (prop), Qspace)
3452 && !EQ (XCAR (prop), Qwhen)
3453 && !EQ (XCAR (prop), Qslice)
3454 && !EQ (XCAR (prop), Qspace_width)
3455 && !EQ (XCAR (prop), Qheight)
3456 && !EQ (XCAR (prop), Qraise)
3457 /* Marginal area specifications. */
3458 && !(CONSP (XCAR (prop)) && EQ (XCAR (XCAR (prop)), Qmargin))
3459 && !EQ (XCAR (prop), Qleft_fringe)
3460 && !EQ (XCAR (prop), Qright_fringe)
3461 && !NILP (XCAR (prop)))
3462 {
3463 for (; CONSP (prop); prop = XCDR (prop))
3464 {
3465 if (handle_single_display_spec (it, XCAR (prop), object,
3466 position, display_replaced_p))
3467 display_replaced_p = 1;
3468 }
3469 }
3470 else if (VECTORP (prop))
3471 {
3472 int i;
3473 for (i = 0; i < ASIZE (prop); ++i)
3474 if (handle_single_display_spec (it, AREF (prop, i), object,
3475 position, display_replaced_p))
3476 display_replaced_p = 1;
3477 }
3478 else
3479 {
3480 int ret = handle_single_display_spec (it, prop, object, position, 0);
3481 if (ret < 0) /* Replaced by "", i.e. nothing. */
3482 return HANDLED_RECOMPUTE_PROPS;
3483 if (ret)
3484 display_replaced_p = 1;
3485 }
3486
3487 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3488 }
3489
3490
3491 /* Value is the position of the end of the `display' property starting
3492 at START_POS in OBJECT. */
3493
3494 static struct text_pos
3495 display_prop_end (it, object, start_pos)
3496 struct it *it;
3497 Lisp_Object object;
3498 struct text_pos start_pos;
3499 {
3500 Lisp_Object end;
3501 struct text_pos end_pos;
3502
3503 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3504 Qdisplay, object, Qnil);
3505 CHARPOS (end_pos) = XFASTINT (end);
3506 if (STRINGP (object))
3507 compute_string_pos (&end_pos, start_pos, it->string);
3508 else
3509 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3510
3511 return end_pos;
3512 }
3513
3514
3515 /* Set up IT from a single `display' specification PROP. OBJECT
3516 is the object in which the `display' property was found. *POSITION
3517 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3518 means that we previously saw a display specification which already
3519 replaced text display with something else, for example an image;
3520 we ignore such properties after the first one has been processed.
3521
3522 If PROP is a `space' or `image' specification, and in some other
3523 cases too, set *POSITION to the position where the `display'
3524 property ends.
3525
3526 Value is non-zero if something was found which replaces the display
3527 of buffer or string text. Specifically, the value is -1 if that
3528 "something" is "nothing". */
3529
3530 static int
3531 handle_single_display_spec (it, spec, object, position,
3532 display_replaced_before_p)
3533 struct it *it;
3534 Lisp_Object spec;
3535 Lisp_Object object;
3536 struct text_pos *position;
3537 int display_replaced_before_p;
3538 {
3539 Lisp_Object form;
3540 Lisp_Object location, value;
3541 struct text_pos start_pos;
3542 int valid_p;
3543
3544 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3545 If the result is non-nil, use VALUE instead of SPEC. */
3546 form = Qt;
3547 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3548 {
3549 spec = XCDR (spec);
3550 if (!CONSP (spec))
3551 return 0;
3552 form = XCAR (spec);
3553 spec = XCDR (spec);
3554 }
3555
3556 if (!NILP (form) && !EQ (form, Qt))
3557 {
3558 int count = SPECPDL_INDEX ();
3559 struct gcpro gcpro1;
3560
3561 /* Bind `object' to the object having the `display' property, a
3562 buffer or string. Bind `position' to the position in the
3563 object where the property was found, and `buffer-position'
3564 to the current position in the buffer. */
3565 specbind (Qobject, object);
3566 specbind (Qposition, make_number (CHARPOS (*position)));
3567 specbind (Qbuffer_position,
3568 make_number (STRINGP (object)
3569 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3570 GCPRO1 (form);
3571 form = safe_eval (form);
3572 UNGCPRO;
3573 unbind_to (count, Qnil);
3574 }
3575
3576 if (NILP (form))
3577 return 0;
3578
3579 /* Handle `(height HEIGHT)' specifications. */
3580 if (CONSP (spec)
3581 && EQ (XCAR (spec), Qheight)
3582 && CONSP (XCDR (spec)))
3583 {
3584 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3585 return 0;
3586
3587 it->font_height = XCAR (XCDR (spec));
3588 if (!NILP (it->font_height))
3589 {
3590 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3591 int new_height = -1;
3592
3593 if (CONSP (it->font_height)
3594 && (EQ (XCAR (it->font_height), Qplus)
3595 || EQ (XCAR (it->font_height), Qminus))
3596 && CONSP (XCDR (it->font_height))
3597 && INTEGERP (XCAR (XCDR (it->font_height))))
3598 {
3599 /* `(+ N)' or `(- N)' where N is an integer. */
3600 int steps = XINT (XCAR (XCDR (it->font_height)));
3601 if (EQ (XCAR (it->font_height), Qplus))
3602 steps = - steps;
3603 it->face_id = smaller_face (it->f, it->face_id, steps);
3604 }
3605 else if (FUNCTIONP (it->font_height))
3606 {
3607 /* Call function with current height as argument.
3608 Value is the new height. */
3609 Lisp_Object height;
3610 height = safe_call1 (it->font_height,
3611 face->lface[LFACE_HEIGHT_INDEX]);
3612 if (NUMBERP (height))
3613 new_height = XFLOATINT (height);
3614 }
3615 else if (NUMBERP (it->font_height))
3616 {
3617 /* Value is a multiple of the canonical char height. */
3618 struct face *face;
3619
3620 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3621 new_height = (XFLOATINT (it->font_height)
3622 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3623 }
3624 else
3625 {
3626 /* Evaluate IT->font_height with `height' bound to the
3627 current specified height to get the new height. */
3628 int count = SPECPDL_INDEX ();
3629
3630 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3631 value = safe_eval (it->font_height);
3632 unbind_to (count, Qnil);
3633
3634 if (NUMBERP (value))
3635 new_height = XFLOATINT (value);
3636 }
3637
3638 if (new_height > 0)
3639 it->face_id = face_with_height (it->f, it->face_id, new_height);
3640 }
3641
3642 return 0;
3643 }
3644
3645 /* Handle `(space_width WIDTH)'. */
3646 if (CONSP (spec)
3647 && EQ (XCAR (spec), Qspace_width)
3648 && CONSP (XCDR (spec)))
3649 {
3650 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3651 return 0;
3652
3653 value = XCAR (XCDR (spec));
3654 if (NUMBERP (value) && XFLOATINT (value) > 0)
3655 it->space_width = value;
3656
3657 return 0;
3658 }
3659
3660 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3661 if (CONSP (spec)
3662 && EQ (XCAR (spec), Qslice))
3663 {
3664 Lisp_Object tem;
3665
3666 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3667 return 0;
3668
3669 if (tem = XCDR (spec), CONSP (tem))
3670 {
3671 it->slice.x = XCAR (tem);
3672 if (tem = XCDR (tem), CONSP (tem))
3673 {
3674 it->slice.y = XCAR (tem);
3675 if (tem = XCDR (tem), CONSP (tem))
3676 {
3677 it->slice.width = XCAR (tem);
3678 if (tem = XCDR (tem), CONSP (tem))
3679 it->slice.height = XCAR (tem);
3680 }
3681 }
3682 }
3683
3684 return 0;
3685 }
3686
3687 /* Handle `(raise FACTOR)'. */
3688 if (CONSP (spec)
3689 && EQ (XCAR (spec), Qraise)
3690 && CONSP (XCDR (spec)))
3691 {
3692 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3693 return 0;
3694
3695 #ifdef HAVE_WINDOW_SYSTEM
3696 value = XCAR (XCDR (spec));
3697 if (NUMBERP (value))
3698 {
3699 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3700 it->voffset = - (XFLOATINT (value)
3701 * (FONT_HEIGHT (face->font)));
3702 }
3703 #endif /* HAVE_WINDOW_SYSTEM */
3704
3705 return 0;
3706 }
3707
3708 /* Don't handle the other kinds of display specifications
3709 inside a string that we got from a `display' property. */
3710 if (it->string_from_display_prop_p)
3711 return 0;
3712
3713 /* Characters having this form of property are not displayed, so
3714 we have to find the end of the property. */
3715 start_pos = *position;
3716 *position = display_prop_end (it, object, start_pos);
3717 value = Qnil;
3718
3719 /* Stop the scan at that end position--we assume that all
3720 text properties change there. */
3721 it->stop_charpos = position->charpos;
3722
3723 /* Handle `(left-fringe BITMAP [FACE])'
3724 and `(right-fringe BITMAP [FACE])'. */
3725 if (CONSP (spec)
3726 && (EQ (XCAR (spec), Qleft_fringe)
3727 || EQ (XCAR (spec), Qright_fringe))
3728 && CONSP (XCDR (spec)))
3729 {
3730 int face_id = DEFAULT_FACE_ID;
3731 int fringe_bitmap;
3732
3733 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3734 /* If we return here, POSITION has been advanced
3735 across the text with this property. */
3736 return 0;
3737
3738 #ifdef HAVE_WINDOW_SYSTEM
3739 value = XCAR (XCDR (spec));
3740 if (!SYMBOLP (value)
3741 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3742 /* If we return here, POSITION has been advanced
3743 across the text with this property. */
3744 return 0;
3745
3746 if (CONSP (XCDR (XCDR (spec))))
3747 {
3748 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
3749 int face_id2 = lookup_derived_face (it->f, face_name,
3750 'A', FRINGE_FACE_ID, 0);
3751 if (face_id2 >= 0)
3752 face_id = face_id2;
3753 }
3754
3755 /* Save current settings of IT so that we can restore them
3756 when we are finished with the glyph property value. */
3757
3758 push_it (it);
3759
3760 it->area = TEXT_AREA;
3761 it->what = IT_IMAGE;
3762 it->image_id = -1; /* no image */
3763 it->position = start_pos;
3764 it->object = NILP (object) ? it->w->buffer : object;
3765 it->method = GET_FROM_IMAGE;
3766 it->face_id = face_id;
3767
3768 /* Say that we haven't consumed the characters with
3769 `display' property yet. The call to pop_it in
3770 set_iterator_to_next will clean this up. */
3771 *position = start_pos;
3772
3773 if (EQ (XCAR (spec), Qleft_fringe))
3774 {
3775 it->left_user_fringe_bitmap = fringe_bitmap;
3776 it->left_user_fringe_face_id = face_id;
3777 }
3778 else
3779 {
3780 it->right_user_fringe_bitmap = fringe_bitmap;
3781 it->right_user_fringe_face_id = face_id;
3782 }
3783 #endif /* HAVE_WINDOW_SYSTEM */
3784 return 1;
3785 }
3786
3787 /* Prepare to handle `((margin left-margin) ...)',
3788 `((margin right-margin) ...)' and `((margin nil) ...)'
3789 prefixes for display specifications. */
3790 location = Qunbound;
3791 if (CONSP (spec) && CONSP (XCAR (spec)))
3792 {
3793 Lisp_Object tem;
3794
3795 value = XCDR (spec);
3796 if (CONSP (value))
3797 value = XCAR (value);
3798
3799 tem = XCAR (spec);
3800 if (EQ (XCAR (tem), Qmargin)
3801 && (tem = XCDR (tem),
3802 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3803 (NILP (tem)
3804 || EQ (tem, Qleft_margin)
3805 || EQ (tem, Qright_margin))))
3806 location = tem;
3807 }
3808
3809 if (EQ (location, Qunbound))
3810 {
3811 location = Qnil;
3812 value = spec;
3813 }
3814
3815 /* After this point, VALUE is the property after any
3816 margin prefix has been stripped. It must be a string,
3817 an image specification, or `(space ...)'.
3818
3819 LOCATION specifies where to display: `left-margin',
3820 `right-margin' or nil. */
3821
3822 valid_p = (STRINGP (value)
3823 #ifdef HAVE_WINDOW_SYSTEM
3824 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3825 #endif /* not HAVE_WINDOW_SYSTEM */
3826 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3827
3828 if (valid_p && !display_replaced_before_p)
3829 {
3830 /* Save current settings of IT so that we can restore them
3831 when we are finished with the glyph property value. */
3832 push_it (it);
3833
3834 if (NILP (location))
3835 it->area = TEXT_AREA;
3836 else if (EQ (location, Qleft_margin))
3837 it->area = LEFT_MARGIN_AREA;
3838 else
3839 it->area = RIGHT_MARGIN_AREA;
3840
3841 if (STRINGP (value))
3842 {
3843 if (SCHARS (value) == 0)
3844 {
3845 pop_it (it);
3846 return -1; /* Replaced by "", i.e. nothing. */
3847 }
3848 it->string = value;
3849 it->multibyte_p = STRING_MULTIBYTE (it->string);
3850 it->current.overlay_string_index = -1;
3851 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3852 it->end_charpos = it->string_nchars = SCHARS (it->string);
3853 it->method = GET_FROM_STRING;
3854 it->stop_charpos = 0;
3855 it->string_from_display_prop_p = 1;
3856 /* Say that we haven't consumed the characters with
3857 `display' property yet. The call to pop_it in
3858 set_iterator_to_next will clean this up. */
3859 *position = start_pos;
3860 }
3861 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3862 {
3863 it->method = GET_FROM_STRETCH;
3864 it->object = value;
3865 it->current.pos = it->position = start_pos;
3866 }
3867 #ifdef HAVE_WINDOW_SYSTEM
3868 else
3869 {
3870 it->what = IT_IMAGE;
3871 it->image_id = lookup_image (it->f, value);
3872 it->position = start_pos;
3873 it->object = NILP (object) ? it->w->buffer : object;
3874 it->method = GET_FROM_IMAGE;
3875
3876 /* Say that we haven't consumed the characters with
3877 `display' property yet. The call to pop_it in
3878 set_iterator_to_next will clean this up. */
3879 *position = start_pos;
3880 }
3881 #endif /* HAVE_WINDOW_SYSTEM */
3882
3883 return 1;
3884 }
3885
3886 /* Invalid property or property not supported. Restore
3887 POSITION to what it was before. */
3888 *position = start_pos;
3889 return 0;
3890 }
3891
3892
3893 /* Check if SPEC is a display specification value whose text should be
3894 treated as intangible. */
3895
3896 static int
3897 single_display_spec_intangible_p (prop)
3898 Lisp_Object prop;
3899 {
3900 /* Skip over `when FORM'. */
3901 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3902 {
3903 prop = XCDR (prop);
3904 if (!CONSP (prop))
3905 return 0;
3906 prop = XCDR (prop);
3907 }
3908
3909 if (STRINGP (prop))
3910 return 1;
3911
3912 if (!CONSP (prop))
3913 return 0;
3914
3915 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3916 we don't need to treat text as intangible. */
3917 if (EQ (XCAR (prop), Qmargin))
3918 {
3919 prop = XCDR (prop);
3920 if (!CONSP (prop))
3921 return 0;
3922
3923 prop = XCDR (prop);
3924 if (!CONSP (prop)
3925 || EQ (XCAR (prop), Qleft_margin)
3926 || EQ (XCAR (prop), Qright_margin))
3927 return 0;
3928 }
3929
3930 return (CONSP (prop)
3931 && (EQ (XCAR (prop), Qimage)
3932 || EQ (XCAR (prop), Qspace)));
3933 }
3934
3935
3936 /* Check if PROP is a display property value whose text should be
3937 treated as intangible. */
3938
3939 int
3940 display_prop_intangible_p (prop)
3941 Lisp_Object prop;
3942 {
3943 if (CONSP (prop)
3944 && CONSP (XCAR (prop))
3945 && !EQ (Qmargin, XCAR (XCAR (prop))))
3946 {
3947 /* A list of sub-properties. */
3948 while (CONSP (prop))
3949 {
3950 if (single_display_spec_intangible_p (XCAR (prop)))
3951 return 1;
3952 prop = XCDR (prop);
3953 }
3954 }
3955 else if (VECTORP (prop))
3956 {
3957 /* A vector of sub-properties. */
3958 int i;
3959 for (i = 0; i < ASIZE (prop); ++i)
3960 if (single_display_spec_intangible_p (AREF (prop, i)))
3961 return 1;
3962 }
3963 else
3964 return single_display_spec_intangible_p (prop);
3965
3966 return 0;
3967 }
3968
3969
3970 /* Return 1 if PROP is a display sub-property value containing STRING. */
3971
3972 static int
3973 single_display_spec_string_p (prop, string)
3974 Lisp_Object prop, string;
3975 {
3976 if (EQ (string, prop))
3977 return 1;
3978
3979 /* Skip over `when FORM'. */
3980 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3981 {
3982 prop = XCDR (prop);
3983 if (!CONSP (prop))
3984 return 0;
3985 prop = XCDR (prop);
3986 }
3987
3988 if (CONSP (prop))
3989 /* Skip over `margin LOCATION'. */
3990 if (EQ (XCAR (prop), Qmargin))
3991 {
3992 prop = XCDR (prop);
3993 if (!CONSP (prop))
3994 return 0;
3995
3996 prop = XCDR (prop);
3997 if (!CONSP (prop))
3998 return 0;
3999 }
4000
4001 return CONSP (prop) && EQ (XCAR (prop), string);
4002 }
4003
4004
4005 /* Return 1 if STRING appears in the `display' property PROP. */
4006
4007 static int
4008 display_prop_string_p (prop, string)
4009 Lisp_Object prop, string;
4010 {
4011 if (CONSP (prop)
4012 && CONSP (XCAR (prop))
4013 && !EQ (Qmargin, XCAR (XCAR (prop))))
4014 {
4015 /* A list of sub-properties. */
4016 while (CONSP (prop))
4017 {
4018 if (single_display_spec_string_p (XCAR (prop), string))
4019 return 1;
4020 prop = XCDR (prop);
4021 }
4022 }
4023 else if (VECTORP (prop))
4024 {
4025 /* A vector of sub-properties. */
4026 int i;
4027 for (i = 0; i < ASIZE (prop); ++i)
4028 if (single_display_spec_string_p (AREF (prop, i), string))
4029 return 1;
4030 }
4031 else
4032 return single_display_spec_string_p (prop, string);
4033
4034 return 0;
4035 }
4036
4037
4038 /* Determine from which buffer position in W's buffer STRING comes
4039 from. AROUND_CHARPOS is an approximate position where it could
4040 be from. Value is the buffer position or 0 if it couldn't be
4041 determined.
4042
4043 W's buffer must be current.
4044
4045 This function is necessary because we don't record buffer positions
4046 in glyphs generated from strings (to keep struct glyph small).
4047 This function may only use code that doesn't eval because it is
4048 called asynchronously from note_mouse_highlight. */
4049
4050 int
4051 string_buffer_position (w, string, around_charpos)
4052 struct window *w;
4053 Lisp_Object string;
4054 int around_charpos;
4055 {
4056 Lisp_Object limit, prop, pos;
4057 const int MAX_DISTANCE = 1000;
4058 int found = 0;
4059
4060 pos = make_number (around_charpos);
4061 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4062 while (!found && !EQ (pos, limit))
4063 {
4064 prop = Fget_char_property (pos, Qdisplay, Qnil);
4065 if (!NILP (prop) && display_prop_string_p (prop, string))
4066 found = 1;
4067 else
4068 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4069 }
4070
4071 if (!found)
4072 {
4073 pos = make_number (around_charpos);
4074 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4075 while (!found && !EQ (pos, limit))
4076 {
4077 prop = Fget_char_property (pos, Qdisplay, Qnil);
4078 if (!NILP (prop) && display_prop_string_p (prop, string))
4079 found = 1;
4080 else
4081 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4082 limit);
4083 }
4084 }
4085
4086 return found ? XINT (pos) : 0;
4087 }
4088
4089
4090 \f
4091 /***********************************************************************
4092 `composition' property
4093 ***********************************************************************/
4094
4095 /* Set up iterator IT from `composition' property at its current
4096 position. Called from handle_stop. */
4097
4098 static enum prop_handled
4099 handle_composition_prop (it)
4100 struct it *it;
4101 {
4102 Lisp_Object prop, string;
4103 int pos, pos_byte, end;
4104 enum prop_handled handled = HANDLED_NORMALLY;
4105
4106 if (STRINGP (it->string))
4107 {
4108 pos = IT_STRING_CHARPOS (*it);
4109 pos_byte = IT_STRING_BYTEPOS (*it);
4110 string = it->string;
4111 }
4112 else
4113 {
4114 pos = IT_CHARPOS (*it);
4115 pos_byte = IT_BYTEPOS (*it);
4116 string = Qnil;
4117 }
4118
4119 /* If there's a valid composition and point is not inside of the
4120 composition (in the case that the composition is from the current
4121 buffer), draw a glyph composed from the composition components. */
4122 if (find_composition (pos, -1, &pos, &end, &prop, string)
4123 && COMPOSITION_VALID_P (pos, end, prop)
4124 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4125 {
4126 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4127
4128 if (id >= 0)
4129 {
4130 it->method = GET_FROM_COMPOSITION;
4131 it->cmp_id = id;
4132 it->cmp_len = COMPOSITION_LENGTH (prop);
4133 /* For a terminal, draw only the first character of the
4134 components. */
4135 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4136 it->len = (STRINGP (it->string)
4137 ? string_char_to_byte (it->string, end)
4138 : CHAR_TO_BYTE (end)) - pos_byte;
4139 it->stop_charpos = end;
4140 handled = HANDLED_RETURN;
4141 }
4142 }
4143
4144 return handled;
4145 }
4146
4147
4148 \f
4149 /***********************************************************************
4150 Overlay strings
4151 ***********************************************************************/
4152
4153 /* The following structure is used to record overlay strings for
4154 later sorting in load_overlay_strings. */
4155
4156 struct overlay_entry
4157 {
4158 Lisp_Object overlay;
4159 Lisp_Object string;
4160 int priority;
4161 int after_string_p;
4162 };
4163
4164
4165 /* Set up iterator IT from overlay strings at its current position.
4166 Called from handle_stop. */
4167
4168 static enum prop_handled
4169 handle_overlay_change (it)
4170 struct it *it;
4171 {
4172 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4173 return HANDLED_RECOMPUTE_PROPS;
4174 else
4175 return HANDLED_NORMALLY;
4176 }
4177
4178
4179 /* Set up the next overlay string for delivery by IT, if there is an
4180 overlay string to deliver. Called by set_iterator_to_next when the
4181 end of the current overlay string is reached. If there are more
4182 overlay strings to display, IT->string and
4183 IT->current.overlay_string_index are set appropriately here.
4184 Otherwise IT->string is set to nil. */
4185
4186 static void
4187 next_overlay_string (it)
4188 struct it *it;
4189 {
4190 ++it->current.overlay_string_index;
4191 if (it->current.overlay_string_index == it->n_overlay_strings)
4192 {
4193 /* No more overlay strings. Restore IT's settings to what
4194 they were before overlay strings were processed, and
4195 continue to deliver from current_buffer. */
4196 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4197
4198 pop_it (it);
4199 xassert (it->stop_charpos >= BEGV
4200 && it->stop_charpos <= it->end_charpos);
4201 it->string = Qnil;
4202 it->current.overlay_string_index = -1;
4203 SET_TEXT_POS (it->current.string_pos, -1, -1);
4204 it->n_overlay_strings = 0;
4205 it->method = GET_FROM_BUFFER;
4206
4207 /* If we're at the end of the buffer, record that we have
4208 processed the overlay strings there already, so that
4209 next_element_from_buffer doesn't try it again. */
4210 if (IT_CHARPOS (*it) >= it->end_charpos)
4211 it->overlay_strings_at_end_processed_p = 1;
4212
4213 /* If we have to display `...' for invisible text, set
4214 the iterator up for that. */
4215 if (display_ellipsis_p)
4216 setup_for_ellipsis (it, 0);
4217 }
4218 else
4219 {
4220 /* There are more overlay strings to process. If
4221 IT->current.overlay_string_index has advanced to a position
4222 where we must load IT->overlay_strings with more strings, do
4223 it. */
4224 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4225
4226 if (it->current.overlay_string_index && i == 0)
4227 load_overlay_strings (it, 0);
4228
4229 /* Initialize IT to deliver display elements from the overlay
4230 string. */
4231 it->string = it->overlay_strings[i];
4232 it->multibyte_p = STRING_MULTIBYTE (it->string);
4233 SET_TEXT_POS (it->current.string_pos, 0, 0);
4234 it->method = GET_FROM_STRING;
4235 it->stop_charpos = 0;
4236 }
4237
4238 CHECK_IT (it);
4239 }
4240
4241
4242 /* Compare two overlay_entry structures E1 and E2. Used as a
4243 comparison function for qsort in load_overlay_strings. Overlay
4244 strings for the same position are sorted so that
4245
4246 1. All after-strings come in front of before-strings, except
4247 when they come from the same overlay.
4248
4249 2. Within after-strings, strings are sorted so that overlay strings
4250 from overlays with higher priorities come first.
4251
4252 2. Within before-strings, strings are sorted so that overlay
4253 strings from overlays with higher priorities come last.
4254
4255 Value is analogous to strcmp. */
4256
4257
4258 static int
4259 compare_overlay_entries (e1, e2)
4260 void *e1, *e2;
4261 {
4262 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4263 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4264 int result;
4265
4266 if (entry1->after_string_p != entry2->after_string_p)
4267 {
4268 /* Let after-strings appear in front of before-strings if
4269 they come from different overlays. */
4270 if (EQ (entry1->overlay, entry2->overlay))
4271 result = entry1->after_string_p ? 1 : -1;
4272 else
4273 result = entry1->after_string_p ? -1 : 1;
4274 }
4275 else if (entry1->after_string_p)
4276 /* After-strings sorted in order of decreasing priority. */
4277 result = entry2->priority - entry1->priority;
4278 else
4279 /* Before-strings sorted in order of increasing priority. */
4280 result = entry1->priority - entry2->priority;
4281
4282 return result;
4283 }
4284
4285
4286 /* Load the vector IT->overlay_strings with overlay strings from IT's
4287 current buffer position, or from CHARPOS if that is > 0. Set
4288 IT->n_overlays to the total number of overlay strings found.
4289
4290 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4291 a time. On entry into load_overlay_strings,
4292 IT->current.overlay_string_index gives the number of overlay
4293 strings that have already been loaded by previous calls to this
4294 function.
4295
4296 IT->add_overlay_start contains an additional overlay start
4297 position to consider for taking overlay strings from, if non-zero.
4298 This position comes into play when the overlay has an `invisible'
4299 property, and both before and after-strings. When we've skipped to
4300 the end of the overlay, because of its `invisible' property, we
4301 nevertheless want its before-string to appear.
4302 IT->add_overlay_start will contain the overlay start position
4303 in this case.
4304
4305 Overlay strings are sorted so that after-string strings come in
4306 front of before-string strings. Within before and after-strings,
4307 strings are sorted by overlay priority. See also function
4308 compare_overlay_entries. */
4309
4310 static void
4311 load_overlay_strings (it, charpos)
4312 struct it *it;
4313 int charpos;
4314 {
4315 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4316 Lisp_Object overlay, window, str, invisible;
4317 struct Lisp_Overlay *ov;
4318 int start, end;
4319 int size = 20;
4320 int n = 0, i, j, invis_p;
4321 struct overlay_entry *entries
4322 = (struct overlay_entry *) alloca (size * sizeof *entries);
4323
4324 if (charpos <= 0)
4325 charpos = IT_CHARPOS (*it);
4326
4327 /* Append the overlay string STRING of overlay OVERLAY to vector
4328 `entries' which has size `size' and currently contains `n'
4329 elements. AFTER_P non-zero means STRING is an after-string of
4330 OVERLAY. */
4331 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4332 do \
4333 { \
4334 Lisp_Object priority; \
4335 \
4336 if (n == size) \
4337 { \
4338 int new_size = 2 * size; \
4339 struct overlay_entry *old = entries; \
4340 entries = \
4341 (struct overlay_entry *) alloca (new_size \
4342 * sizeof *entries); \
4343 bcopy (old, entries, size * sizeof *entries); \
4344 size = new_size; \
4345 } \
4346 \
4347 entries[n].string = (STRING); \
4348 entries[n].overlay = (OVERLAY); \
4349 priority = Foverlay_get ((OVERLAY), Qpriority); \
4350 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4351 entries[n].after_string_p = (AFTER_P); \
4352 ++n; \
4353 } \
4354 while (0)
4355
4356 /* Process overlay before the overlay center. */
4357 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4358 {
4359 XSETMISC (overlay, ov);
4360 xassert (OVERLAYP (overlay));
4361 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4362 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4363
4364 if (end < charpos)
4365 break;
4366
4367 /* Skip this overlay if it doesn't start or end at IT's current
4368 position. */
4369 if (end != charpos && start != charpos)
4370 continue;
4371
4372 /* Skip this overlay if it doesn't apply to IT->w. */
4373 window = Foverlay_get (overlay, Qwindow);
4374 if (WINDOWP (window) && XWINDOW (window) != it->w)
4375 continue;
4376
4377 /* If the text ``under'' the overlay is invisible, both before-
4378 and after-strings from this overlay are visible; start and
4379 end position are indistinguishable. */
4380 invisible = Foverlay_get (overlay, Qinvisible);
4381 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4382
4383 /* If overlay has a non-empty before-string, record it. */
4384 if ((start == charpos || (end == charpos && invis_p))
4385 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4386 && SCHARS (str))
4387 RECORD_OVERLAY_STRING (overlay, str, 0);
4388
4389 /* If overlay has a non-empty after-string, record it. */
4390 if ((end == charpos || (start == charpos && invis_p))
4391 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4392 && SCHARS (str))
4393 RECORD_OVERLAY_STRING (overlay, str, 1);
4394 }
4395
4396 /* Process overlays after the overlay center. */
4397 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4398 {
4399 XSETMISC (overlay, ov);
4400 xassert (OVERLAYP (overlay));
4401 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4402 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4403
4404 if (start > charpos)
4405 break;
4406
4407 /* Skip this overlay if it doesn't start or end at IT's current
4408 position. */
4409 if (end != charpos && start != charpos)
4410 continue;
4411
4412 /* Skip this overlay if it doesn't apply to IT->w. */
4413 window = Foverlay_get (overlay, Qwindow);
4414 if (WINDOWP (window) && XWINDOW (window) != it->w)
4415 continue;
4416
4417 /* If the text ``under'' the overlay is invisible, it has a zero
4418 dimension, and both before- and after-strings apply. */
4419 invisible = Foverlay_get (overlay, Qinvisible);
4420 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4421
4422 /* If overlay has a non-empty before-string, record it. */
4423 if ((start == charpos || (end == charpos && invis_p))
4424 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4425 && SCHARS (str))
4426 RECORD_OVERLAY_STRING (overlay, str, 0);
4427
4428 /* If overlay has a non-empty after-string, record it. */
4429 if ((end == charpos || (start == charpos && invis_p))
4430 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4431 && SCHARS (str))
4432 RECORD_OVERLAY_STRING (overlay, str, 1);
4433 }
4434
4435 #undef RECORD_OVERLAY_STRING
4436
4437 /* Sort entries. */
4438 if (n > 1)
4439 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4440
4441 /* Record the total number of strings to process. */
4442 it->n_overlay_strings = n;
4443
4444 /* IT->current.overlay_string_index is the number of overlay strings
4445 that have already been consumed by IT. Copy some of the
4446 remaining overlay strings to IT->overlay_strings. */
4447 i = 0;
4448 j = it->current.overlay_string_index;
4449 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4450 it->overlay_strings[i++] = entries[j++].string;
4451
4452 CHECK_IT (it);
4453 }
4454
4455
4456 /* Get the first chunk of overlay strings at IT's current buffer
4457 position, or at CHARPOS if that is > 0. Value is non-zero if at
4458 least one overlay string was found. */
4459
4460 static int
4461 get_overlay_strings (it, charpos)
4462 struct it *it;
4463 int charpos;
4464 {
4465 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4466 process. This fills IT->overlay_strings with strings, and sets
4467 IT->n_overlay_strings to the total number of strings to process.
4468 IT->pos.overlay_string_index has to be set temporarily to zero
4469 because load_overlay_strings needs this; it must be set to -1
4470 when no overlay strings are found because a zero value would
4471 indicate a position in the first overlay string. */
4472 it->current.overlay_string_index = 0;
4473 load_overlay_strings (it, charpos);
4474
4475 /* If we found overlay strings, set up IT to deliver display
4476 elements from the first one. Otherwise set up IT to deliver
4477 from current_buffer. */
4478 if (it->n_overlay_strings)
4479 {
4480 /* Make sure we know settings in current_buffer, so that we can
4481 restore meaningful values when we're done with the overlay
4482 strings. */
4483 compute_stop_pos (it);
4484 xassert (it->face_id >= 0);
4485
4486 /* Save IT's settings. They are restored after all overlay
4487 strings have been processed. */
4488 xassert (it->sp == 0);
4489 push_it (it);
4490
4491 /* Set up IT to deliver display elements from the first overlay
4492 string. */
4493 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4494 it->string = it->overlay_strings[0];
4495 it->stop_charpos = 0;
4496 xassert (STRINGP (it->string));
4497 it->end_charpos = SCHARS (it->string);
4498 it->multibyte_p = STRING_MULTIBYTE (it->string);
4499 it->method = GET_FROM_STRING;
4500 }
4501 else
4502 {
4503 it->string = Qnil;
4504 it->current.overlay_string_index = -1;
4505 it->method = GET_FROM_BUFFER;
4506 }
4507
4508 CHECK_IT (it);
4509
4510 /* Value is non-zero if we found at least one overlay string. */
4511 return STRINGP (it->string);
4512 }
4513
4514
4515 \f
4516 /***********************************************************************
4517 Saving and restoring state
4518 ***********************************************************************/
4519
4520 /* Save current settings of IT on IT->stack. Called, for example,
4521 before setting up IT for an overlay string, to be able to restore
4522 IT's settings to what they were after the overlay string has been
4523 processed. */
4524
4525 static void
4526 push_it (it)
4527 struct it *it;
4528 {
4529 struct iterator_stack_entry *p;
4530
4531 xassert (it->sp < 2);
4532 p = it->stack + it->sp;
4533
4534 p->stop_charpos = it->stop_charpos;
4535 xassert (it->face_id >= 0);
4536 p->face_id = it->face_id;
4537 p->string = it->string;
4538 p->pos = it->current;
4539 p->end_charpos = it->end_charpos;
4540 p->string_nchars = it->string_nchars;
4541 p->area = it->area;
4542 p->multibyte_p = it->multibyte_p;
4543 p->slice = it->slice;
4544 p->space_width = it->space_width;
4545 p->font_height = it->font_height;
4546 p->voffset = it->voffset;
4547 p->string_from_display_prop_p = it->string_from_display_prop_p;
4548 p->display_ellipsis_p = 0;
4549 ++it->sp;
4550 }
4551
4552
4553 /* Restore IT's settings from IT->stack. Called, for example, when no
4554 more overlay strings must be processed, and we return to delivering
4555 display elements from a buffer, or when the end of a string from a
4556 `display' property is reached and we return to delivering display
4557 elements from an overlay string, or from a buffer. */
4558
4559 static void
4560 pop_it (it)
4561 struct it *it;
4562 {
4563 struct iterator_stack_entry *p;
4564
4565 xassert (it->sp > 0);
4566 --it->sp;
4567 p = it->stack + it->sp;
4568 it->stop_charpos = p->stop_charpos;
4569 it->face_id = p->face_id;
4570 it->string = p->string;
4571 it->current = p->pos;
4572 it->end_charpos = p->end_charpos;
4573 it->string_nchars = p->string_nchars;
4574 it->area = p->area;
4575 it->multibyte_p = p->multibyte_p;
4576 it->slice = p->slice;
4577 it->space_width = p->space_width;
4578 it->font_height = p->font_height;
4579 it->voffset = p->voffset;
4580 it->string_from_display_prop_p = p->string_from_display_prop_p;
4581 }
4582
4583
4584 \f
4585 /***********************************************************************
4586 Moving over lines
4587 ***********************************************************************/
4588
4589 /* Set IT's current position to the previous line start. */
4590
4591 static void
4592 back_to_previous_line_start (it)
4593 struct it *it;
4594 {
4595 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4596 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4597 }
4598
4599
4600 /* Move IT to the next line start.
4601
4602 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4603 we skipped over part of the text (as opposed to moving the iterator
4604 continuously over the text). Otherwise, don't change the value
4605 of *SKIPPED_P.
4606
4607 Newlines may come from buffer text, overlay strings, or strings
4608 displayed via the `display' property. That's the reason we can't
4609 simply use find_next_newline_no_quit.
4610
4611 Note that this function may not skip over invisible text that is so
4612 because of text properties and immediately follows a newline. If
4613 it would, function reseat_at_next_visible_line_start, when called
4614 from set_iterator_to_next, would effectively make invisible
4615 characters following a newline part of the wrong glyph row, which
4616 leads to wrong cursor motion. */
4617
4618 static int
4619 forward_to_next_line_start (it, skipped_p)
4620 struct it *it;
4621 int *skipped_p;
4622 {
4623 int old_selective, newline_found_p, n;
4624 const int MAX_NEWLINE_DISTANCE = 500;
4625
4626 /* If already on a newline, just consume it to avoid unintended
4627 skipping over invisible text below. */
4628 if (it->what == IT_CHARACTER
4629 && it->c == '\n'
4630 && CHARPOS (it->position) == IT_CHARPOS (*it))
4631 {
4632 set_iterator_to_next (it, 0);
4633 it->c = 0;
4634 return 1;
4635 }
4636
4637 /* Don't handle selective display in the following. It's (a)
4638 unnecessary because it's done by the caller, and (b) leads to an
4639 infinite recursion because next_element_from_ellipsis indirectly
4640 calls this function. */
4641 old_selective = it->selective;
4642 it->selective = 0;
4643
4644 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4645 from buffer text. */
4646 for (n = newline_found_p = 0;
4647 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4648 n += STRINGP (it->string) ? 0 : 1)
4649 {
4650 if (!get_next_display_element (it))
4651 return 0;
4652 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4653 set_iterator_to_next (it, 0);
4654 }
4655
4656 /* If we didn't find a newline near enough, see if we can use a
4657 short-cut. */
4658 if (!newline_found_p)
4659 {
4660 int start = IT_CHARPOS (*it);
4661 int limit = find_next_newline_no_quit (start, 1);
4662 Lisp_Object pos;
4663
4664 xassert (!STRINGP (it->string));
4665
4666 /* If there isn't any `display' property in sight, and no
4667 overlays, we can just use the position of the newline in
4668 buffer text. */
4669 if (it->stop_charpos >= limit
4670 || ((pos = Fnext_single_property_change (make_number (start),
4671 Qdisplay,
4672 Qnil, make_number (limit)),
4673 NILP (pos))
4674 && next_overlay_change (start) == ZV))
4675 {
4676 IT_CHARPOS (*it) = limit;
4677 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4678 *skipped_p = newline_found_p = 1;
4679 }
4680 else
4681 {
4682 while (get_next_display_element (it)
4683 && !newline_found_p)
4684 {
4685 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4686 set_iterator_to_next (it, 0);
4687 }
4688 }
4689 }
4690
4691 it->selective = old_selective;
4692 return newline_found_p;
4693 }
4694
4695
4696 /* Set IT's current position to the previous visible line start. Skip
4697 invisible text that is so either due to text properties or due to
4698 selective display. Caution: this does not change IT->current_x and
4699 IT->hpos. */
4700
4701 static void
4702 back_to_previous_visible_line_start (it)
4703 struct it *it;
4704 {
4705 while (IT_CHARPOS (*it) > BEGV)
4706 {
4707 back_to_previous_line_start (it);
4708 if (IT_CHARPOS (*it) <= BEGV)
4709 break;
4710
4711 /* If selective > 0, then lines indented more than that values
4712 are invisible. */
4713 if (it->selective > 0
4714 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4715 (double) it->selective)) /* iftc */
4716 continue;
4717
4718 /* Check the newline before point for invisibility. */
4719 {
4720 Lisp_Object prop;
4721 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4722 Qinvisible, it->window);
4723 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4724 continue;
4725 }
4726
4727 /* If newline has a display property that replaces the newline with something
4728 else (image or text), find start of overlay or interval and continue search
4729 from that point. */
4730 if (IT_CHARPOS (*it) > BEGV)
4731 {
4732 struct it it2 = *it;
4733 int pos;
4734 int beg, end;
4735 Lisp_Object val, overlay;
4736
4737 pos = --IT_CHARPOS (it2);
4738 --IT_BYTEPOS (it2);
4739 it2.sp = 0;
4740 if (handle_display_prop (&it2) == HANDLED_RETURN
4741 && !NILP (val = get_char_property_and_overlay
4742 (make_number (pos), Qdisplay, Qnil, &overlay))
4743 && (OVERLAYP (overlay)
4744 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
4745 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
4746 {
4747 if (beg < BEGV)
4748 beg = BEGV;
4749 IT_CHARPOS (*it) = beg;
4750 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
4751 continue;
4752 }
4753 }
4754
4755 break;
4756 }
4757
4758 xassert (IT_CHARPOS (*it) >= BEGV);
4759 xassert (IT_CHARPOS (*it) == BEGV
4760 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4761 CHECK_IT (it);
4762 }
4763
4764
4765 /* Reseat iterator IT at the previous visible line start. Skip
4766 invisible text that is so either due to text properties or due to
4767 selective display. At the end, update IT's overlay information,
4768 face information etc. */
4769
4770 void
4771 reseat_at_previous_visible_line_start (it)
4772 struct it *it;
4773 {
4774 back_to_previous_visible_line_start (it);
4775 reseat (it, it->current.pos, 1);
4776 CHECK_IT (it);
4777 }
4778
4779
4780 /* Reseat iterator IT on the next visible line start in the current
4781 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4782 preceding the line start. Skip over invisible text that is so
4783 because of selective display. Compute faces, overlays etc at the
4784 new position. Note that this function does not skip over text that
4785 is invisible because of text properties. */
4786
4787 static void
4788 reseat_at_next_visible_line_start (it, on_newline_p)
4789 struct it *it;
4790 int on_newline_p;
4791 {
4792 int newline_found_p, skipped_p = 0;
4793
4794 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4795
4796 /* Skip over lines that are invisible because they are indented
4797 more than the value of IT->selective. */
4798 if (it->selective > 0)
4799 while (IT_CHARPOS (*it) < ZV
4800 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4801 (double) it->selective)) /* iftc */
4802 {
4803 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4804 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4805 }
4806
4807 /* Position on the newline if that's what's requested. */
4808 if (on_newline_p && newline_found_p)
4809 {
4810 if (STRINGP (it->string))
4811 {
4812 if (IT_STRING_CHARPOS (*it) > 0)
4813 {
4814 --IT_STRING_CHARPOS (*it);
4815 --IT_STRING_BYTEPOS (*it);
4816 }
4817 }
4818 else if (IT_CHARPOS (*it) > BEGV)
4819 {
4820 --IT_CHARPOS (*it);
4821 --IT_BYTEPOS (*it);
4822 reseat (it, it->current.pos, 0);
4823 }
4824 }
4825 else if (skipped_p)
4826 reseat (it, it->current.pos, 0);
4827
4828 CHECK_IT (it);
4829 }
4830
4831
4832 \f
4833 /***********************************************************************
4834 Changing an iterator's position
4835 ***********************************************************************/
4836
4837 /* Change IT's current position to POS in current_buffer. If FORCE_P
4838 is non-zero, always check for text properties at the new position.
4839 Otherwise, text properties are only looked up if POS >=
4840 IT->check_charpos of a property. */
4841
4842 static void
4843 reseat (it, pos, force_p)
4844 struct it *it;
4845 struct text_pos pos;
4846 int force_p;
4847 {
4848 int original_pos = IT_CHARPOS (*it);
4849
4850 reseat_1 (it, pos, 0);
4851
4852 /* Determine where to check text properties. Avoid doing it
4853 where possible because text property lookup is very expensive. */
4854 if (force_p
4855 || CHARPOS (pos) > it->stop_charpos
4856 || CHARPOS (pos) < original_pos)
4857 handle_stop (it);
4858
4859 CHECK_IT (it);
4860 }
4861
4862
4863 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4864 IT->stop_pos to POS, also. */
4865
4866 static void
4867 reseat_1 (it, pos, set_stop_p)
4868 struct it *it;
4869 struct text_pos pos;
4870 int set_stop_p;
4871 {
4872 /* Don't call this function when scanning a C string. */
4873 xassert (it->s == NULL);
4874
4875 /* POS must be a reasonable value. */
4876 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4877
4878 it->current.pos = it->position = pos;
4879 XSETBUFFER (it->object, current_buffer);
4880 it->end_charpos = ZV;
4881 it->dpvec = NULL;
4882 it->current.dpvec_index = -1;
4883 it->current.overlay_string_index = -1;
4884 IT_STRING_CHARPOS (*it) = -1;
4885 IT_STRING_BYTEPOS (*it) = -1;
4886 it->string = Qnil;
4887 it->method = GET_FROM_BUFFER;
4888 /* RMS: I added this to fix a bug in move_it_vertically_backward
4889 where it->area continued to relate to the starting point
4890 for the backward motion. Bug report from
4891 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4892 However, I am not sure whether reseat still does the right thing
4893 in general after this change. */
4894 it->area = TEXT_AREA;
4895 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4896 it->sp = 0;
4897 it->face_before_selective_p = 0;
4898
4899 if (set_stop_p)
4900 it->stop_charpos = CHARPOS (pos);
4901 }
4902
4903
4904 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4905 If S is non-null, it is a C string to iterate over. Otherwise,
4906 STRING gives a Lisp string to iterate over.
4907
4908 If PRECISION > 0, don't return more then PRECISION number of
4909 characters from the string.
4910
4911 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4912 characters have been returned. FIELD_WIDTH < 0 means an infinite
4913 field width.
4914
4915 MULTIBYTE = 0 means disable processing of multibyte characters,
4916 MULTIBYTE > 0 means enable it,
4917 MULTIBYTE < 0 means use IT->multibyte_p.
4918
4919 IT must be initialized via a prior call to init_iterator before
4920 calling this function. */
4921
4922 static void
4923 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4924 struct it *it;
4925 unsigned char *s;
4926 Lisp_Object string;
4927 int charpos;
4928 int precision, field_width, multibyte;
4929 {
4930 /* No region in strings. */
4931 it->region_beg_charpos = it->region_end_charpos = -1;
4932
4933 /* No text property checks performed by default, but see below. */
4934 it->stop_charpos = -1;
4935
4936 /* Set iterator position and end position. */
4937 bzero (&it->current, sizeof it->current);
4938 it->current.overlay_string_index = -1;
4939 it->current.dpvec_index = -1;
4940 xassert (charpos >= 0);
4941
4942 /* If STRING is specified, use its multibyteness, otherwise use the
4943 setting of MULTIBYTE, if specified. */
4944 if (multibyte >= 0)
4945 it->multibyte_p = multibyte > 0;
4946
4947 if (s == NULL)
4948 {
4949 xassert (STRINGP (string));
4950 it->string = string;
4951 it->s = NULL;
4952 it->end_charpos = it->string_nchars = SCHARS (string);
4953 it->method = GET_FROM_STRING;
4954 it->current.string_pos = string_pos (charpos, string);
4955 }
4956 else
4957 {
4958 it->s = s;
4959 it->string = Qnil;
4960
4961 /* Note that we use IT->current.pos, not it->current.string_pos,
4962 for displaying C strings. */
4963 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4964 if (it->multibyte_p)
4965 {
4966 it->current.pos = c_string_pos (charpos, s, 1);
4967 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4968 }
4969 else
4970 {
4971 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4972 it->end_charpos = it->string_nchars = strlen (s);
4973 }
4974
4975 it->method = GET_FROM_C_STRING;
4976 }
4977
4978 /* PRECISION > 0 means don't return more than PRECISION characters
4979 from the string. */
4980 if (precision > 0 && it->end_charpos - charpos > precision)
4981 it->end_charpos = it->string_nchars = charpos + precision;
4982
4983 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4984 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4985 FIELD_WIDTH < 0 means infinite field width. This is useful for
4986 padding with `-' at the end of a mode line. */
4987 if (field_width < 0)
4988 field_width = INFINITY;
4989 if (field_width > it->end_charpos - charpos)
4990 it->end_charpos = charpos + field_width;
4991
4992 /* Use the standard display table for displaying strings. */
4993 if (DISP_TABLE_P (Vstandard_display_table))
4994 it->dp = XCHAR_TABLE (Vstandard_display_table);
4995
4996 it->stop_charpos = charpos;
4997 CHECK_IT (it);
4998 }
4999
5000
5001 \f
5002 /***********************************************************************
5003 Iteration
5004 ***********************************************************************/
5005
5006 /* Map enum it_method value to corresponding next_element_from_* function. */
5007
5008 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5009 {
5010 next_element_from_buffer,
5011 next_element_from_display_vector,
5012 next_element_from_composition,
5013 next_element_from_string,
5014 next_element_from_c_string,
5015 next_element_from_image,
5016 next_element_from_stretch
5017 };
5018
5019
5020 /* Load IT's display element fields with information about the next
5021 display element from the current position of IT. Value is zero if
5022 end of buffer (or C string) is reached. */
5023
5024 int
5025 get_next_display_element (it)
5026 struct it *it;
5027 {
5028 /* Non-zero means that we found a display element. Zero means that
5029 we hit the end of what we iterate over. Performance note: the
5030 function pointer `method' used here turns out to be faster than
5031 using a sequence of if-statements. */
5032 int success_p;
5033
5034 get_next:
5035 success_p = (*get_next_element[it->method]) (it);
5036
5037 if (it->what == IT_CHARACTER)
5038 {
5039 /* Map via display table or translate control characters.
5040 IT->c, IT->len etc. have been set to the next character by
5041 the function call above. If we have a display table, and it
5042 contains an entry for IT->c, translate it. Don't do this if
5043 IT->c itself comes from a display table, otherwise we could
5044 end up in an infinite recursion. (An alternative could be to
5045 count the recursion depth of this function and signal an
5046 error when a certain maximum depth is reached.) Is it worth
5047 it? */
5048 if (success_p && it->dpvec == NULL)
5049 {
5050 Lisp_Object dv;
5051
5052 if (it->dp
5053 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5054 VECTORP (dv)))
5055 {
5056 struct Lisp_Vector *v = XVECTOR (dv);
5057
5058 /* Return the first character from the display table
5059 entry, if not empty. If empty, don't display the
5060 current character. */
5061 if (v->size)
5062 {
5063 it->dpvec_char_len = it->len;
5064 it->dpvec = v->contents;
5065 it->dpend = v->contents + v->size;
5066 it->current.dpvec_index = 0;
5067 it->dpvec_face_id = -1;
5068 it->saved_face_id = it->face_id;
5069 it->method = GET_FROM_DISPLAY_VECTOR;
5070 it->ellipsis_p = 0;
5071 }
5072 else
5073 {
5074 set_iterator_to_next (it, 0);
5075 }
5076 goto get_next;
5077 }
5078
5079 /* Translate control characters into `\003' or `^C' form.
5080 Control characters coming from a display table entry are
5081 currently not translated because we use IT->dpvec to hold
5082 the translation. This could easily be changed but I
5083 don't believe that it is worth doing.
5084
5085 If it->multibyte_p is nonzero, eight-bit characters and
5086 non-printable multibyte characters are also translated to
5087 octal form.
5088
5089 If it->multibyte_p is zero, eight-bit characters that
5090 don't have corresponding multibyte char code are also
5091 translated to octal form. */
5092 else if ((it->c < ' '
5093 && (it->area != TEXT_AREA
5094 /* In mode line, treat \n like other crl chars. */
5095 || (it->c != '\t'
5096 && it->glyph_row && it->glyph_row->mode_line_p)
5097 || (it->c != '\n' && it->c != '\t')))
5098 || (it->multibyte_p
5099 ? ((it->c >= 127
5100 && it->len == 1)
5101 || !CHAR_PRINTABLE_P (it->c)
5102 || (!NILP (Vnobreak_char_display)
5103 && (it->c == 0x8a0 || it->c == 0x8ad
5104 || it->c == 0x920 || it->c == 0x92d
5105 || it->c == 0xe20 || it->c == 0xe2d
5106 || it->c == 0xf20 || it->c == 0xf2d)))
5107 : (it->c >= 127
5108 && (!unibyte_display_via_language_environment
5109 || it->c == unibyte_char_to_multibyte (it->c)))))
5110 {
5111 /* IT->c is a control character which must be displayed
5112 either as '\003' or as `^C' where the '\\' and '^'
5113 can be defined in the display table. Fill
5114 IT->ctl_chars with glyphs for what we have to
5115 display. Then, set IT->dpvec to these glyphs. */
5116 GLYPH g;
5117 int ctl_len;
5118 int face_id, lface_id = 0 ;
5119 GLYPH escape_glyph;
5120
5121 /* Handle control characters with ^. */
5122
5123 if (it->c < 128 && it->ctl_arrow_p)
5124 {
5125 g = '^'; /* default glyph for Control */
5126 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5127 if (it->dp
5128 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5129 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5130 {
5131 g = XINT (DISP_CTRL_GLYPH (it->dp));
5132 lface_id = FAST_GLYPH_FACE (g);
5133 }
5134 if (lface_id)
5135 {
5136 g = FAST_GLYPH_CHAR (g);
5137 face_id = merge_faces (it->f, Qt, lface_id,
5138 it->face_id);
5139 }
5140 else
5141 {
5142 /* Merge the escape-glyph face into the current face. */
5143 face_id = merge_faces (it->f, Qescape_glyph, 0,
5144 it->face_id);
5145 }
5146
5147 XSETINT (it->ctl_chars[0], g);
5148 g = it->c ^ 0100;
5149 XSETINT (it->ctl_chars[1], g);
5150 ctl_len = 2;
5151 goto display_control;
5152 }
5153
5154 /* Handle non-break space in the mode where it only gets
5155 highlighting. */
5156
5157 if (EQ (Vnobreak_char_display, Qt)
5158 && (it->c == 0x8a0 || it->c == 0x920
5159 || it->c == 0xe20 || it->c == 0xf20))
5160 {
5161 /* Merge the no-break-space face into the current face. */
5162 face_id = merge_faces (it->f, Qnobreak_space, 0,
5163 it->face_id);
5164
5165 g = it->c = ' ';
5166 XSETINT (it->ctl_chars[0], g);
5167 ctl_len = 1;
5168 goto display_control;
5169 }
5170
5171 /* Handle sequences that start with the "escape glyph". */
5172
5173 /* the default escape glyph is \. */
5174 escape_glyph = '\\';
5175
5176 if (it->dp
5177 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5178 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5179 {
5180 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5181 lface_id = FAST_GLYPH_FACE (escape_glyph);
5182 }
5183 if (lface_id)
5184 {
5185 /* The display table specified a face.
5186 Merge it into face_id and also into escape_glyph. */
5187 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5188 face_id = merge_faces (it->f, Qt, lface_id,
5189 it->face_id);
5190 }
5191 else
5192 {
5193 /* Merge the escape-glyph face into the current face. */
5194 face_id = merge_faces (it->f, Qescape_glyph, 0,
5195 it->face_id);
5196 }
5197
5198 /* Handle soft hyphens in the mode where they only get
5199 highlighting. */
5200
5201 if (EQ (Vnobreak_char_display, Qt)
5202 && (it->c == 0x8ad || it->c == 0x92d
5203 || it->c == 0xe2d || it->c == 0xf2d))
5204 {
5205 g = it->c = '-';
5206 XSETINT (it->ctl_chars[0], g);
5207 ctl_len = 1;
5208 goto display_control;
5209 }
5210
5211 /* Handle non-break space and soft hyphen
5212 with the escape glyph. */
5213
5214 if (it->c == 0x8a0 || it->c == 0x8ad
5215 || it->c == 0x920 || it->c == 0x92d
5216 || it->c == 0xe20 || it->c == 0xe2d
5217 || it->c == 0xf20 || it->c == 0xf2d)
5218 {
5219 XSETINT (it->ctl_chars[0], escape_glyph);
5220 g = it->c = ((it->c & 0xf) == 0 ? ' ' : '-');
5221 XSETINT (it->ctl_chars[1], g);
5222 ctl_len = 2;
5223 goto display_control;
5224 }
5225
5226 {
5227 unsigned char str[MAX_MULTIBYTE_LENGTH];
5228 int len;
5229 int i;
5230
5231 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5232 if (SINGLE_BYTE_CHAR_P (it->c))
5233 str[0] = it->c, len = 1;
5234 else
5235 {
5236 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5237 if (len < 0)
5238 {
5239 /* It's an invalid character, which shouldn't
5240 happen actually, but due to bugs it may
5241 happen. Let's print the char as is, there's
5242 not much meaningful we can do with it. */
5243 str[0] = it->c;
5244 str[1] = it->c >> 8;
5245 str[2] = it->c >> 16;
5246 str[3] = it->c >> 24;
5247 len = 4;
5248 }
5249 }
5250
5251 for (i = 0; i < len; i++)
5252 {
5253 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5254 /* Insert three more glyphs into IT->ctl_chars for
5255 the octal display of the character. */
5256 g = ((str[i] >> 6) & 7) + '0';
5257 XSETINT (it->ctl_chars[i * 4 + 1], g);
5258 g = ((str[i] >> 3) & 7) + '0';
5259 XSETINT (it->ctl_chars[i * 4 + 2], g);
5260 g = (str[i] & 7) + '0';
5261 XSETINT (it->ctl_chars[i * 4 + 3], g);
5262 }
5263 ctl_len = len * 4;
5264 }
5265
5266 display_control:
5267 /* Set up IT->dpvec and return first character from it. */
5268 it->dpvec_char_len = it->len;
5269 it->dpvec = it->ctl_chars;
5270 it->dpend = it->dpvec + ctl_len;
5271 it->current.dpvec_index = 0;
5272 it->dpvec_face_id = face_id;
5273 it->saved_face_id = it->face_id;
5274 it->method = GET_FROM_DISPLAY_VECTOR;
5275 it->ellipsis_p = 0;
5276 goto get_next;
5277 }
5278 }
5279
5280 /* Adjust face id for a multibyte character. There are no
5281 multibyte character in unibyte text. */
5282 if (it->multibyte_p
5283 && success_p
5284 && FRAME_WINDOW_P (it->f))
5285 {
5286 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5287 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5288 }
5289 }
5290
5291 /* Is this character the last one of a run of characters with
5292 box? If yes, set IT->end_of_box_run_p to 1. */
5293 if (it->face_box_p
5294 && it->s == NULL)
5295 {
5296 int face_id;
5297 struct face *face;
5298
5299 it->end_of_box_run_p
5300 = ((face_id = face_after_it_pos (it),
5301 face_id != it->face_id)
5302 && (face = FACE_FROM_ID (it->f, face_id),
5303 face->box == FACE_NO_BOX));
5304 }
5305
5306 /* Value is 0 if end of buffer or string reached. */
5307 return success_p;
5308 }
5309
5310
5311 /* Move IT to the next display element.
5312
5313 RESEAT_P non-zero means if called on a newline in buffer text,
5314 skip to the next visible line start.
5315
5316 Functions get_next_display_element and set_iterator_to_next are
5317 separate because I find this arrangement easier to handle than a
5318 get_next_display_element function that also increments IT's
5319 position. The way it is we can first look at an iterator's current
5320 display element, decide whether it fits on a line, and if it does,
5321 increment the iterator position. The other way around we probably
5322 would either need a flag indicating whether the iterator has to be
5323 incremented the next time, or we would have to implement a
5324 decrement position function which would not be easy to write. */
5325
5326 void
5327 set_iterator_to_next (it, reseat_p)
5328 struct it *it;
5329 int reseat_p;
5330 {
5331 /* Reset flags indicating start and end of a sequence of characters
5332 with box. Reset them at the start of this function because
5333 moving the iterator to a new position might set them. */
5334 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5335
5336 switch (it->method)
5337 {
5338 case GET_FROM_BUFFER:
5339 /* The current display element of IT is a character from
5340 current_buffer. Advance in the buffer, and maybe skip over
5341 invisible lines that are so because of selective display. */
5342 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5343 reseat_at_next_visible_line_start (it, 0);
5344 else
5345 {
5346 xassert (it->len != 0);
5347 IT_BYTEPOS (*it) += it->len;
5348 IT_CHARPOS (*it) += 1;
5349 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5350 }
5351 break;
5352
5353 case GET_FROM_COMPOSITION:
5354 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5355 if (STRINGP (it->string))
5356 {
5357 IT_STRING_BYTEPOS (*it) += it->len;
5358 IT_STRING_CHARPOS (*it) += it->cmp_len;
5359 it->method = GET_FROM_STRING;
5360 goto consider_string_end;
5361 }
5362 else
5363 {
5364 IT_BYTEPOS (*it) += it->len;
5365 IT_CHARPOS (*it) += it->cmp_len;
5366 it->method = GET_FROM_BUFFER;
5367 }
5368 break;
5369
5370 case GET_FROM_C_STRING:
5371 /* Current display element of IT is from a C string. */
5372 IT_BYTEPOS (*it) += it->len;
5373 IT_CHARPOS (*it) += 1;
5374 break;
5375
5376 case GET_FROM_DISPLAY_VECTOR:
5377 /* Current display element of IT is from a display table entry.
5378 Advance in the display table definition. Reset it to null if
5379 end reached, and continue with characters from buffers/
5380 strings. */
5381 ++it->current.dpvec_index;
5382
5383 /* Restore face of the iterator to what they were before the
5384 display vector entry (these entries may contain faces). */
5385 it->face_id = it->saved_face_id;
5386
5387 if (it->dpvec + it->current.dpvec_index == it->dpend)
5388 {
5389 if (it->s)
5390 it->method = GET_FROM_C_STRING;
5391 else if (STRINGP (it->string))
5392 it->method = GET_FROM_STRING;
5393 else
5394 it->method = GET_FROM_BUFFER;
5395
5396 it->dpvec = NULL;
5397 it->current.dpvec_index = -1;
5398
5399 /* Skip over characters which were displayed via IT->dpvec. */
5400 if (it->dpvec_char_len < 0)
5401 reseat_at_next_visible_line_start (it, 1);
5402 else if (it->dpvec_char_len > 0)
5403 {
5404 it->len = it->dpvec_char_len;
5405 set_iterator_to_next (it, reseat_p);
5406 }
5407
5408 /* Recheck faces after display vector */
5409 it->stop_charpos = IT_CHARPOS (*it);
5410 }
5411 break;
5412
5413 case GET_FROM_STRING:
5414 /* Current display element is a character from a Lisp string. */
5415 xassert (it->s == NULL && STRINGP (it->string));
5416 IT_STRING_BYTEPOS (*it) += it->len;
5417 IT_STRING_CHARPOS (*it) += 1;
5418
5419 consider_string_end:
5420
5421 if (it->current.overlay_string_index >= 0)
5422 {
5423 /* IT->string is an overlay string. Advance to the
5424 next, if there is one. */
5425 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5426 next_overlay_string (it);
5427 }
5428 else
5429 {
5430 /* IT->string is not an overlay string. If we reached
5431 its end, and there is something on IT->stack, proceed
5432 with what is on the stack. This can be either another
5433 string, this time an overlay string, or a buffer. */
5434 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5435 && it->sp > 0)
5436 {
5437 pop_it (it);
5438 if (STRINGP (it->string))
5439 goto consider_string_end;
5440 it->method = GET_FROM_BUFFER;
5441 }
5442 }
5443 break;
5444
5445 case GET_FROM_IMAGE:
5446 case GET_FROM_STRETCH:
5447 /* The position etc with which we have to proceed are on
5448 the stack. The position may be at the end of a string,
5449 if the `display' property takes up the whole string. */
5450 xassert (it->sp > 0);
5451 pop_it (it);
5452 it->image_id = 0;
5453 if (STRINGP (it->string))
5454 {
5455 it->method = GET_FROM_STRING;
5456 goto consider_string_end;
5457 }
5458 it->method = GET_FROM_BUFFER;
5459 break;
5460
5461 default:
5462 /* There are no other methods defined, so this should be a bug. */
5463 abort ();
5464 }
5465
5466 xassert (it->method != GET_FROM_STRING
5467 || (STRINGP (it->string)
5468 && IT_STRING_CHARPOS (*it) >= 0));
5469 }
5470
5471 /* Load IT's display element fields with information about the next
5472 display element which comes from a display table entry or from the
5473 result of translating a control character to one of the forms `^C'
5474 or `\003'.
5475
5476 IT->dpvec holds the glyphs to return as characters.
5477 IT->saved_face_id holds the face id before the display vector--
5478 it is restored into IT->face_idin set_iterator_to_next. */
5479
5480 static int
5481 next_element_from_display_vector (it)
5482 struct it *it;
5483 {
5484 /* Precondition. */
5485 xassert (it->dpvec && it->current.dpvec_index >= 0);
5486
5487 it->face_id = it->saved_face_id;
5488
5489 if (INTEGERP (*it->dpvec)
5490 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5491 {
5492 GLYPH g;
5493
5494 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5495 it->c = FAST_GLYPH_CHAR (g);
5496 it->len = CHAR_BYTES (it->c);
5497
5498 /* The entry may contain a face id to use. Such a face id is
5499 the id of a Lisp face, not a realized face. A face id of
5500 zero means no face is specified. */
5501 if (it->dpvec_face_id >= 0)
5502 it->face_id = it->dpvec_face_id;
5503 else
5504 {
5505 int lface_id = FAST_GLYPH_FACE (g);
5506 if (lface_id > 0)
5507 it->face_id = merge_faces (it->f, Qt, lface_id,
5508 it->saved_face_id);
5509 }
5510 }
5511 else
5512 /* Display table entry is invalid. Return a space. */
5513 it->c = ' ', it->len = 1;
5514
5515 /* Don't change position and object of the iterator here. They are
5516 still the values of the character that had this display table
5517 entry or was translated, and that's what we want. */
5518 it->what = IT_CHARACTER;
5519 return 1;
5520 }
5521
5522
5523 /* Load IT with the next display element from Lisp string IT->string.
5524 IT->current.string_pos is the current position within the string.
5525 If IT->current.overlay_string_index >= 0, the Lisp string is an
5526 overlay string. */
5527
5528 static int
5529 next_element_from_string (it)
5530 struct it *it;
5531 {
5532 struct text_pos position;
5533
5534 xassert (STRINGP (it->string));
5535 xassert (IT_STRING_CHARPOS (*it) >= 0);
5536 position = it->current.string_pos;
5537
5538 /* Time to check for invisible text? */
5539 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5540 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5541 {
5542 handle_stop (it);
5543
5544 /* Since a handler may have changed IT->method, we must
5545 recurse here. */
5546 return get_next_display_element (it);
5547 }
5548
5549 if (it->current.overlay_string_index >= 0)
5550 {
5551 /* Get the next character from an overlay string. In overlay
5552 strings, There is no field width or padding with spaces to
5553 do. */
5554 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5555 {
5556 it->what = IT_EOB;
5557 return 0;
5558 }
5559 else if (STRING_MULTIBYTE (it->string))
5560 {
5561 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5562 const unsigned char *s = (SDATA (it->string)
5563 + IT_STRING_BYTEPOS (*it));
5564 it->c = string_char_and_length (s, remaining, &it->len);
5565 }
5566 else
5567 {
5568 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5569 it->len = 1;
5570 }
5571 }
5572 else
5573 {
5574 /* Get the next character from a Lisp string that is not an
5575 overlay string. Such strings come from the mode line, for
5576 example. We may have to pad with spaces, or truncate the
5577 string. See also next_element_from_c_string. */
5578 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5579 {
5580 it->what = IT_EOB;
5581 return 0;
5582 }
5583 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5584 {
5585 /* Pad with spaces. */
5586 it->c = ' ', it->len = 1;
5587 CHARPOS (position) = BYTEPOS (position) = -1;
5588 }
5589 else if (STRING_MULTIBYTE (it->string))
5590 {
5591 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5592 const unsigned char *s = (SDATA (it->string)
5593 + IT_STRING_BYTEPOS (*it));
5594 it->c = string_char_and_length (s, maxlen, &it->len);
5595 }
5596 else
5597 {
5598 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5599 it->len = 1;
5600 }
5601 }
5602
5603 /* Record what we have and where it came from. Note that we store a
5604 buffer position in IT->position although it could arguably be a
5605 string position. */
5606 it->what = IT_CHARACTER;
5607 it->object = it->string;
5608 it->position = position;
5609 return 1;
5610 }
5611
5612
5613 /* Load IT with next display element from C string IT->s.
5614 IT->string_nchars is the maximum number of characters to return
5615 from the string. IT->end_charpos may be greater than
5616 IT->string_nchars when this function is called, in which case we
5617 may have to return padding spaces. Value is zero if end of string
5618 reached, including padding spaces. */
5619
5620 static int
5621 next_element_from_c_string (it)
5622 struct it *it;
5623 {
5624 int success_p = 1;
5625
5626 xassert (it->s);
5627 it->what = IT_CHARACTER;
5628 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5629 it->object = Qnil;
5630
5631 /* IT's position can be greater IT->string_nchars in case a field
5632 width or precision has been specified when the iterator was
5633 initialized. */
5634 if (IT_CHARPOS (*it) >= it->end_charpos)
5635 {
5636 /* End of the game. */
5637 it->what = IT_EOB;
5638 success_p = 0;
5639 }
5640 else if (IT_CHARPOS (*it) >= it->string_nchars)
5641 {
5642 /* Pad with spaces. */
5643 it->c = ' ', it->len = 1;
5644 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5645 }
5646 else if (it->multibyte_p)
5647 {
5648 /* Implementation note: The calls to strlen apparently aren't a
5649 performance problem because there is no noticeable performance
5650 difference between Emacs running in unibyte or multibyte mode. */
5651 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5652 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5653 maxlen, &it->len);
5654 }
5655 else
5656 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5657
5658 return success_p;
5659 }
5660
5661
5662 /* Set up IT to return characters from an ellipsis, if appropriate.
5663 The definition of the ellipsis glyphs may come from a display table
5664 entry. This function Fills IT with the first glyph from the
5665 ellipsis if an ellipsis is to be displayed. */
5666
5667 static int
5668 next_element_from_ellipsis (it)
5669 struct it *it;
5670 {
5671 if (it->selective_display_ellipsis_p)
5672 setup_for_ellipsis (it, it->len);
5673 else
5674 {
5675 /* The face at the current position may be different from the
5676 face we find after the invisible text. Remember what it
5677 was in IT->saved_face_id, and signal that it's there by
5678 setting face_before_selective_p. */
5679 it->saved_face_id = it->face_id;
5680 it->method = GET_FROM_BUFFER;
5681 reseat_at_next_visible_line_start (it, 1);
5682 it->face_before_selective_p = 1;
5683 }
5684
5685 return get_next_display_element (it);
5686 }
5687
5688
5689 /* Deliver an image display element. The iterator IT is already
5690 filled with image information (done in handle_display_prop). Value
5691 is always 1. */
5692
5693
5694 static int
5695 next_element_from_image (it)
5696 struct it *it;
5697 {
5698 it->what = IT_IMAGE;
5699 return 1;
5700 }
5701
5702
5703 /* Fill iterator IT with next display element from a stretch glyph
5704 property. IT->object is the value of the text property. Value is
5705 always 1. */
5706
5707 static int
5708 next_element_from_stretch (it)
5709 struct it *it;
5710 {
5711 it->what = IT_STRETCH;
5712 return 1;
5713 }
5714
5715
5716 /* Load IT with the next display element from current_buffer. Value
5717 is zero if end of buffer reached. IT->stop_charpos is the next
5718 position at which to stop and check for text properties or buffer
5719 end. */
5720
5721 static int
5722 next_element_from_buffer (it)
5723 struct it *it;
5724 {
5725 int success_p = 1;
5726
5727 /* Check this assumption, otherwise, we would never enter the
5728 if-statement, below. */
5729 xassert (IT_CHARPOS (*it) >= BEGV
5730 && IT_CHARPOS (*it) <= it->stop_charpos);
5731
5732 if (IT_CHARPOS (*it) >= it->stop_charpos)
5733 {
5734 if (IT_CHARPOS (*it) >= it->end_charpos)
5735 {
5736 int overlay_strings_follow_p;
5737
5738 /* End of the game, except when overlay strings follow that
5739 haven't been returned yet. */
5740 if (it->overlay_strings_at_end_processed_p)
5741 overlay_strings_follow_p = 0;
5742 else
5743 {
5744 it->overlay_strings_at_end_processed_p = 1;
5745 overlay_strings_follow_p = get_overlay_strings (it, 0);
5746 }
5747
5748 if (overlay_strings_follow_p)
5749 success_p = get_next_display_element (it);
5750 else
5751 {
5752 it->what = IT_EOB;
5753 it->position = it->current.pos;
5754 success_p = 0;
5755 }
5756 }
5757 else
5758 {
5759 handle_stop (it);
5760 return get_next_display_element (it);
5761 }
5762 }
5763 else
5764 {
5765 /* No face changes, overlays etc. in sight, so just return a
5766 character from current_buffer. */
5767 unsigned char *p;
5768
5769 /* Maybe run the redisplay end trigger hook. Performance note:
5770 This doesn't seem to cost measurable time. */
5771 if (it->redisplay_end_trigger_charpos
5772 && it->glyph_row
5773 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5774 run_redisplay_end_trigger_hook (it);
5775
5776 /* Get the next character, maybe multibyte. */
5777 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5778 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5779 {
5780 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5781 - IT_BYTEPOS (*it));
5782 it->c = string_char_and_length (p, maxlen, &it->len);
5783 }
5784 else
5785 it->c = *p, it->len = 1;
5786
5787 /* Record what we have and where it came from. */
5788 it->what = IT_CHARACTER;;
5789 it->object = it->w->buffer;
5790 it->position = it->current.pos;
5791
5792 /* Normally we return the character found above, except when we
5793 really want to return an ellipsis for selective display. */
5794 if (it->selective)
5795 {
5796 if (it->c == '\n')
5797 {
5798 /* A value of selective > 0 means hide lines indented more
5799 than that number of columns. */
5800 if (it->selective > 0
5801 && IT_CHARPOS (*it) + 1 < ZV
5802 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5803 IT_BYTEPOS (*it) + 1,
5804 (double) it->selective)) /* iftc */
5805 {
5806 success_p = next_element_from_ellipsis (it);
5807 it->dpvec_char_len = -1;
5808 }
5809 }
5810 else if (it->c == '\r' && it->selective == -1)
5811 {
5812 /* A value of selective == -1 means that everything from the
5813 CR to the end of the line is invisible, with maybe an
5814 ellipsis displayed for it. */
5815 success_p = next_element_from_ellipsis (it);
5816 it->dpvec_char_len = -1;
5817 }
5818 }
5819 }
5820
5821 /* Value is zero if end of buffer reached. */
5822 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5823 return success_p;
5824 }
5825
5826
5827 /* Run the redisplay end trigger hook for IT. */
5828
5829 static void
5830 run_redisplay_end_trigger_hook (it)
5831 struct it *it;
5832 {
5833 Lisp_Object args[3];
5834
5835 /* IT->glyph_row should be non-null, i.e. we should be actually
5836 displaying something, or otherwise we should not run the hook. */
5837 xassert (it->glyph_row);
5838
5839 /* Set up hook arguments. */
5840 args[0] = Qredisplay_end_trigger_functions;
5841 args[1] = it->window;
5842 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5843 it->redisplay_end_trigger_charpos = 0;
5844
5845 /* Since we are *trying* to run these functions, don't try to run
5846 them again, even if they get an error. */
5847 it->w->redisplay_end_trigger = Qnil;
5848 Frun_hook_with_args (3, args);
5849
5850 /* Notice if it changed the face of the character we are on. */
5851 handle_face_prop (it);
5852 }
5853
5854
5855 /* Deliver a composition display element. The iterator IT is already
5856 filled with composition information (done in
5857 handle_composition_prop). Value is always 1. */
5858
5859 static int
5860 next_element_from_composition (it)
5861 struct it *it;
5862 {
5863 it->what = IT_COMPOSITION;
5864 it->position = (STRINGP (it->string)
5865 ? it->current.string_pos
5866 : it->current.pos);
5867 return 1;
5868 }
5869
5870
5871 \f
5872 /***********************************************************************
5873 Moving an iterator without producing glyphs
5874 ***********************************************************************/
5875
5876 /* Check if iterator is at a position corresponding to a valid buffer
5877 position after some move_it_ call. */
5878
5879 #define IT_POS_VALID_AFTER_MOVE_P(it) \
5880 ((it)->method == GET_FROM_STRING \
5881 ? IT_STRING_CHARPOS (*it) == 0 \
5882 : 1)
5883
5884
5885 /* Move iterator IT to a specified buffer or X position within one
5886 line on the display without producing glyphs.
5887
5888 OP should be a bit mask including some or all of these bits:
5889 MOVE_TO_X: Stop on reaching x-position TO_X.
5890 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5891 Regardless of OP's value, stop in reaching the end of the display line.
5892
5893 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5894 This means, in particular, that TO_X includes window's horizontal
5895 scroll amount.
5896
5897 The return value has several possible values that
5898 say what condition caused the scan to stop:
5899
5900 MOVE_POS_MATCH_OR_ZV
5901 - when TO_POS or ZV was reached.
5902
5903 MOVE_X_REACHED
5904 -when TO_X was reached before TO_POS or ZV were reached.
5905
5906 MOVE_LINE_CONTINUED
5907 - when we reached the end of the display area and the line must
5908 be continued.
5909
5910 MOVE_LINE_TRUNCATED
5911 - when we reached the end of the display area and the line is
5912 truncated.
5913
5914 MOVE_NEWLINE_OR_CR
5915 - when we stopped at a line end, i.e. a newline or a CR and selective
5916 display is on. */
5917
5918 static enum move_it_result
5919 move_it_in_display_line_to (it, to_charpos, to_x, op)
5920 struct it *it;
5921 int to_charpos, to_x, op;
5922 {
5923 enum move_it_result result = MOVE_UNDEFINED;
5924 struct glyph_row *saved_glyph_row;
5925
5926 /* Don't produce glyphs in produce_glyphs. */
5927 saved_glyph_row = it->glyph_row;
5928 it->glyph_row = NULL;
5929
5930 #define BUFFER_POS_REACHED_P() \
5931 ((op & MOVE_TO_POS) != 0 \
5932 && BUFFERP (it->object) \
5933 && IT_CHARPOS (*it) >= to_charpos \
5934 && (it->method == GET_FROM_BUFFER \
5935 || (it->method == GET_FROM_DISPLAY_VECTOR \
5936 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
5937
5938
5939 while (1)
5940 {
5941 int x, i, ascent = 0, descent = 0;
5942
5943 /* Stop if we move beyond TO_CHARPOS (after an image or stretch glyph). */
5944 if ((op & MOVE_TO_POS) != 0
5945 && BUFFERP (it->object)
5946 && it->method == GET_FROM_BUFFER
5947 && IT_CHARPOS (*it) > to_charpos)
5948 {
5949 result = MOVE_POS_MATCH_OR_ZV;
5950 break;
5951 }
5952
5953 /* Stop when ZV reached.
5954 We used to stop here when TO_CHARPOS reached as well, but that is
5955 too soon if this glyph does not fit on this line. So we handle it
5956 explicitly below. */
5957 if (!get_next_display_element (it)
5958 || (it->truncate_lines_p
5959 && BUFFER_POS_REACHED_P ()))
5960 {
5961 result = MOVE_POS_MATCH_OR_ZV;
5962 break;
5963 }
5964
5965 /* The call to produce_glyphs will get the metrics of the
5966 display element IT is loaded with. We record in x the
5967 x-position before this display element in case it does not
5968 fit on the line. */
5969 x = it->current_x;
5970
5971 /* Remember the line height so far in case the next element doesn't
5972 fit on the line. */
5973 if (!it->truncate_lines_p)
5974 {
5975 ascent = it->max_ascent;
5976 descent = it->max_descent;
5977 }
5978
5979 PRODUCE_GLYPHS (it);
5980
5981 if (it->area != TEXT_AREA)
5982 {
5983 set_iterator_to_next (it, 1);
5984 continue;
5985 }
5986
5987 /* The number of glyphs we get back in IT->nglyphs will normally
5988 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5989 character on a terminal frame, or (iii) a line end. For the
5990 second case, IT->nglyphs - 1 padding glyphs will be present
5991 (on X frames, there is only one glyph produced for a
5992 composite character.
5993
5994 The behavior implemented below means, for continuation lines,
5995 that as many spaces of a TAB as fit on the current line are
5996 displayed there. For terminal frames, as many glyphs of a
5997 multi-glyph character are displayed in the current line, too.
5998 This is what the old redisplay code did, and we keep it that
5999 way. Under X, the whole shape of a complex character must
6000 fit on the line or it will be completely displayed in the
6001 next line.
6002
6003 Note that both for tabs and padding glyphs, all glyphs have
6004 the same width. */
6005 if (it->nglyphs)
6006 {
6007 /* More than one glyph or glyph doesn't fit on line. All
6008 glyphs have the same width. */
6009 int single_glyph_width = it->pixel_width / it->nglyphs;
6010 int new_x;
6011
6012 for (i = 0; i < it->nglyphs; ++i, x = new_x)
6013 {
6014 new_x = x + single_glyph_width;
6015
6016 /* We want to leave anything reaching TO_X to the caller. */
6017 if ((op & MOVE_TO_X) && new_x > to_x)
6018 {
6019 if (BUFFER_POS_REACHED_P ())
6020 goto buffer_pos_reached;
6021 it->current_x = x;
6022 result = MOVE_X_REACHED;
6023 break;
6024 }
6025 else if (/* Lines are continued. */
6026 !it->truncate_lines_p
6027 && (/* And glyph doesn't fit on the line. */
6028 new_x > it->last_visible_x
6029 /* Or it fits exactly and we're on a window
6030 system frame. */
6031 || (new_x == it->last_visible_x
6032 && FRAME_WINDOW_P (it->f))))
6033 {
6034 if (/* IT->hpos == 0 means the very first glyph
6035 doesn't fit on the line, e.g. a wide image. */
6036 it->hpos == 0
6037 || (new_x == it->last_visible_x
6038 && FRAME_WINDOW_P (it->f)))
6039 {
6040 ++it->hpos;
6041 it->current_x = new_x;
6042 if (i == it->nglyphs - 1)
6043 {
6044 set_iterator_to_next (it, 1);
6045 #ifdef HAVE_WINDOW_SYSTEM
6046 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6047 {
6048 if (!get_next_display_element (it))
6049 {
6050 result = MOVE_POS_MATCH_OR_ZV;
6051 break;
6052 }
6053 if (BUFFER_POS_REACHED_P ())
6054 {
6055 if (ITERATOR_AT_END_OF_LINE_P (it))
6056 result = MOVE_POS_MATCH_OR_ZV;
6057 else
6058 result = MOVE_LINE_CONTINUED;
6059 break;
6060 }
6061 if (ITERATOR_AT_END_OF_LINE_P (it))
6062 {
6063 result = MOVE_NEWLINE_OR_CR;
6064 break;
6065 }
6066 }
6067 #endif /* HAVE_WINDOW_SYSTEM */
6068 }
6069 }
6070 else
6071 {
6072 it->current_x = x;
6073 it->max_ascent = ascent;
6074 it->max_descent = descent;
6075 }
6076
6077 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6078 IT_CHARPOS (*it)));
6079 result = MOVE_LINE_CONTINUED;
6080 break;
6081 }
6082 else if (BUFFER_POS_REACHED_P ())
6083 goto buffer_pos_reached;
6084 else if (new_x > it->first_visible_x)
6085 {
6086 /* Glyph is visible. Increment number of glyphs that
6087 would be displayed. */
6088 ++it->hpos;
6089 }
6090 else
6091 {
6092 /* Glyph is completely off the left margin of the display
6093 area. Nothing to do. */
6094 }
6095 }
6096
6097 if (result != MOVE_UNDEFINED)
6098 break;
6099 }
6100 else if (BUFFER_POS_REACHED_P ())
6101 {
6102 buffer_pos_reached:
6103 it->current_x = x;
6104 it->max_ascent = ascent;
6105 it->max_descent = descent;
6106 result = MOVE_POS_MATCH_OR_ZV;
6107 break;
6108 }
6109 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6110 {
6111 /* Stop when TO_X specified and reached. This check is
6112 necessary here because of lines consisting of a line end,
6113 only. The line end will not produce any glyphs and we
6114 would never get MOVE_X_REACHED. */
6115 xassert (it->nglyphs == 0);
6116 result = MOVE_X_REACHED;
6117 break;
6118 }
6119
6120 /* Is this a line end? If yes, we're done. */
6121 if (ITERATOR_AT_END_OF_LINE_P (it))
6122 {
6123 result = MOVE_NEWLINE_OR_CR;
6124 break;
6125 }
6126
6127 /* The current display element has been consumed. Advance
6128 to the next. */
6129 set_iterator_to_next (it, 1);
6130
6131 /* Stop if lines are truncated and IT's current x-position is
6132 past the right edge of the window now. */
6133 if (it->truncate_lines_p
6134 && it->current_x >= it->last_visible_x)
6135 {
6136 #ifdef HAVE_WINDOW_SYSTEM
6137 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6138 {
6139 if (!get_next_display_element (it)
6140 || BUFFER_POS_REACHED_P ())
6141 {
6142 result = MOVE_POS_MATCH_OR_ZV;
6143 break;
6144 }
6145 if (ITERATOR_AT_END_OF_LINE_P (it))
6146 {
6147 result = MOVE_NEWLINE_OR_CR;
6148 break;
6149 }
6150 }
6151 #endif /* HAVE_WINDOW_SYSTEM */
6152 result = MOVE_LINE_TRUNCATED;
6153 break;
6154 }
6155 }
6156
6157 #undef BUFFER_POS_REACHED_P
6158
6159 /* Restore the iterator settings altered at the beginning of this
6160 function. */
6161 it->glyph_row = saved_glyph_row;
6162 return result;
6163 }
6164
6165
6166 /* Move IT forward until it satisfies one or more of the criteria in
6167 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6168
6169 OP is a bit-mask that specifies where to stop, and in particular,
6170 which of those four position arguments makes a difference. See the
6171 description of enum move_operation_enum.
6172
6173 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6174 screen line, this function will set IT to the next position >
6175 TO_CHARPOS. */
6176
6177 void
6178 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6179 struct it *it;
6180 int to_charpos, to_x, to_y, to_vpos;
6181 int op;
6182 {
6183 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6184 int line_height;
6185 int reached = 0;
6186
6187 for (;;)
6188 {
6189 if (op & MOVE_TO_VPOS)
6190 {
6191 /* If no TO_CHARPOS and no TO_X specified, stop at the
6192 start of the line TO_VPOS. */
6193 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6194 {
6195 if (it->vpos == to_vpos)
6196 {
6197 reached = 1;
6198 break;
6199 }
6200 else
6201 skip = move_it_in_display_line_to (it, -1, -1, 0);
6202 }
6203 else
6204 {
6205 /* TO_VPOS >= 0 means stop at TO_X in the line at
6206 TO_VPOS, or at TO_POS, whichever comes first. */
6207 if (it->vpos == to_vpos)
6208 {
6209 reached = 2;
6210 break;
6211 }
6212
6213 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6214
6215 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6216 {
6217 reached = 3;
6218 break;
6219 }
6220 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6221 {
6222 /* We have reached TO_X but not in the line we want. */
6223 skip = move_it_in_display_line_to (it, to_charpos,
6224 -1, MOVE_TO_POS);
6225 if (skip == MOVE_POS_MATCH_OR_ZV)
6226 {
6227 reached = 4;
6228 break;
6229 }
6230 }
6231 }
6232 }
6233 else if (op & MOVE_TO_Y)
6234 {
6235 struct it it_backup;
6236
6237 /* TO_Y specified means stop at TO_X in the line containing
6238 TO_Y---or at TO_CHARPOS if this is reached first. The
6239 problem is that we can't really tell whether the line
6240 contains TO_Y before we have completely scanned it, and
6241 this may skip past TO_X. What we do is to first scan to
6242 TO_X.
6243
6244 If TO_X is not specified, use a TO_X of zero. The reason
6245 is to make the outcome of this function more predictable.
6246 If we didn't use TO_X == 0, we would stop at the end of
6247 the line which is probably not what a caller would expect
6248 to happen. */
6249 skip = move_it_in_display_line_to (it, to_charpos,
6250 ((op & MOVE_TO_X)
6251 ? to_x : 0),
6252 (MOVE_TO_X
6253 | (op & MOVE_TO_POS)));
6254
6255 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6256 if (skip == MOVE_POS_MATCH_OR_ZV)
6257 {
6258 reached = 5;
6259 break;
6260 }
6261
6262 /* If TO_X was reached, we would like to know whether TO_Y
6263 is in the line. This can only be said if we know the
6264 total line height which requires us to scan the rest of
6265 the line. */
6266 if (skip == MOVE_X_REACHED)
6267 {
6268 it_backup = *it;
6269 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6270 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6271 op & MOVE_TO_POS);
6272 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6273 }
6274
6275 /* Now, decide whether TO_Y is in this line. */
6276 line_height = it->max_ascent + it->max_descent;
6277 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6278
6279 if (to_y >= it->current_y
6280 && to_y < it->current_y + line_height)
6281 {
6282 if (skip == MOVE_X_REACHED)
6283 /* If TO_Y is in this line and TO_X was reached above,
6284 we scanned too far. We have to restore IT's settings
6285 to the ones before skipping. */
6286 *it = it_backup;
6287 reached = 6;
6288 }
6289 else if (skip == MOVE_X_REACHED)
6290 {
6291 skip = skip2;
6292 if (skip == MOVE_POS_MATCH_OR_ZV)
6293 reached = 7;
6294 }
6295
6296 if (reached)
6297 break;
6298 }
6299 else
6300 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6301
6302 switch (skip)
6303 {
6304 case MOVE_POS_MATCH_OR_ZV:
6305 reached = 8;
6306 goto out;
6307
6308 case MOVE_NEWLINE_OR_CR:
6309 set_iterator_to_next (it, 1);
6310 it->continuation_lines_width = 0;
6311 break;
6312
6313 case MOVE_LINE_TRUNCATED:
6314 it->continuation_lines_width = 0;
6315 reseat_at_next_visible_line_start (it, 0);
6316 if ((op & MOVE_TO_POS) != 0
6317 && IT_CHARPOS (*it) > to_charpos)
6318 {
6319 reached = 9;
6320 goto out;
6321 }
6322 break;
6323
6324 case MOVE_LINE_CONTINUED:
6325 it->continuation_lines_width += it->current_x;
6326 break;
6327
6328 default:
6329 abort ();
6330 }
6331
6332 /* Reset/increment for the next run. */
6333 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6334 it->current_x = it->hpos = 0;
6335 it->current_y += it->max_ascent + it->max_descent;
6336 ++it->vpos;
6337 last_height = it->max_ascent + it->max_descent;
6338 last_max_ascent = it->max_ascent;
6339 it->max_ascent = it->max_descent = 0;
6340 }
6341
6342 out:
6343
6344 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6345 }
6346
6347
6348 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6349
6350 If DY > 0, move IT backward at least that many pixels. DY = 0
6351 means move IT backward to the preceding line start or BEGV. This
6352 function may move over more than DY pixels if IT->current_y - DY
6353 ends up in the middle of a line; in this case IT->current_y will be
6354 set to the top of the line moved to. */
6355
6356 void
6357 move_it_vertically_backward (it, dy)
6358 struct it *it;
6359 int dy;
6360 {
6361 int nlines, h;
6362 struct it it2, it3;
6363 int start_pos;
6364
6365 move_further_back:
6366 xassert (dy >= 0);
6367
6368 start_pos = IT_CHARPOS (*it);
6369
6370 /* Estimate how many newlines we must move back. */
6371 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6372
6373 /* Set the iterator's position that many lines back. */
6374 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6375 back_to_previous_visible_line_start (it);
6376
6377 /* Reseat the iterator here. When moving backward, we don't want
6378 reseat to skip forward over invisible text, set up the iterator
6379 to deliver from overlay strings at the new position etc. So,
6380 use reseat_1 here. */
6381 reseat_1 (it, it->current.pos, 1);
6382
6383 /* We are now surely at a line start. */
6384 it->current_x = it->hpos = 0;
6385 it->continuation_lines_width = 0;
6386
6387 /* Move forward and see what y-distance we moved. First move to the
6388 start of the next line so that we get its height. We need this
6389 height to be able to tell whether we reached the specified
6390 y-distance. */
6391 it2 = *it;
6392 it2.max_ascent = it2.max_descent = 0;
6393 do
6394 {
6395 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6396 MOVE_TO_POS | MOVE_TO_VPOS);
6397 }
6398 while (!IT_POS_VALID_AFTER_MOVE_P (&it2));
6399 xassert (IT_CHARPOS (*it) >= BEGV);
6400 it3 = it2;
6401
6402 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6403 xassert (IT_CHARPOS (*it) >= BEGV);
6404 /* H is the actual vertical distance from the position in *IT
6405 and the starting position. */
6406 h = it2.current_y - it->current_y;
6407 /* NLINES is the distance in number of lines. */
6408 nlines = it2.vpos - it->vpos;
6409
6410 /* Correct IT's y and vpos position
6411 so that they are relative to the starting point. */
6412 it->vpos -= nlines;
6413 it->current_y -= h;
6414
6415 if (dy == 0)
6416 {
6417 /* DY == 0 means move to the start of the screen line. The
6418 value of nlines is > 0 if continuation lines were involved. */
6419 if (nlines > 0)
6420 move_it_by_lines (it, nlines, 1);
6421 #if 0
6422 /* I think this assert is bogus if buffer contains
6423 invisible text or images. KFS. */
6424 xassert (IT_CHARPOS (*it) <= start_pos);
6425 #endif
6426 }
6427 else
6428 {
6429 /* The y-position we try to reach, relative to *IT.
6430 Note that H has been subtracted in front of the if-statement. */
6431 int target_y = it->current_y + h - dy;
6432 int y0 = it3.current_y;
6433 int y1 = line_bottom_y (&it3);
6434 int line_height = y1 - y0;
6435
6436 /* If we did not reach target_y, try to move further backward if
6437 we can. If we moved too far backward, try to move forward. */
6438 if (target_y < it->current_y
6439 /* This is heuristic. In a window that's 3 lines high, with
6440 a line height of 13 pixels each, recentering with point
6441 on the bottom line will try to move -39/2 = 19 pixels
6442 backward. Try to avoid moving into the first line. */
6443 && (it->current_y - target_y
6444 > min (window_box_height (it->w), line_height * 2 / 3))
6445 && IT_CHARPOS (*it) > BEGV)
6446 {
6447 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6448 target_y - it->current_y));
6449 dy = it->current_y - target_y;
6450 goto move_further_back;
6451 }
6452 else if (target_y >= it->current_y + line_height
6453 && IT_CHARPOS (*it) < ZV)
6454 {
6455 /* Should move forward by at least one line, maybe more.
6456
6457 Note: Calling move_it_by_lines can be expensive on
6458 terminal frames, where compute_motion is used (via
6459 vmotion) to do the job, when there are very long lines
6460 and truncate-lines is nil. That's the reason for
6461 treating terminal frames specially here. */
6462
6463 if (!FRAME_WINDOW_P (it->f))
6464 move_it_vertically (it, target_y - (it->current_y + line_height));
6465 else
6466 {
6467 do
6468 {
6469 move_it_by_lines (it, 1, 1);
6470 }
6471 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6472 }
6473
6474 #if 0
6475 /* I think this assert is bogus if buffer contains
6476 invisible text or images. KFS. */
6477 xassert (IT_CHARPOS (*it) >= BEGV);
6478 #endif
6479 }
6480 }
6481 }
6482
6483
6484 /* Move IT by a specified amount of pixel lines DY. DY negative means
6485 move backwards. DY = 0 means move to start of screen line. At the
6486 end, IT will be on the start of a screen line. */
6487
6488 void
6489 move_it_vertically (it, dy)
6490 struct it *it;
6491 int dy;
6492 {
6493 if (dy <= 0)
6494 move_it_vertically_backward (it, -dy);
6495 else
6496 {
6497 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6498 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6499 MOVE_TO_POS | MOVE_TO_Y);
6500 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6501
6502 /* If buffer ends in ZV without a newline, move to the start of
6503 the line to satisfy the post-condition. */
6504 if (IT_CHARPOS (*it) == ZV
6505 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6506 move_it_by_lines (it, 0, 0);
6507 }
6508 }
6509
6510
6511 /* Move iterator IT past the end of the text line it is in. */
6512
6513 void
6514 move_it_past_eol (it)
6515 struct it *it;
6516 {
6517 enum move_it_result rc;
6518
6519 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6520 if (rc == MOVE_NEWLINE_OR_CR)
6521 set_iterator_to_next (it, 0);
6522 }
6523
6524
6525 #if 0 /* Currently not used. */
6526
6527 /* Return non-zero if some text between buffer positions START_CHARPOS
6528 and END_CHARPOS is invisible. IT->window is the window for text
6529 property lookup. */
6530
6531 static int
6532 invisible_text_between_p (it, start_charpos, end_charpos)
6533 struct it *it;
6534 int start_charpos, end_charpos;
6535 {
6536 Lisp_Object prop, limit;
6537 int invisible_found_p;
6538
6539 xassert (it != NULL && start_charpos <= end_charpos);
6540
6541 /* Is text at START invisible? */
6542 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6543 it->window);
6544 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6545 invisible_found_p = 1;
6546 else
6547 {
6548 limit = Fnext_single_char_property_change (make_number (start_charpos),
6549 Qinvisible, Qnil,
6550 make_number (end_charpos));
6551 invisible_found_p = XFASTINT (limit) < end_charpos;
6552 }
6553
6554 return invisible_found_p;
6555 }
6556
6557 #endif /* 0 */
6558
6559
6560 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6561 negative means move up. DVPOS == 0 means move to the start of the
6562 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6563 NEED_Y_P is zero, IT->current_y will be left unchanged.
6564
6565 Further optimization ideas: If we would know that IT->f doesn't use
6566 a face with proportional font, we could be faster for
6567 truncate-lines nil. */
6568
6569 void
6570 move_it_by_lines (it, dvpos, need_y_p)
6571 struct it *it;
6572 int dvpos, need_y_p;
6573 {
6574 struct position pos;
6575
6576 if (!FRAME_WINDOW_P (it->f))
6577 {
6578 struct text_pos textpos;
6579
6580 /* We can use vmotion on frames without proportional fonts. */
6581 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6582 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6583 reseat (it, textpos, 1);
6584 it->vpos += pos.vpos;
6585 it->current_y += pos.vpos;
6586 }
6587 else if (dvpos == 0)
6588 {
6589 /* DVPOS == 0 means move to the start of the screen line. */
6590 move_it_vertically_backward (it, 0);
6591 xassert (it->current_x == 0 && it->hpos == 0);
6592 /* Let next call to line_bottom_y calculate real line height */
6593 last_height = 0;
6594 }
6595 else if (dvpos > 0)
6596 {
6597 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6598 if (!IT_POS_VALID_AFTER_MOVE_P (it))
6599 move_it_to (it, IT_CHARPOS (*it) + 1, -1, -1, -1, MOVE_TO_POS);
6600 }
6601 else
6602 {
6603 struct it it2;
6604 int start_charpos, i;
6605
6606 /* Start at the beginning of the screen line containing IT's
6607 position. This may actually move vertically backwards,
6608 in case of overlays, so adjust dvpos accordingly. */
6609 dvpos += it->vpos;
6610 move_it_vertically_backward (it, 0);
6611 dvpos -= it->vpos;
6612
6613 /* Go back -DVPOS visible lines and reseat the iterator there. */
6614 start_charpos = IT_CHARPOS (*it);
6615 for (i = -dvpos; i > 0 && IT_CHARPOS (*it) > BEGV; --i)
6616 back_to_previous_visible_line_start (it);
6617 reseat (it, it->current.pos, 1);
6618
6619 /* Move further back if we end up in a string or an image. */
6620 while (!IT_POS_VALID_AFTER_MOVE_P (it))
6621 {
6622 /* First try to move to start of display line. */
6623 dvpos += it->vpos;
6624 move_it_vertically_backward (it, 0);
6625 dvpos -= it->vpos;
6626 if (IT_POS_VALID_AFTER_MOVE_P (it))
6627 break;
6628 /* If start of line is still in string or image,
6629 move further back. */
6630 back_to_previous_visible_line_start (it);
6631 reseat (it, it->current.pos, 1);
6632 dvpos--;
6633 }
6634
6635 it->current_x = it->hpos = 0;
6636
6637 /* Above call may have moved too far if continuation lines
6638 are involved. Scan forward and see if it did. */
6639 it2 = *it;
6640 it2.vpos = it2.current_y = 0;
6641 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6642 it->vpos -= it2.vpos;
6643 it->current_y -= it2.current_y;
6644 it->current_x = it->hpos = 0;
6645
6646 /* If we moved too far back, move IT some lines forward. */
6647 if (it2.vpos > -dvpos)
6648 {
6649 int delta = it2.vpos + dvpos;
6650 it2 = *it;
6651 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6652 /* Move back again if we got too far ahead. */
6653 if (IT_CHARPOS (*it) >= start_charpos)
6654 *it = it2;
6655 }
6656 }
6657 }
6658
6659 /* Return 1 if IT points into the middle of a display vector. */
6660
6661 int
6662 in_display_vector_p (it)
6663 struct it *it;
6664 {
6665 return (it->method == GET_FROM_DISPLAY_VECTOR
6666 && it->current.dpvec_index > 0
6667 && it->dpvec + it->current.dpvec_index != it->dpend);
6668 }
6669
6670 \f
6671 /***********************************************************************
6672 Messages
6673 ***********************************************************************/
6674
6675
6676 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6677 to *Messages*. */
6678
6679 void
6680 add_to_log (format, arg1, arg2)
6681 char *format;
6682 Lisp_Object arg1, arg2;
6683 {
6684 Lisp_Object args[3];
6685 Lisp_Object msg, fmt;
6686 char *buffer;
6687 int len;
6688 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6689 USE_SAFE_ALLOCA;
6690
6691 /* Do nothing if called asynchronously. Inserting text into
6692 a buffer may call after-change-functions and alike and
6693 that would means running Lisp asynchronously. */
6694 if (handling_signal)
6695 return;
6696
6697 fmt = msg = Qnil;
6698 GCPRO4 (fmt, msg, arg1, arg2);
6699
6700 args[0] = fmt = build_string (format);
6701 args[1] = arg1;
6702 args[2] = arg2;
6703 msg = Fformat (3, args);
6704
6705 len = SBYTES (msg) + 1;
6706 SAFE_ALLOCA (buffer, char *, len);
6707 bcopy (SDATA (msg), buffer, len);
6708
6709 message_dolog (buffer, len - 1, 1, 0);
6710 SAFE_FREE ();
6711
6712 UNGCPRO;
6713 }
6714
6715
6716 /* Output a newline in the *Messages* buffer if "needs" one. */
6717
6718 void
6719 message_log_maybe_newline ()
6720 {
6721 if (message_log_need_newline)
6722 message_dolog ("", 0, 1, 0);
6723 }
6724
6725
6726 /* Add a string M of length NBYTES to the message log, optionally
6727 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6728 nonzero, means interpret the contents of M as multibyte. This
6729 function calls low-level routines in order to bypass text property
6730 hooks, etc. which might not be safe to run. */
6731
6732 void
6733 message_dolog (m, nbytes, nlflag, multibyte)
6734 const char *m;
6735 int nbytes, nlflag, multibyte;
6736 {
6737 if (!NILP (Vmemory_full))
6738 return;
6739
6740 if (!NILP (Vmessage_log_max))
6741 {
6742 struct buffer *oldbuf;
6743 Lisp_Object oldpoint, oldbegv, oldzv;
6744 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6745 int point_at_end = 0;
6746 int zv_at_end = 0;
6747 Lisp_Object old_deactivate_mark, tem;
6748 struct gcpro gcpro1;
6749
6750 old_deactivate_mark = Vdeactivate_mark;
6751 oldbuf = current_buffer;
6752 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6753 current_buffer->undo_list = Qt;
6754
6755 oldpoint = message_dolog_marker1;
6756 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6757 oldbegv = message_dolog_marker2;
6758 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6759 oldzv = message_dolog_marker3;
6760 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6761 GCPRO1 (old_deactivate_mark);
6762
6763 if (PT == Z)
6764 point_at_end = 1;
6765 if (ZV == Z)
6766 zv_at_end = 1;
6767
6768 BEGV = BEG;
6769 BEGV_BYTE = BEG_BYTE;
6770 ZV = Z;
6771 ZV_BYTE = Z_BYTE;
6772 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6773
6774 /* Insert the string--maybe converting multibyte to single byte
6775 or vice versa, so that all the text fits the buffer. */
6776 if (multibyte
6777 && NILP (current_buffer->enable_multibyte_characters))
6778 {
6779 int i, c, char_bytes;
6780 unsigned char work[1];
6781
6782 /* Convert a multibyte string to single-byte
6783 for the *Message* buffer. */
6784 for (i = 0; i < nbytes; i += char_bytes)
6785 {
6786 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6787 work[0] = (SINGLE_BYTE_CHAR_P (c)
6788 ? c
6789 : multibyte_char_to_unibyte (c, Qnil));
6790 insert_1_both (work, 1, 1, 1, 0, 0);
6791 }
6792 }
6793 else if (! multibyte
6794 && ! NILP (current_buffer->enable_multibyte_characters))
6795 {
6796 int i, c, char_bytes;
6797 unsigned char *msg = (unsigned char *) m;
6798 unsigned char str[MAX_MULTIBYTE_LENGTH];
6799 /* Convert a single-byte string to multibyte
6800 for the *Message* buffer. */
6801 for (i = 0; i < nbytes; i++)
6802 {
6803 c = unibyte_char_to_multibyte (msg[i]);
6804 char_bytes = CHAR_STRING (c, str);
6805 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6806 }
6807 }
6808 else if (nbytes)
6809 insert_1 (m, nbytes, 1, 0, 0);
6810
6811 if (nlflag)
6812 {
6813 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6814 insert_1 ("\n", 1, 1, 0, 0);
6815
6816 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6817 this_bol = PT;
6818 this_bol_byte = PT_BYTE;
6819
6820 /* See if this line duplicates the previous one.
6821 If so, combine duplicates. */
6822 if (this_bol > BEG)
6823 {
6824 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6825 prev_bol = PT;
6826 prev_bol_byte = PT_BYTE;
6827
6828 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6829 this_bol, this_bol_byte);
6830 if (dup)
6831 {
6832 del_range_both (prev_bol, prev_bol_byte,
6833 this_bol, this_bol_byte, 0);
6834 if (dup > 1)
6835 {
6836 char dupstr[40];
6837 int duplen;
6838
6839 /* If you change this format, don't forget to also
6840 change message_log_check_duplicate. */
6841 sprintf (dupstr, " [%d times]", dup);
6842 duplen = strlen (dupstr);
6843 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6844 insert_1 (dupstr, duplen, 1, 0, 1);
6845 }
6846 }
6847 }
6848
6849 /* If we have more than the desired maximum number of lines
6850 in the *Messages* buffer now, delete the oldest ones.
6851 This is safe because we don't have undo in this buffer. */
6852
6853 if (NATNUMP (Vmessage_log_max))
6854 {
6855 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6856 -XFASTINT (Vmessage_log_max) - 1, 0);
6857 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6858 }
6859 }
6860 BEGV = XMARKER (oldbegv)->charpos;
6861 BEGV_BYTE = marker_byte_position (oldbegv);
6862
6863 if (zv_at_end)
6864 {
6865 ZV = Z;
6866 ZV_BYTE = Z_BYTE;
6867 }
6868 else
6869 {
6870 ZV = XMARKER (oldzv)->charpos;
6871 ZV_BYTE = marker_byte_position (oldzv);
6872 }
6873
6874 if (point_at_end)
6875 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6876 else
6877 /* We can't do Fgoto_char (oldpoint) because it will run some
6878 Lisp code. */
6879 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6880 XMARKER (oldpoint)->bytepos);
6881
6882 UNGCPRO;
6883 unchain_marker (XMARKER (oldpoint));
6884 unchain_marker (XMARKER (oldbegv));
6885 unchain_marker (XMARKER (oldzv));
6886
6887 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6888 set_buffer_internal (oldbuf);
6889 if (NILP (tem))
6890 windows_or_buffers_changed = old_windows_or_buffers_changed;
6891 message_log_need_newline = !nlflag;
6892 Vdeactivate_mark = old_deactivate_mark;
6893 }
6894 }
6895
6896
6897 /* We are at the end of the buffer after just having inserted a newline.
6898 (Note: We depend on the fact we won't be crossing the gap.)
6899 Check to see if the most recent message looks a lot like the previous one.
6900 Return 0 if different, 1 if the new one should just replace it, or a
6901 value N > 1 if we should also append " [N times]". */
6902
6903 static int
6904 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6905 int prev_bol, this_bol;
6906 int prev_bol_byte, this_bol_byte;
6907 {
6908 int i;
6909 int len = Z_BYTE - 1 - this_bol_byte;
6910 int seen_dots = 0;
6911 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6912 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6913
6914 for (i = 0; i < len; i++)
6915 {
6916 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6917 seen_dots = 1;
6918 if (p1[i] != p2[i])
6919 return seen_dots;
6920 }
6921 p1 += len;
6922 if (*p1 == '\n')
6923 return 2;
6924 if (*p1++ == ' ' && *p1++ == '[')
6925 {
6926 int n = 0;
6927 while (*p1 >= '0' && *p1 <= '9')
6928 n = n * 10 + *p1++ - '0';
6929 if (strncmp (p1, " times]\n", 8) == 0)
6930 return n+1;
6931 }
6932 return 0;
6933 }
6934 \f
6935
6936 /* Display an echo area message M with a specified length of NBYTES
6937 bytes. The string may include null characters. If M is 0, clear
6938 out any existing message, and let the mini-buffer text show
6939 through.
6940
6941 The buffer M must continue to exist until after the echo area gets
6942 cleared or some other message gets displayed there. This means do
6943 not pass text that is stored in a Lisp string; do not pass text in
6944 a buffer that was alloca'd. */
6945
6946 void
6947 message2 (m, nbytes, multibyte)
6948 const char *m;
6949 int nbytes;
6950 int multibyte;
6951 {
6952 /* First flush out any partial line written with print. */
6953 message_log_maybe_newline ();
6954 if (m)
6955 message_dolog (m, nbytes, 1, multibyte);
6956 message2_nolog (m, nbytes, multibyte);
6957 }
6958
6959
6960 /* The non-logging counterpart of message2. */
6961
6962 void
6963 message2_nolog (m, nbytes, multibyte)
6964 const char *m;
6965 int nbytes, multibyte;
6966 {
6967 struct frame *sf = SELECTED_FRAME ();
6968 message_enable_multibyte = multibyte;
6969
6970 if (noninteractive)
6971 {
6972 if (noninteractive_need_newline)
6973 putc ('\n', stderr);
6974 noninteractive_need_newline = 0;
6975 if (m)
6976 fwrite (m, nbytes, 1, stderr);
6977 if (cursor_in_echo_area == 0)
6978 fprintf (stderr, "\n");
6979 fflush (stderr);
6980 }
6981 /* A null message buffer means that the frame hasn't really been
6982 initialized yet. Error messages get reported properly by
6983 cmd_error, so this must be just an informative message; toss it. */
6984 else if (INTERACTIVE
6985 && sf->glyphs_initialized_p
6986 && FRAME_MESSAGE_BUF (sf))
6987 {
6988 Lisp_Object mini_window;
6989 struct frame *f;
6990
6991 /* Get the frame containing the mini-buffer
6992 that the selected frame is using. */
6993 mini_window = FRAME_MINIBUF_WINDOW (sf);
6994 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6995
6996 FRAME_SAMPLE_VISIBILITY (f);
6997 if (FRAME_VISIBLE_P (sf)
6998 && ! FRAME_VISIBLE_P (f))
6999 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
7000
7001 if (m)
7002 {
7003 set_message (m, Qnil, nbytes, multibyte);
7004 if (minibuffer_auto_raise)
7005 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7006 }
7007 else
7008 clear_message (1, 1);
7009
7010 do_pending_window_change (0);
7011 echo_area_display (1);
7012 do_pending_window_change (0);
7013 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7014 (*frame_up_to_date_hook) (f);
7015 }
7016 }
7017
7018
7019 /* Display an echo area message M with a specified length of NBYTES
7020 bytes. The string may include null characters. If M is not a
7021 string, clear out any existing message, and let the mini-buffer
7022 text show through.
7023
7024 This function cancels echoing. */
7025
7026 void
7027 message3 (m, nbytes, multibyte)
7028 Lisp_Object m;
7029 int nbytes;
7030 int multibyte;
7031 {
7032 struct gcpro gcpro1;
7033
7034 GCPRO1 (m);
7035 clear_message (1,1);
7036 cancel_echoing ();
7037
7038 /* First flush out any partial line written with print. */
7039 message_log_maybe_newline ();
7040 if (STRINGP (m))
7041 message_dolog (SDATA (m), nbytes, 1, multibyte);
7042 message3_nolog (m, nbytes, multibyte);
7043
7044 UNGCPRO;
7045 }
7046
7047
7048 /* The non-logging version of message3.
7049 This does not cancel echoing, because it is used for echoing.
7050 Perhaps we need to make a separate function for echoing
7051 and make this cancel echoing. */
7052
7053 void
7054 message3_nolog (m, nbytes, multibyte)
7055 Lisp_Object m;
7056 int nbytes, multibyte;
7057 {
7058 struct frame *sf = SELECTED_FRAME ();
7059 message_enable_multibyte = multibyte;
7060
7061 if (noninteractive)
7062 {
7063 if (noninteractive_need_newline)
7064 putc ('\n', stderr);
7065 noninteractive_need_newline = 0;
7066 if (STRINGP (m))
7067 fwrite (SDATA (m), nbytes, 1, stderr);
7068 if (cursor_in_echo_area == 0)
7069 fprintf (stderr, "\n");
7070 fflush (stderr);
7071 }
7072 /* A null message buffer means that the frame hasn't really been
7073 initialized yet. Error messages get reported properly by
7074 cmd_error, so this must be just an informative message; toss it. */
7075 else if (INTERACTIVE
7076 && sf->glyphs_initialized_p
7077 && FRAME_MESSAGE_BUF (sf))
7078 {
7079 Lisp_Object mini_window;
7080 Lisp_Object frame;
7081 struct frame *f;
7082
7083 /* Get the frame containing the mini-buffer
7084 that the selected frame is using. */
7085 mini_window = FRAME_MINIBUF_WINDOW (sf);
7086 frame = XWINDOW (mini_window)->frame;
7087 f = XFRAME (frame);
7088
7089 FRAME_SAMPLE_VISIBILITY (f);
7090 if (FRAME_VISIBLE_P (sf)
7091 && !FRAME_VISIBLE_P (f))
7092 Fmake_frame_visible (frame);
7093
7094 if (STRINGP (m) && SCHARS (m) > 0)
7095 {
7096 set_message (NULL, m, nbytes, multibyte);
7097 if (minibuffer_auto_raise)
7098 Fraise_frame (frame);
7099 }
7100 else
7101 clear_message (1, 1);
7102
7103 do_pending_window_change (0);
7104 echo_area_display (1);
7105 do_pending_window_change (0);
7106 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7107 (*frame_up_to_date_hook) (f);
7108 }
7109 }
7110
7111
7112 /* Display a null-terminated echo area message M. If M is 0, clear
7113 out any existing message, and let the mini-buffer text show through.
7114
7115 The buffer M must continue to exist until after the echo area gets
7116 cleared or some other message gets displayed there. Do not pass
7117 text that is stored in a Lisp string. Do not pass text in a buffer
7118 that was alloca'd. */
7119
7120 void
7121 message1 (m)
7122 char *m;
7123 {
7124 message2 (m, (m ? strlen (m) : 0), 0);
7125 }
7126
7127
7128 /* The non-logging counterpart of message1. */
7129
7130 void
7131 message1_nolog (m)
7132 char *m;
7133 {
7134 message2_nolog (m, (m ? strlen (m) : 0), 0);
7135 }
7136
7137 /* Display a message M which contains a single %s
7138 which gets replaced with STRING. */
7139
7140 void
7141 message_with_string (m, string, log)
7142 char *m;
7143 Lisp_Object string;
7144 int log;
7145 {
7146 CHECK_STRING (string);
7147
7148 if (noninteractive)
7149 {
7150 if (m)
7151 {
7152 if (noninteractive_need_newline)
7153 putc ('\n', stderr);
7154 noninteractive_need_newline = 0;
7155 fprintf (stderr, m, SDATA (string));
7156 if (cursor_in_echo_area == 0)
7157 fprintf (stderr, "\n");
7158 fflush (stderr);
7159 }
7160 }
7161 else if (INTERACTIVE)
7162 {
7163 /* The frame whose minibuffer we're going to display the message on.
7164 It may be larger than the selected frame, so we need
7165 to use its buffer, not the selected frame's buffer. */
7166 Lisp_Object mini_window;
7167 struct frame *f, *sf = SELECTED_FRAME ();
7168
7169 /* Get the frame containing the minibuffer
7170 that the selected frame is using. */
7171 mini_window = FRAME_MINIBUF_WINDOW (sf);
7172 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7173
7174 /* A null message buffer means that the frame hasn't really been
7175 initialized yet. Error messages get reported properly by
7176 cmd_error, so this must be just an informative message; toss it. */
7177 if (FRAME_MESSAGE_BUF (f))
7178 {
7179 Lisp_Object args[2], message;
7180 struct gcpro gcpro1, gcpro2;
7181
7182 args[0] = build_string (m);
7183 args[1] = message = string;
7184 GCPRO2 (args[0], message);
7185 gcpro1.nvars = 2;
7186
7187 message = Fformat (2, args);
7188
7189 if (log)
7190 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7191 else
7192 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7193
7194 UNGCPRO;
7195
7196 /* Print should start at the beginning of the message
7197 buffer next time. */
7198 message_buf_print = 0;
7199 }
7200 }
7201 }
7202
7203
7204 /* Dump an informative message to the minibuf. If M is 0, clear out
7205 any existing message, and let the mini-buffer text show through. */
7206
7207 /* VARARGS 1 */
7208 void
7209 message (m, a1, a2, a3)
7210 char *m;
7211 EMACS_INT a1, a2, a3;
7212 {
7213 if (noninteractive)
7214 {
7215 if (m)
7216 {
7217 if (noninteractive_need_newline)
7218 putc ('\n', stderr);
7219 noninteractive_need_newline = 0;
7220 fprintf (stderr, m, a1, a2, a3);
7221 if (cursor_in_echo_area == 0)
7222 fprintf (stderr, "\n");
7223 fflush (stderr);
7224 }
7225 }
7226 else if (INTERACTIVE)
7227 {
7228 /* The frame whose mini-buffer we're going to display the message
7229 on. It may be larger than the selected frame, so we need to
7230 use its buffer, not the selected frame's buffer. */
7231 Lisp_Object mini_window;
7232 struct frame *f, *sf = SELECTED_FRAME ();
7233
7234 /* Get the frame containing the mini-buffer
7235 that the selected frame is using. */
7236 mini_window = FRAME_MINIBUF_WINDOW (sf);
7237 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7238
7239 /* A null message buffer means that the frame hasn't really been
7240 initialized yet. Error messages get reported properly by
7241 cmd_error, so this must be just an informative message; toss
7242 it. */
7243 if (FRAME_MESSAGE_BUF (f))
7244 {
7245 if (m)
7246 {
7247 int len;
7248 #ifdef NO_ARG_ARRAY
7249 char *a[3];
7250 a[0] = (char *) a1;
7251 a[1] = (char *) a2;
7252 a[2] = (char *) a3;
7253
7254 len = doprnt (FRAME_MESSAGE_BUF (f),
7255 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7256 #else
7257 len = doprnt (FRAME_MESSAGE_BUF (f),
7258 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7259 (char **) &a1);
7260 #endif /* NO_ARG_ARRAY */
7261
7262 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7263 }
7264 else
7265 message1 (0);
7266
7267 /* Print should start at the beginning of the message
7268 buffer next time. */
7269 message_buf_print = 0;
7270 }
7271 }
7272 }
7273
7274
7275 /* The non-logging version of message. */
7276
7277 void
7278 message_nolog (m, a1, a2, a3)
7279 char *m;
7280 EMACS_INT a1, a2, a3;
7281 {
7282 Lisp_Object old_log_max;
7283 old_log_max = Vmessage_log_max;
7284 Vmessage_log_max = Qnil;
7285 message (m, a1, a2, a3);
7286 Vmessage_log_max = old_log_max;
7287 }
7288
7289
7290 /* Display the current message in the current mini-buffer. This is
7291 only called from error handlers in process.c, and is not time
7292 critical. */
7293
7294 void
7295 update_echo_area ()
7296 {
7297 if (!NILP (echo_area_buffer[0]))
7298 {
7299 Lisp_Object string;
7300 string = Fcurrent_message ();
7301 message3 (string, SBYTES (string),
7302 !NILP (current_buffer->enable_multibyte_characters));
7303 }
7304 }
7305
7306
7307 /* Make sure echo area buffers in `echo_buffers' are live.
7308 If they aren't, make new ones. */
7309
7310 static void
7311 ensure_echo_area_buffers ()
7312 {
7313 int i;
7314
7315 for (i = 0; i < 2; ++i)
7316 if (!BUFFERP (echo_buffer[i])
7317 || NILP (XBUFFER (echo_buffer[i])->name))
7318 {
7319 char name[30];
7320 Lisp_Object old_buffer;
7321 int j;
7322
7323 old_buffer = echo_buffer[i];
7324 sprintf (name, " *Echo Area %d*", i);
7325 echo_buffer[i] = Fget_buffer_create (build_string (name));
7326 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7327
7328 for (j = 0; j < 2; ++j)
7329 if (EQ (old_buffer, echo_area_buffer[j]))
7330 echo_area_buffer[j] = echo_buffer[i];
7331 }
7332 }
7333
7334
7335 /* Call FN with args A1..A4 with either the current or last displayed
7336 echo_area_buffer as current buffer.
7337
7338 WHICH zero means use the current message buffer
7339 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7340 from echo_buffer[] and clear it.
7341
7342 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7343 suitable buffer from echo_buffer[] and clear it.
7344
7345 Value is what FN returns. */
7346
7347 static int
7348 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7349 struct window *w;
7350 int which;
7351 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7352 EMACS_INT a1;
7353 Lisp_Object a2;
7354 EMACS_INT a3, a4;
7355 {
7356 Lisp_Object buffer;
7357 int this_one, the_other, clear_buffer_p, rc;
7358 int count = SPECPDL_INDEX ();
7359
7360 /* If buffers aren't live, make new ones. */
7361 ensure_echo_area_buffers ();
7362
7363 clear_buffer_p = 0;
7364
7365 if (which == 0)
7366 this_one = 0, the_other = 1;
7367 else if (which > 0)
7368 this_one = 1, the_other = 0;
7369
7370 /* Choose a suitable buffer from echo_buffer[] is we don't
7371 have one. */
7372 if (NILP (echo_area_buffer[this_one]))
7373 {
7374 echo_area_buffer[this_one]
7375 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7376 ? echo_buffer[the_other]
7377 : echo_buffer[this_one]);
7378 clear_buffer_p = 1;
7379 }
7380
7381 buffer = echo_area_buffer[this_one];
7382
7383 /* Don't get confused by reusing the buffer used for echoing
7384 for a different purpose. */
7385 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7386 cancel_echoing ();
7387
7388 record_unwind_protect (unwind_with_echo_area_buffer,
7389 with_echo_area_buffer_unwind_data (w));
7390
7391 /* Make the echo area buffer current. Note that for display
7392 purposes, it is not necessary that the displayed window's buffer
7393 == current_buffer, except for text property lookup. So, let's
7394 only set that buffer temporarily here without doing a full
7395 Fset_window_buffer. We must also change w->pointm, though,
7396 because otherwise an assertions in unshow_buffer fails, and Emacs
7397 aborts. */
7398 set_buffer_internal_1 (XBUFFER (buffer));
7399 if (w)
7400 {
7401 w->buffer = buffer;
7402 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7403 }
7404
7405 current_buffer->undo_list = Qt;
7406 current_buffer->read_only = Qnil;
7407 specbind (Qinhibit_read_only, Qt);
7408 specbind (Qinhibit_modification_hooks, Qt);
7409
7410 if (clear_buffer_p && Z > BEG)
7411 del_range (BEG, Z);
7412
7413 xassert (BEGV >= BEG);
7414 xassert (ZV <= Z && ZV >= BEGV);
7415
7416 rc = fn (a1, a2, a3, a4);
7417
7418 xassert (BEGV >= BEG);
7419 xassert (ZV <= Z && ZV >= BEGV);
7420
7421 unbind_to (count, Qnil);
7422 return rc;
7423 }
7424
7425
7426 /* Save state that should be preserved around the call to the function
7427 FN called in with_echo_area_buffer. */
7428
7429 static Lisp_Object
7430 with_echo_area_buffer_unwind_data (w)
7431 struct window *w;
7432 {
7433 int i = 0;
7434 Lisp_Object vector;
7435
7436 /* Reduce consing by keeping one vector in
7437 Vwith_echo_area_save_vector. */
7438 vector = Vwith_echo_area_save_vector;
7439 Vwith_echo_area_save_vector = Qnil;
7440
7441 if (NILP (vector))
7442 vector = Fmake_vector (make_number (7), Qnil);
7443
7444 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7445 AREF (vector, i) = Vdeactivate_mark, ++i;
7446 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7447
7448 if (w)
7449 {
7450 XSETWINDOW (AREF (vector, i), w); ++i;
7451 AREF (vector, i) = w->buffer; ++i;
7452 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7453 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7454 }
7455 else
7456 {
7457 int end = i + 4;
7458 for (; i < end; ++i)
7459 AREF (vector, i) = Qnil;
7460 }
7461
7462 xassert (i == ASIZE (vector));
7463 return vector;
7464 }
7465
7466
7467 /* Restore global state from VECTOR which was created by
7468 with_echo_area_buffer_unwind_data. */
7469
7470 static Lisp_Object
7471 unwind_with_echo_area_buffer (vector)
7472 Lisp_Object vector;
7473 {
7474 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7475 Vdeactivate_mark = AREF (vector, 1);
7476 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7477
7478 if (WINDOWP (AREF (vector, 3)))
7479 {
7480 struct window *w;
7481 Lisp_Object buffer, charpos, bytepos;
7482
7483 w = XWINDOW (AREF (vector, 3));
7484 buffer = AREF (vector, 4);
7485 charpos = AREF (vector, 5);
7486 bytepos = AREF (vector, 6);
7487
7488 w->buffer = buffer;
7489 set_marker_both (w->pointm, buffer,
7490 XFASTINT (charpos), XFASTINT (bytepos));
7491 }
7492
7493 Vwith_echo_area_save_vector = vector;
7494 return Qnil;
7495 }
7496
7497
7498 /* Set up the echo area for use by print functions. MULTIBYTE_P
7499 non-zero means we will print multibyte. */
7500
7501 void
7502 setup_echo_area_for_printing (multibyte_p)
7503 int multibyte_p;
7504 {
7505 /* If we can't find an echo area any more, exit. */
7506 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7507 Fkill_emacs (Qnil);
7508
7509 ensure_echo_area_buffers ();
7510
7511 if (!message_buf_print)
7512 {
7513 /* A message has been output since the last time we printed.
7514 Choose a fresh echo area buffer. */
7515 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7516 echo_area_buffer[0] = echo_buffer[1];
7517 else
7518 echo_area_buffer[0] = echo_buffer[0];
7519
7520 /* Switch to that buffer and clear it. */
7521 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7522 current_buffer->truncate_lines = Qnil;
7523
7524 if (Z > BEG)
7525 {
7526 int count = SPECPDL_INDEX ();
7527 specbind (Qinhibit_read_only, Qt);
7528 /* Note that undo recording is always disabled. */
7529 del_range (BEG, Z);
7530 unbind_to (count, Qnil);
7531 }
7532 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7533
7534 /* Set up the buffer for the multibyteness we need. */
7535 if (multibyte_p
7536 != !NILP (current_buffer->enable_multibyte_characters))
7537 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7538
7539 /* Raise the frame containing the echo area. */
7540 if (minibuffer_auto_raise)
7541 {
7542 struct frame *sf = SELECTED_FRAME ();
7543 Lisp_Object mini_window;
7544 mini_window = FRAME_MINIBUF_WINDOW (sf);
7545 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7546 }
7547
7548 message_log_maybe_newline ();
7549 message_buf_print = 1;
7550 }
7551 else
7552 {
7553 if (NILP (echo_area_buffer[0]))
7554 {
7555 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7556 echo_area_buffer[0] = echo_buffer[1];
7557 else
7558 echo_area_buffer[0] = echo_buffer[0];
7559 }
7560
7561 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7562 {
7563 /* Someone switched buffers between print requests. */
7564 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7565 current_buffer->truncate_lines = Qnil;
7566 }
7567 }
7568 }
7569
7570
7571 /* Display an echo area message in window W. Value is non-zero if W's
7572 height is changed. If display_last_displayed_message_p is
7573 non-zero, display the message that was last displayed, otherwise
7574 display the current message. */
7575
7576 static int
7577 display_echo_area (w)
7578 struct window *w;
7579 {
7580 int i, no_message_p, window_height_changed_p, count;
7581
7582 /* Temporarily disable garbage collections while displaying the echo
7583 area. This is done because a GC can print a message itself.
7584 That message would modify the echo area buffer's contents while a
7585 redisplay of the buffer is going on, and seriously confuse
7586 redisplay. */
7587 count = inhibit_garbage_collection ();
7588
7589 /* If there is no message, we must call display_echo_area_1
7590 nevertheless because it resizes the window. But we will have to
7591 reset the echo_area_buffer in question to nil at the end because
7592 with_echo_area_buffer will sets it to an empty buffer. */
7593 i = display_last_displayed_message_p ? 1 : 0;
7594 no_message_p = NILP (echo_area_buffer[i]);
7595
7596 window_height_changed_p
7597 = with_echo_area_buffer (w, display_last_displayed_message_p,
7598 display_echo_area_1,
7599 (EMACS_INT) w, Qnil, 0, 0);
7600
7601 if (no_message_p)
7602 echo_area_buffer[i] = Qnil;
7603
7604 unbind_to (count, Qnil);
7605 return window_height_changed_p;
7606 }
7607
7608
7609 /* Helper for display_echo_area. Display the current buffer which
7610 contains the current echo area message in window W, a mini-window,
7611 a pointer to which is passed in A1. A2..A4 are currently not used.
7612 Change the height of W so that all of the message is displayed.
7613 Value is non-zero if height of W was changed. */
7614
7615 static int
7616 display_echo_area_1 (a1, a2, a3, a4)
7617 EMACS_INT a1;
7618 Lisp_Object a2;
7619 EMACS_INT a3, a4;
7620 {
7621 struct window *w = (struct window *) a1;
7622 Lisp_Object window;
7623 struct text_pos start;
7624 int window_height_changed_p = 0;
7625
7626 /* Do this before displaying, so that we have a large enough glyph
7627 matrix for the display. */
7628 window_height_changed_p = resize_mini_window (w, 0);
7629
7630 /* Display. */
7631 clear_glyph_matrix (w->desired_matrix);
7632 XSETWINDOW (window, w);
7633 SET_TEXT_POS (start, BEG, BEG_BYTE);
7634 try_window (window, start, 0);
7635
7636 return window_height_changed_p;
7637 }
7638
7639
7640 /* Resize the echo area window to exactly the size needed for the
7641 currently displayed message, if there is one. If a mini-buffer
7642 is active, don't shrink it. */
7643
7644 void
7645 resize_echo_area_exactly ()
7646 {
7647 if (BUFFERP (echo_area_buffer[0])
7648 && WINDOWP (echo_area_window))
7649 {
7650 struct window *w = XWINDOW (echo_area_window);
7651 int resized_p;
7652 Lisp_Object resize_exactly;
7653
7654 if (minibuf_level == 0)
7655 resize_exactly = Qt;
7656 else
7657 resize_exactly = Qnil;
7658
7659 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7660 (EMACS_INT) w, resize_exactly, 0, 0);
7661 if (resized_p)
7662 {
7663 ++windows_or_buffers_changed;
7664 ++update_mode_lines;
7665 redisplay_internal (0);
7666 }
7667 }
7668 }
7669
7670
7671 /* Callback function for with_echo_area_buffer, when used from
7672 resize_echo_area_exactly. A1 contains a pointer to the window to
7673 resize, EXACTLY non-nil means resize the mini-window exactly to the
7674 size of the text displayed. A3 and A4 are not used. Value is what
7675 resize_mini_window returns. */
7676
7677 static int
7678 resize_mini_window_1 (a1, exactly, a3, a4)
7679 EMACS_INT a1;
7680 Lisp_Object exactly;
7681 EMACS_INT a3, a4;
7682 {
7683 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7684 }
7685
7686
7687 /* Resize mini-window W to fit the size of its contents. EXACT:P
7688 means size the window exactly to the size needed. Otherwise, it's
7689 only enlarged until W's buffer is empty. Value is non-zero if
7690 the window height has been changed. */
7691
7692 int
7693 resize_mini_window (w, exact_p)
7694 struct window *w;
7695 int exact_p;
7696 {
7697 struct frame *f = XFRAME (w->frame);
7698 int window_height_changed_p = 0;
7699
7700 xassert (MINI_WINDOW_P (w));
7701
7702 /* Don't resize windows while redisplaying a window; it would
7703 confuse redisplay functions when the size of the window they are
7704 displaying changes from under them. Such a resizing can happen,
7705 for instance, when which-func prints a long message while
7706 we are running fontification-functions. We're running these
7707 functions with safe_call which binds inhibit-redisplay to t. */
7708 if (!NILP (Vinhibit_redisplay))
7709 return 0;
7710
7711 /* Nil means don't try to resize. */
7712 if (NILP (Vresize_mini_windows)
7713 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7714 return 0;
7715
7716 if (!FRAME_MINIBUF_ONLY_P (f))
7717 {
7718 struct it it;
7719 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7720 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7721 int height, max_height;
7722 int unit = FRAME_LINE_HEIGHT (f);
7723 struct text_pos start;
7724 struct buffer *old_current_buffer = NULL;
7725
7726 if (current_buffer != XBUFFER (w->buffer))
7727 {
7728 old_current_buffer = current_buffer;
7729 set_buffer_internal (XBUFFER (w->buffer));
7730 }
7731
7732 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7733
7734 /* Compute the max. number of lines specified by the user. */
7735 if (FLOATP (Vmax_mini_window_height))
7736 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7737 else if (INTEGERP (Vmax_mini_window_height))
7738 max_height = XINT (Vmax_mini_window_height);
7739 else
7740 max_height = total_height / 4;
7741
7742 /* Correct that max. height if it's bogus. */
7743 max_height = max (1, max_height);
7744 max_height = min (total_height, max_height);
7745
7746 /* Find out the height of the text in the window. */
7747 if (it.truncate_lines_p)
7748 height = 1;
7749 else
7750 {
7751 last_height = 0;
7752 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7753 if (it.max_ascent == 0 && it.max_descent == 0)
7754 height = it.current_y + last_height;
7755 else
7756 height = it.current_y + it.max_ascent + it.max_descent;
7757 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7758 height = (height + unit - 1) / unit;
7759 }
7760
7761 /* Compute a suitable window start. */
7762 if (height > max_height)
7763 {
7764 height = max_height;
7765 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7766 move_it_vertically_backward (&it, (height - 1) * unit);
7767 start = it.current.pos;
7768 }
7769 else
7770 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7771 SET_MARKER_FROM_TEXT_POS (w->start, start);
7772
7773 if (EQ (Vresize_mini_windows, Qgrow_only))
7774 {
7775 /* Let it grow only, until we display an empty message, in which
7776 case the window shrinks again. */
7777 if (height > WINDOW_TOTAL_LINES (w))
7778 {
7779 int old_height = WINDOW_TOTAL_LINES (w);
7780 freeze_window_starts (f, 1);
7781 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7782 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7783 }
7784 else if (height < WINDOW_TOTAL_LINES (w)
7785 && (exact_p || BEGV == ZV))
7786 {
7787 int old_height = WINDOW_TOTAL_LINES (w);
7788 freeze_window_starts (f, 0);
7789 shrink_mini_window (w);
7790 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7791 }
7792 }
7793 else
7794 {
7795 /* Always resize to exact size needed. */
7796 if (height > WINDOW_TOTAL_LINES (w))
7797 {
7798 int old_height = WINDOW_TOTAL_LINES (w);
7799 freeze_window_starts (f, 1);
7800 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7801 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7802 }
7803 else if (height < WINDOW_TOTAL_LINES (w))
7804 {
7805 int old_height = WINDOW_TOTAL_LINES (w);
7806 freeze_window_starts (f, 0);
7807 shrink_mini_window (w);
7808
7809 if (height)
7810 {
7811 freeze_window_starts (f, 1);
7812 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7813 }
7814
7815 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7816 }
7817 }
7818
7819 if (old_current_buffer)
7820 set_buffer_internal (old_current_buffer);
7821 }
7822
7823 return window_height_changed_p;
7824 }
7825
7826
7827 /* Value is the current message, a string, or nil if there is no
7828 current message. */
7829
7830 Lisp_Object
7831 current_message ()
7832 {
7833 Lisp_Object msg;
7834
7835 if (NILP (echo_area_buffer[0]))
7836 msg = Qnil;
7837 else
7838 {
7839 with_echo_area_buffer (0, 0, current_message_1,
7840 (EMACS_INT) &msg, Qnil, 0, 0);
7841 if (NILP (msg))
7842 echo_area_buffer[0] = Qnil;
7843 }
7844
7845 return msg;
7846 }
7847
7848
7849 static int
7850 current_message_1 (a1, a2, a3, a4)
7851 EMACS_INT a1;
7852 Lisp_Object a2;
7853 EMACS_INT a3, a4;
7854 {
7855 Lisp_Object *msg = (Lisp_Object *) a1;
7856
7857 if (Z > BEG)
7858 *msg = make_buffer_string (BEG, Z, 1);
7859 else
7860 *msg = Qnil;
7861 return 0;
7862 }
7863
7864
7865 /* Push the current message on Vmessage_stack for later restauration
7866 by restore_message. Value is non-zero if the current message isn't
7867 empty. This is a relatively infrequent operation, so it's not
7868 worth optimizing. */
7869
7870 int
7871 push_message ()
7872 {
7873 Lisp_Object msg;
7874 msg = current_message ();
7875 Vmessage_stack = Fcons (msg, Vmessage_stack);
7876 return STRINGP (msg);
7877 }
7878
7879
7880 /* Restore message display from the top of Vmessage_stack. */
7881
7882 void
7883 restore_message ()
7884 {
7885 Lisp_Object msg;
7886
7887 xassert (CONSP (Vmessage_stack));
7888 msg = XCAR (Vmessage_stack);
7889 if (STRINGP (msg))
7890 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7891 else
7892 message3_nolog (msg, 0, 0);
7893 }
7894
7895
7896 /* Handler for record_unwind_protect calling pop_message. */
7897
7898 Lisp_Object
7899 pop_message_unwind (dummy)
7900 Lisp_Object dummy;
7901 {
7902 pop_message ();
7903 return Qnil;
7904 }
7905
7906 /* Pop the top-most entry off Vmessage_stack. */
7907
7908 void
7909 pop_message ()
7910 {
7911 xassert (CONSP (Vmessage_stack));
7912 Vmessage_stack = XCDR (Vmessage_stack);
7913 }
7914
7915
7916 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7917 exits. If the stack is not empty, we have a missing pop_message
7918 somewhere. */
7919
7920 void
7921 check_message_stack ()
7922 {
7923 if (!NILP (Vmessage_stack))
7924 abort ();
7925 }
7926
7927
7928 /* Truncate to NCHARS what will be displayed in the echo area the next
7929 time we display it---but don't redisplay it now. */
7930
7931 void
7932 truncate_echo_area (nchars)
7933 int nchars;
7934 {
7935 if (nchars == 0)
7936 echo_area_buffer[0] = Qnil;
7937 /* A null message buffer means that the frame hasn't really been
7938 initialized yet. Error messages get reported properly by
7939 cmd_error, so this must be just an informative message; toss it. */
7940 else if (!noninteractive
7941 && INTERACTIVE
7942 && !NILP (echo_area_buffer[0]))
7943 {
7944 struct frame *sf = SELECTED_FRAME ();
7945 if (FRAME_MESSAGE_BUF (sf))
7946 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7947 }
7948 }
7949
7950
7951 /* Helper function for truncate_echo_area. Truncate the current
7952 message to at most NCHARS characters. */
7953
7954 static int
7955 truncate_message_1 (nchars, a2, a3, a4)
7956 EMACS_INT nchars;
7957 Lisp_Object a2;
7958 EMACS_INT a3, a4;
7959 {
7960 if (BEG + nchars < Z)
7961 del_range (BEG + nchars, Z);
7962 if (Z == BEG)
7963 echo_area_buffer[0] = Qnil;
7964 return 0;
7965 }
7966
7967
7968 /* Set the current message to a substring of S or STRING.
7969
7970 If STRING is a Lisp string, set the message to the first NBYTES
7971 bytes from STRING. NBYTES zero means use the whole string. If
7972 STRING is multibyte, the message will be displayed multibyte.
7973
7974 If S is not null, set the message to the first LEN bytes of S. LEN
7975 zero means use the whole string. MULTIBYTE_P non-zero means S is
7976 multibyte. Display the message multibyte in that case. */
7977
7978 void
7979 set_message (s, string, nbytes, multibyte_p)
7980 const char *s;
7981 Lisp_Object string;
7982 int nbytes, multibyte_p;
7983 {
7984 message_enable_multibyte
7985 = ((s && multibyte_p)
7986 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7987
7988 with_echo_area_buffer (0, 0, set_message_1,
7989 (EMACS_INT) s, string, nbytes, multibyte_p);
7990 message_buf_print = 0;
7991 help_echo_showing_p = 0;
7992 }
7993
7994
7995 /* Helper function for set_message. Arguments have the same meaning
7996 as there, with A1 corresponding to S and A2 corresponding to STRING
7997 This function is called with the echo area buffer being
7998 current. */
7999
8000 static int
8001 set_message_1 (a1, a2, nbytes, multibyte_p)
8002 EMACS_INT a1;
8003 Lisp_Object a2;
8004 EMACS_INT nbytes, multibyte_p;
8005 {
8006 const char *s = (const char *) a1;
8007 Lisp_Object string = a2;
8008
8009 /* Change multibyteness of the echo buffer appropriately. */
8010 if (message_enable_multibyte
8011 != !NILP (current_buffer->enable_multibyte_characters))
8012 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
8013
8014 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
8015
8016 /* Insert new message at BEG. */
8017 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
8018 Ferase_buffer ();
8019
8020 if (STRINGP (string))
8021 {
8022 int nchars;
8023
8024 if (nbytes == 0)
8025 nbytes = SBYTES (string);
8026 nchars = string_byte_to_char (string, nbytes);
8027
8028 /* This function takes care of single/multibyte conversion. We
8029 just have to ensure that the echo area buffer has the right
8030 setting of enable_multibyte_characters. */
8031 insert_from_string (string, 0, 0, nchars, nbytes, 1);
8032 }
8033 else if (s)
8034 {
8035 if (nbytes == 0)
8036 nbytes = strlen (s);
8037
8038 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
8039 {
8040 /* Convert from multi-byte to single-byte. */
8041 int i, c, n;
8042 unsigned char work[1];
8043
8044 /* Convert a multibyte string to single-byte. */
8045 for (i = 0; i < nbytes; i += n)
8046 {
8047 c = string_char_and_length (s + i, nbytes - i, &n);
8048 work[0] = (SINGLE_BYTE_CHAR_P (c)
8049 ? c
8050 : multibyte_char_to_unibyte (c, Qnil));
8051 insert_1_both (work, 1, 1, 1, 0, 0);
8052 }
8053 }
8054 else if (!multibyte_p
8055 && !NILP (current_buffer->enable_multibyte_characters))
8056 {
8057 /* Convert from single-byte to multi-byte. */
8058 int i, c, n;
8059 const unsigned char *msg = (const unsigned char *) s;
8060 unsigned char str[MAX_MULTIBYTE_LENGTH];
8061
8062 /* Convert a single-byte string to multibyte. */
8063 for (i = 0; i < nbytes; i++)
8064 {
8065 c = unibyte_char_to_multibyte (msg[i]);
8066 n = CHAR_STRING (c, str);
8067 insert_1_both (str, 1, n, 1, 0, 0);
8068 }
8069 }
8070 else
8071 insert_1 (s, nbytes, 1, 0, 0);
8072 }
8073
8074 return 0;
8075 }
8076
8077
8078 /* Clear messages. CURRENT_P non-zero means clear the current
8079 message. LAST_DISPLAYED_P non-zero means clear the message
8080 last displayed. */
8081
8082 void
8083 clear_message (current_p, last_displayed_p)
8084 int current_p, last_displayed_p;
8085 {
8086 if (current_p)
8087 {
8088 echo_area_buffer[0] = Qnil;
8089 message_cleared_p = 1;
8090 }
8091
8092 if (last_displayed_p)
8093 echo_area_buffer[1] = Qnil;
8094
8095 message_buf_print = 0;
8096 }
8097
8098 /* Clear garbaged frames.
8099
8100 This function is used where the old redisplay called
8101 redraw_garbaged_frames which in turn called redraw_frame which in
8102 turn called clear_frame. The call to clear_frame was a source of
8103 flickering. I believe a clear_frame is not necessary. It should
8104 suffice in the new redisplay to invalidate all current matrices,
8105 and ensure a complete redisplay of all windows. */
8106
8107 static void
8108 clear_garbaged_frames ()
8109 {
8110 if (frame_garbaged)
8111 {
8112 Lisp_Object tail, frame;
8113 int changed_count = 0;
8114
8115 FOR_EACH_FRAME (tail, frame)
8116 {
8117 struct frame *f = XFRAME (frame);
8118
8119 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8120 {
8121 if (f->resized_p)
8122 {
8123 Fredraw_frame (frame);
8124 f->force_flush_display_p = 1;
8125 }
8126 clear_current_matrices (f);
8127 changed_count++;
8128 f->garbaged = 0;
8129 f->resized_p = 0;
8130 }
8131 }
8132
8133 frame_garbaged = 0;
8134 if (changed_count)
8135 ++windows_or_buffers_changed;
8136 }
8137 }
8138
8139
8140 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8141 is non-zero update selected_frame. Value is non-zero if the
8142 mini-windows height has been changed. */
8143
8144 static int
8145 echo_area_display (update_frame_p)
8146 int update_frame_p;
8147 {
8148 Lisp_Object mini_window;
8149 struct window *w;
8150 struct frame *f;
8151 int window_height_changed_p = 0;
8152 struct frame *sf = SELECTED_FRAME ();
8153
8154 mini_window = FRAME_MINIBUF_WINDOW (sf);
8155 w = XWINDOW (mini_window);
8156 f = XFRAME (WINDOW_FRAME (w));
8157
8158 /* Don't display if frame is invisible or not yet initialized. */
8159 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8160 return 0;
8161
8162 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8163 #ifndef MAC_OS8
8164 #ifdef HAVE_WINDOW_SYSTEM
8165 /* When Emacs starts, selected_frame may be a visible terminal
8166 frame, even if we run under a window system. If we let this
8167 through, a message would be displayed on the terminal. */
8168 if (EQ (selected_frame, Vterminal_frame)
8169 && !NILP (Vwindow_system))
8170 return 0;
8171 #endif /* HAVE_WINDOW_SYSTEM */
8172 #endif
8173
8174 /* Redraw garbaged frames. */
8175 if (frame_garbaged)
8176 clear_garbaged_frames ();
8177
8178 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8179 {
8180 echo_area_window = mini_window;
8181 window_height_changed_p = display_echo_area (w);
8182 w->must_be_updated_p = 1;
8183
8184 /* Update the display, unless called from redisplay_internal.
8185 Also don't update the screen during redisplay itself. The
8186 update will happen at the end of redisplay, and an update
8187 here could cause confusion. */
8188 if (update_frame_p && !redisplaying_p)
8189 {
8190 int n = 0;
8191
8192 /* If the display update has been interrupted by pending
8193 input, update mode lines in the frame. Due to the
8194 pending input, it might have been that redisplay hasn't
8195 been called, so that mode lines above the echo area are
8196 garbaged. This looks odd, so we prevent it here. */
8197 if (!display_completed)
8198 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8199
8200 if (window_height_changed_p
8201 /* Don't do this if Emacs is shutting down. Redisplay
8202 needs to run hooks. */
8203 && !NILP (Vrun_hooks))
8204 {
8205 /* Must update other windows. Likewise as in other
8206 cases, don't let this update be interrupted by
8207 pending input. */
8208 int count = SPECPDL_INDEX ();
8209 specbind (Qredisplay_dont_pause, Qt);
8210 windows_or_buffers_changed = 1;
8211 redisplay_internal (0);
8212 unbind_to (count, Qnil);
8213 }
8214 else if (FRAME_WINDOW_P (f) && n == 0)
8215 {
8216 /* Window configuration is the same as before.
8217 Can do with a display update of the echo area,
8218 unless we displayed some mode lines. */
8219 update_single_window (w, 1);
8220 rif->flush_display (f);
8221 }
8222 else
8223 update_frame (f, 1, 1);
8224
8225 /* If cursor is in the echo area, make sure that the next
8226 redisplay displays the minibuffer, so that the cursor will
8227 be replaced with what the minibuffer wants. */
8228 if (cursor_in_echo_area)
8229 ++windows_or_buffers_changed;
8230 }
8231 }
8232 else if (!EQ (mini_window, selected_window))
8233 windows_or_buffers_changed++;
8234
8235 /* The current message is now also the last one displayed. */
8236 echo_area_buffer[1] = echo_area_buffer[0];
8237
8238 /* Prevent redisplay optimization in redisplay_internal by resetting
8239 this_line_start_pos. This is done because the mini-buffer now
8240 displays the message instead of its buffer text. */
8241 if (EQ (mini_window, selected_window))
8242 CHARPOS (this_line_start_pos) = 0;
8243
8244 return window_height_changed_p;
8245 }
8246
8247
8248 \f
8249 /***********************************************************************
8250 Mode Lines and Frame Titles
8251 ***********************************************************************/
8252
8253 /* A buffer for constructing non-propertized mode-line strings and
8254 frame titles in it; allocated from the heap in init_xdisp and
8255 resized as needed in store_mode_line_noprop_char. */
8256
8257 static char *mode_line_noprop_buf;
8258
8259 /* The buffer's end, and a current output position in it. */
8260
8261 static char *mode_line_noprop_buf_end;
8262 static char *mode_line_noprop_ptr;
8263
8264 #define MODE_LINE_NOPROP_LEN(start) \
8265 ((mode_line_noprop_ptr - mode_line_noprop_buf) - start)
8266
8267 static enum {
8268 MODE_LINE_DISPLAY = 0,
8269 MODE_LINE_TITLE,
8270 MODE_LINE_NOPROP,
8271 MODE_LINE_STRING
8272 } mode_line_target;
8273
8274 /* Alist that caches the results of :propertize.
8275 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
8276 static Lisp_Object mode_line_proptrans_alist;
8277
8278 /* List of strings making up the mode-line. */
8279 static Lisp_Object mode_line_string_list;
8280
8281 /* Base face property when building propertized mode line string. */
8282 static Lisp_Object mode_line_string_face;
8283 static Lisp_Object mode_line_string_face_prop;
8284
8285
8286 /* Unwind data for mode line strings */
8287
8288 static Lisp_Object Vmode_line_unwind_vector;
8289
8290 static Lisp_Object
8291 format_mode_line_unwind_data (obuf)
8292 struct buffer *obuf;
8293 {
8294 Lisp_Object vector;
8295
8296 /* Reduce consing by keeping one vector in
8297 Vwith_echo_area_save_vector. */
8298 vector = Vmode_line_unwind_vector;
8299 Vmode_line_unwind_vector = Qnil;
8300
8301 if (NILP (vector))
8302 vector = Fmake_vector (make_number (7), Qnil);
8303
8304 AREF (vector, 0) = make_number (mode_line_target);
8305 AREF (vector, 1) = make_number (MODE_LINE_NOPROP_LEN (0));
8306 AREF (vector, 2) = mode_line_string_list;
8307 AREF (vector, 3) = mode_line_proptrans_alist;
8308 AREF (vector, 4) = mode_line_string_face;
8309 AREF (vector, 5) = mode_line_string_face_prop;
8310
8311 if (obuf)
8312 XSETBUFFER (AREF (vector, 6), obuf);
8313 else
8314 AREF (vector, 6) = Qnil;
8315
8316 return vector;
8317 }
8318
8319 static Lisp_Object
8320 unwind_format_mode_line (vector)
8321 Lisp_Object vector;
8322 {
8323 mode_line_target = XINT (AREF (vector, 0));
8324 mode_line_noprop_ptr = mode_line_noprop_buf + XINT (AREF (vector, 1));
8325 mode_line_string_list = AREF (vector, 2);
8326 mode_line_proptrans_alist = AREF (vector, 3);
8327 mode_line_string_face = AREF (vector, 4);
8328 mode_line_string_face_prop = AREF (vector, 5);
8329
8330 if (!NILP (AREF (vector, 6)))
8331 {
8332 set_buffer_internal_1 (XBUFFER (AREF (vector, 6)));
8333 AREF (vector, 6) = Qnil;
8334 }
8335
8336 Vmode_line_unwind_vector = vector;
8337 return Qnil;
8338 }
8339
8340
8341 /* Store a single character C for the frame title in mode_line_noprop_buf.
8342 Re-allocate mode_line_noprop_buf if necessary. */
8343
8344 static void
8345 #ifdef PROTOTYPES
8346 store_mode_line_noprop_char (char c)
8347 #else
8348 store_mode_line_noprop_char (c)
8349 char c;
8350 #endif
8351 {
8352 /* If output position has reached the end of the allocated buffer,
8353 double the buffer's size. */
8354 if (mode_line_noprop_ptr == mode_line_noprop_buf_end)
8355 {
8356 int len = MODE_LINE_NOPROP_LEN (0);
8357 int new_size = 2 * len * sizeof *mode_line_noprop_buf;
8358 mode_line_noprop_buf = (char *) xrealloc (mode_line_noprop_buf, new_size);
8359 mode_line_noprop_buf_end = mode_line_noprop_buf + new_size;
8360 mode_line_noprop_ptr = mode_line_noprop_buf + len;
8361 }
8362
8363 *mode_line_noprop_ptr++ = c;
8364 }
8365
8366
8367 /* Store part of a frame title in mode_line_noprop_buf, beginning at
8368 mode_line_noprop_ptr. STR is the string to store. Do not copy
8369 characters that yield more columns than PRECISION; PRECISION <= 0
8370 means copy the whole string. Pad with spaces until FIELD_WIDTH
8371 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8372 pad. Called from display_mode_element when it is used to build a
8373 frame title. */
8374
8375 static int
8376 store_mode_line_noprop (str, field_width, precision)
8377 const unsigned char *str;
8378 int field_width, precision;
8379 {
8380 int n = 0;
8381 int dummy, nbytes;
8382
8383 /* Copy at most PRECISION chars from STR. */
8384 nbytes = strlen (str);
8385 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8386 while (nbytes--)
8387 store_mode_line_noprop_char (*str++);
8388
8389 /* Fill up with spaces until FIELD_WIDTH reached. */
8390 while (field_width > 0
8391 && n < field_width)
8392 {
8393 store_mode_line_noprop_char (' ');
8394 ++n;
8395 }
8396
8397 return n;
8398 }
8399
8400 /***********************************************************************
8401 Frame Titles
8402 ***********************************************************************/
8403
8404 #ifdef HAVE_WINDOW_SYSTEM
8405
8406 /* Set the title of FRAME, if it has changed. The title format is
8407 Vicon_title_format if FRAME is iconified, otherwise it is
8408 frame_title_format. */
8409
8410 static void
8411 x_consider_frame_title (frame)
8412 Lisp_Object frame;
8413 {
8414 struct frame *f = XFRAME (frame);
8415
8416 if (FRAME_WINDOW_P (f)
8417 || FRAME_MINIBUF_ONLY_P (f)
8418 || f->explicit_name)
8419 {
8420 /* Do we have more than one visible frame on this X display? */
8421 Lisp_Object tail;
8422 Lisp_Object fmt;
8423 int title_start;
8424 char *title;
8425 int len;
8426 struct it it;
8427 int count = SPECPDL_INDEX ();
8428
8429 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8430 {
8431 Lisp_Object other_frame = XCAR (tail);
8432 struct frame *tf = XFRAME (other_frame);
8433
8434 if (tf != f
8435 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8436 && !FRAME_MINIBUF_ONLY_P (tf)
8437 && !EQ (other_frame, tip_frame)
8438 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8439 break;
8440 }
8441
8442 /* Set global variable indicating that multiple frames exist. */
8443 multiple_frames = CONSP (tail);
8444
8445 /* Switch to the buffer of selected window of the frame. Set up
8446 mode_line_target so that display_mode_element will output into
8447 mode_line_noprop_buf; then display the title. */
8448 record_unwind_protect (unwind_format_mode_line,
8449 format_mode_line_unwind_data (current_buffer));
8450
8451 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8452 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8453
8454 mode_line_target = MODE_LINE_TITLE;
8455 title_start = MODE_LINE_NOPROP_LEN (0);
8456 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8457 NULL, DEFAULT_FACE_ID);
8458 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8459 len = MODE_LINE_NOPROP_LEN (title_start);
8460 title = mode_line_noprop_buf + title_start;
8461 unbind_to (count, Qnil);
8462
8463 /* Set the title only if it's changed. This avoids consing in
8464 the common case where it hasn't. (If it turns out that we've
8465 already wasted too much time by walking through the list with
8466 display_mode_element, then we might need to optimize at a
8467 higher level than this.) */
8468 if (! STRINGP (f->name)
8469 || SBYTES (f->name) != len
8470 || bcmp (title, SDATA (f->name), len) != 0)
8471 x_implicitly_set_name (f, make_string (title, len), Qnil);
8472 }
8473 }
8474
8475 #endif /* not HAVE_WINDOW_SYSTEM */
8476
8477
8478
8479 \f
8480 /***********************************************************************
8481 Menu Bars
8482 ***********************************************************************/
8483
8484
8485 /* Prepare for redisplay by updating menu-bar item lists when
8486 appropriate. This can call eval. */
8487
8488 void
8489 prepare_menu_bars ()
8490 {
8491 int all_windows;
8492 struct gcpro gcpro1, gcpro2;
8493 struct frame *f;
8494 Lisp_Object tooltip_frame;
8495
8496 #ifdef HAVE_WINDOW_SYSTEM
8497 tooltip_frame = tip_frame;
8498 #else
8499 tooltip_frame = Qnil;
8500 #endif
8501
8502 /* Update all frame titles based on their buffer names, etc. We do
8503 this before the menu bars so that the buffer-menu will show the
8504 up-to-date frame titles. */
8505 #ifdef HAVE_WINDOW_SYSTEM
8506 if (windows_or_buffers_changed || update_mode_lines)
8507 {
8508 Lisp_Object tail, frame;
8509
8510 FOR_EACH_FRAME (tail, frame)
8511 {
8512 f = XFRAME (frame);
8513 if (!EQ (frame, tooltip_frame)
8514 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8515 x_consider_frame_title (frame);
8516 }
8517 }
8518 #endif /* HAVE_WINDOW_SYSTEM */
8519
8520 /* Update the menu bar item lists, if appropriate. This has to be
8521 done before any actual redisplay or generation of display lines. */
8522 all_windows = (update_mode_lines
8523 || buffer_shared > 1
8524 || windows_or_buffers_changed);
8525 if (all_windows)
8526 {
8527 Lisp_Object tail, frame;
8528 int count = SPECPDL_INDEX ();
8529
8530 record_unwind_save_match_data ();
8531
8532 FOR_EACH_FRAME (tail, frame)
8533 {
8534 f = XFRAME (frame);
8535
8536 /* Ignore tooltip frame. */
8537 if (EQ (frame, tooltip_frame))
8538 continue;
8539
8540 /* If a window on this frame changed size, report that to
8541 the user and clear the size-change flag. */
8542 if (FRAME_WINDOW_SIZES_CHANGED (f))
8543 {
8544 Lisp_Object functions;
8545
8546 /* Clear flag first in case we get an error below. */
8547 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8548 functions = Vwindow_size_change_functions;
8549 GCPRO2 (tail, functions);
8550
8551 while (CONSP (functions))
8552 {
8553 call1 (XCAR (functions), frame);
8554 functions = XCDR (functions);
8555 }
8556 UNGCPRO;
8557 }
8558
8559 GCPRO1 (tail);
8560 update_menu_bar (f, 0);
8561 #ifdef HAVE_WINDOW_SYSTEM
8562 update_tool_bar (f, 0);
8563 #endif
8564 UNGCPRO;
8565 }
8566
8567 unbind_to (count, Qnil);
8568 }
8569 else
8570 {
8571 struct frame *sf = SELECTED_FRAME ();
8572 update_menu_bar (sf, 1);
8573 #ifdef HAVE_WINDOW_SYSTEM
8574 update_tool_bar (sf, 1);
8575 #endif
8576 }
8577
8578 /* Motif needs this. See comment in xmenu.c. Turn it off when
8579 pending_menu_activation is not defined. */
8580 #ifdef USE_X_TOOLKIT
8581 pending_menu_activation = 0;
8582 #endif
8583 }
8584
8585
8586 /* Update the menu bar item list for frame F. This has to be done
8587 before we start to fill in any display lines, because it can call
8588 eval.
8589
8590 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8591
8592 static void
8593 update_menu_bar (f, save_match_data)
8594 struct frame *f;
8595 int save_match_data;
8596 {
8597 Lisp_Object window;
8598 register struct window *w;
8599
8600 /* If called recursively during a menu update, do nothing. This can
8601 happen when, for instance, an activate-menubar-hook causes a
8602 redisplay. */
8603 if (inhibit_menubar_update)
8604 return;
8605
8606 window = FRAME_SELECTED_WINDOW (f);
8607 w = XWINDOW (window);
8608
8609 #if 0 /* The if statement below this if statement used to include the
8610 condition !NILP (w->update_mode_line), rather than using
8611 update_mode_lines directly, and this if statement may have
8612 been added to make that condition work. Now the if
8613 statement below matches its comment, this isn't needed. */
8614 if (update_mode_lines)
8615 w->update_mode_line = Qt;
8616 #endif
8617
8618 if (FRAME_WINDOW_P (f)
8619 ?
8620 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8621 || defined (USE_GTK)
8622 FRAME_EXTERNAL_MENU_BAR (f)
8623 #else
8624 FRAME_MENU_BAR_LINES (f) > 0
8625 #endif
8626 : FRAME_MENU_BAR_LINES (f) > 0)
8627 {
8628 /* If the user has switched buffers or windows, we need to
8629 recompute to reflect the new bindings. But we'll
8630 recompute when update_mode_lines is set too; that means
8631 that people can use force-mode-line-update to request
8632 that the menu bar be recomputed. The adverse effect on
8633 the rest of the redisplay algorithm is about the same as
8634 windows_or_buffers_changed anyway. */
8635 if (windows_or_buffers_changed
8636 /* This used to test w->update_mode_line, but we believe
8637 there is no need to recompute the menu in that case. */
8638 || update_mode_lines
8639 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8640 < BUF_MODIFF (XBUFFER (w->buffer)))
8641 != !NILP (w->last_had_star))
8642 || ((!NILP (Vtransient_mark_mode)
8643 && !NILP (XBUFFER (w->buffer)->mark_active))
8644 != !NILP (w->region_showing)))
8645 {
8646 struct buffer *prev = current_buffer;
8647 int count = SPECPDL_INDEX ();
8648
8649 specbind (Qinhibit_menubar_update, Qt);
8650
8651 set_buffer_internal_1 (XBUFFER (w->buffer));
8652 if (save_match_data)
8653 record_unwind_save_match_data ();
8654 if (NILP (Voverriding_local_map_menu_flag))
8655 {
8656 specbind (Qoverriding_terminal_local_map, Qnil);
8657 specbind (Qoverriding_local_map, Qnil);
8658 }
8659
8660 /* Run the Lucid hook. */
8661 safe_run_hooks (Qactivate_menubar_hook);
8662
8663 /* If it has changed current-menubar from previous value,
8664 really recompute the menu-bar from the value. */
8665 if (! NILP (Vlucid_menu_bar_dirty_flag))
8666 call0 (Qrecompute_lucid_menubar);
8667
8668 safe_run_hooks (Qmenu_bar_update_hook);
8669 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8670
8671 /* Redisplay the menu bar in case we changed it. */
8672 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8673 || defined (USE_GTK)
8674 if (FRAME_WINDOW_P (f)
8675 #if defined (MAC_OS)
8676 /* All frames on Mac OS share the same menubar. So only the
8677 selected frame should be allowed to set it. */
8678 && f == SELECTED_FRAME ()
8679 #endif
8680 )
8681 set_frame_menubar (f, 0, 0);
8682 else
8683 /* On a terminal screen, the menu bar is an ordinary screen
8684 line, and this makes it get updated. */
8685 w->update_mode_line = Qt;
8686 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8687 /* In the non-toolkit version, the menu bar is an ordinary screen
8688 line, and this makes it get updated. */
8689 w->update_mode_line = Qt;
8690 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8691
8692 unbind_to (count, Qnil);
8693 set_buffer_internal_1 (prev);
8694 }
8695 }
8696 }
8697
8698
8699 \f
8700 /***********************************************************************
8701 Output Cursor
8702 ***********************************************************************/
8703
8704 #ifdef HAVE_WINDOW_SYSTEM
8705
8706 /* EXPORT:
8707 Nominal cursor position -- where to draw output.
8708 HPOS and VPOS are window relative glyph matrix coordinates.
8709 X and Y are window relative pixel coordinates. */
8710
8711 struct cursor_pos output_cursor;
8712
8713
8714 /* EXPORT:
8715 Set the global variable output_cursor to CURSOR. All cursor
8716 positions are relative to updated_window. */
8717
8718 void
8719 set_output_cursor (cursor)
8720 struct cursor_pos *cursor;
8721 {
8722 output_cursor.hpos = cursor->hpos;
8723 output_cursor.vpos = cursor->vpos;
8724 output_cursor.x = cursor->x;
8725 output_cursor.y = cursor->y;
8726 }
8727
8728
8729 /* EXPORT for RIF:
8730 Set a nominal cursor position.
8731
8732 HPOS and VPOS are column/row positions in a window glyph matrix. X
8733 and Y are window text area relative pixel positions.
8734
8735 If this is done during an update, updated_window will contain the
8736 window that is being updated and the position is the future output
8737 cursor position for that window. If updated_window is null, use
8738 selected_window and display the cursor at the given position. */
8739
8740 void
8741 x_cursor_to (vpos, hpos, y, x)
8742 int vpos, hpos, y, x;
8743 {
8744 struct window *w;
8745
8746 /* If updated_window is not set, work on selected_window. */
8747 if (updated_window)
8748 w = updated_window;
8749 else
8750 w = XWINDOW (selected_window);
8751
8752 /* Set the output cursor. */
8753 output_cursor.hpos = hpos;
8754 output_cursor.vpos = vpos;
8755 output_cursor.x = x;
8756 output_cursor.y = y;
8757
8758 /* If not called as part of an update, really display the cursor.
8759 This will also set the cursor position of W. */
8760 if (updated_window == NULL)
8761 {
8762 BLOCK_INPUT;
8763 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8764 if (rif->flush_display_optional)
8765 rif->flush_display_optional (SELECTED_FRAME ());
8766 UNBLOCK_INPUT;
8767 }
8768 }
8769
8770 #endif /* HAVE_WINDOW_SYSTEM */
8771
8772 \f
8773 /***********************************************************************
8774 Tool-bars
8775 ***********************************************************************/
8776
8777 #ifdef HAVE_WINDOW_SYSTEM
8778
8779 /* Where the mouse was last time we reported a mouse event. */
8780
8781 FRAME_PTR last_mouse_frame;
8782
8783 /* Tool-bar item index of the item on which a mouse button was pressed
8784 or -1. */
8785
8786 int last_tool_bar_item;
8787
8788
8789 /* Update the tool-bar item list for frame F. This has to be done
8790 before we start to fill in any display lines. Called from
8791 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8792 and restore it here. */
8793
8794 static void
8795 update_tool_bar (f, save_match_data)
8796 struct frame *f;
8797 int save_match_data;
8798 {
8799 #ifdef USE_GTK
8800 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8801 #else
8802 int do_update = WINDOWP (f->tool_bar_window)
8803 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8804 #endif
8805
8806 if (do_update)
8807 {
8808 Lisp_Object window;
8809 struct window *w;
8810
8811 window = FRAME_SELECTED_WINDOW (f);
8812 w = XWINDOW (window);
8813
8814 /* If the user has switched buffers or windows, we need to
8815 recompute to reflect the new bindings. But we'll
8816 recompute when update_mode_lines is set too; that means
8817 that people can use force-mode-line-update to request
8818 that the menu bar be recomputed. The adverse effect on
8819 the rest of the redisplay algorithm is about the same as
8820 windows_or_buffers_changed anyway. */
8821 if (windows_or_buffers_changed
8822 || !NILP (w->update_mode_line)
8823 || update_mode_lines
8824 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8825 < BUF_MODIFF (XBUFFER (w->buffer)))
8826 != !NILP (w->last_had_star))
8827 || ((!NILP (Vtransient_mark_mode)
8828 && !NILP (XBUFFER (w->buffer)->mark_active))
8829 != !NILP (w->region_showing)))
8830 {
8831 struct buffer *prev = current_buffer;
8832 int count = SPECPDL_INDEX ();
8833 Lisp_Object new_tool_bar;
8834 int new_n_tool_bar;
8835 struct gcpro gcpro1;
8836
8837 /* Set current_buffer to the buffer of the selected
8838 window of the frame, so that we get the right local
8839 keymaps. */
8840 set_buffer_internal_1 (XBUFFER (w->buffer));
8841
8842 /* Save match data, if we must. */
8843 if (save_match_data)
8844 record_unwind_save_match_data ();
8845
8846 /* Make sure that we don't accidentally use bogus keymaps. */
8847 if (NILP (Voverriding_local_map_menu_flag))
8848 {
8849 specbind (Qoverriding_terminal_local_map, Qnil);
8850 specbind (Qoverriding_local_map, Qnil);
8851 }
8852
8853 GCPRO1 (new_tool_bar);
8854
8855 /* Build desired tool-bar items from keymaps. */
8856 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8857 &new_n_tool_bar);
8858
8859 /* Redisplay the tool-bar if we changed it. */
8860 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8861 {
8862 /* Redisplay that happens asynchronously due to an expose event
8863 may access f->tool_bar_items. Make sure we update both
8864 variables within BLOCK_INPUT so no such event interrupts. */
8865 BLOCK_INPUT;
8866 f->tool_bar_items = new_tool_bar;
8867 f->n_tool_bar_items = new_n_tool_bar;
8868 w->update_mode_line = Qt;
8869 UNBLOCK_INPUT;
8870 }
8871
8872 UNGCPRO;
8873
8874 unbind_to (count, Qnil);
8875 set_buffer_internal_1 (prev);
8876 }
8877 }
8878 }
8879
8880
8881 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8882 F's desired tool-bar contents. F->tool_bar_items must have
8883 been set up previously by calling prepare_menu_bars. */
8884
8885 static void
8886 build_desired_tool_bar_string (f)
8887 struct frame *f;
8888 {
8889 int i, size, size_needed;
8890 struct gcpro gcpro1, gcpro2, gcpro3;
8891 Lisp_Object image, plist, props;
8892
8893 image = plist = props = Qnil;
8894 GCPRO3 (image, plist, props);
8895
8896 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8897 Otherwise, make a new string. */
8898
8899 /* The size of the string we might be able to reuse. */
8900 size = (STRINGP (f->desired_tool_bar_string)
8901 ? SCHARS (f->desired_tool_bar_string)
8902 : 0);
8903
8904 /* We need one space in the string for each image. */
8905 size_needed = f->n_tool_bar_items;
8906
8907 /* Reuse f->desired_tool_bar_string, if possible. */
8908 if (size < size_needed || NILP (f->desired_tool_bar_string))
8909 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8910 make_number (' '));
8911 else
8912 {
8913 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8914 Fremove_text_properties (make_number (0), make_number (size),
8915 props, f->desired_tool_bar_string);
8916 }
8917
8918 /* Put a `display' property on the string for the images to display,
8919 put a `menu_item' property on tool-bar items with a value that
8920 is the index of the item in F's tool-bar item vector. */
8921 for (i = 0; i < f->n_tool_bar_items; ++i)
8922 {
8923 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8924
8925 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8926 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8927 int hmargin, vmargin, relief, idx, end;
8928 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8929
8930 /* If image is a vector, choose the image according to the
8931 button state. */
8932 image = PROP (TOOL_BAR_ITEM_IMAGES);
8933 if (VECTORP (image))
8934 {
8935 if (enabled_p)
8936 idx = (selected_p
8937 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8938 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8939 else
8940 idx = (selected_p
8941 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8942 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8943
8944 xassert (ASIZE (image) >= idx);
8945 image = AREF (image, idx);
8946 }
8947 else
8948 idx = -1;
8949
8950 /* Ignore invalid image specifications. */
8951 if (!valid_image_p (image))
8952 continue;
8953
8954 /* Display the tool-bar button pressed, or depressed. */
8955 plist = Fcopy_sequence (XCDR (image));
8956
8957 /* Compute margin and relief to draw. */
8958 relief = (tool_bar_button_relief >= 0
8959 ? tool_bar_button_relief
8960 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8961 hmargin = vmargin = relief;
8962
8963 if (INTEGERP (Vtool_bar_button_margin)
8964 && XINT (Vtool_bar_button_margin) > 0)
8965 {
8966 hmargin += XFASTINT (Vtool_bar_button_margin);
8967 vmargin += XFASTINT (Vtool_bar_button_margin);
8968 }
8969 else if (CONSP (Vtool_bar_button_margin))
8970 {
8971 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8972 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8973 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8974
8975 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8976 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8977 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8978 }
8979
8980 if (auto_raise_tool_bar_buttons_p)
8981 {
8982 /* Add a `:relief' property to the image spec if the item is
8983 selected. */
8984 if (selected_p)
8985 {
8986 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8987 hmargin -= relief;
8988 vmargin -= relief;
8989 }
8990 }
8991 else
8992 {
8993 /* If image is selected, display it pressed, i.e. with a
8994 negative relief. If it's not selected, display it with a
8995 raised relief. */
8996 plist = Fplist_put (plist, QCrelief,
8997 (selected_p
8998 ? make_number (-relief)
8999 : make_number (relief)));
9000 hmargin -= relief;
9001 vmargin -= relief;
9002 }
9003
9004 /* Put a margin around the image. */
9005 if (hmargin || vmargin)
9006 {
9007 if (hmargin == vmargin)
9008 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
9009 else
9010 plist = Fplist_put (plist, QCmargin,
9011 Fcons (make_number (hmargin),
9012 make_number (vmargin)));
9013 }
9014
9015 /* If button is not enabled, and we don't have special images
9016 for the disabled state, make the image appear disabled by
9017 applying an appropriate algorithm to it. */
9018 if (!enabled_p && idx < 0)
9019 plist = Fplist_put (plist, QCconversion, Qdisabled);
9020
9021 /* Put a `display' text property on the string for the image to
9022 display. Put a `menu-item' property on the string that gives
9023 the start of this item's properties in the tool-bar items
9024 vector. */
9025 image = Fcons (Qimage, plist);
9026 props = list4 (Qdisplay, image,
9027 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
9028
9029 /* Let the last image hide all remaining spaces in the tool bar
9030 string. The string can be longer than needed when we reuse a
9031 previous string. */
9032 if (i + 1 == f->n_tool_bar_items)
9033 end = SCHARS (f->desired_tool_bar_string);
9034 else
9035 end = i + 1;
9036 Fadd_text_properties (make_number (i), make_number (end),
9037 props, f->desired_tool_bar_string);
9038 #undef PROP
9039 }
9040
9041 UNGCPRO;
9042 }
9043
9044
9045 /* Display one line of the tool-bar of frame IT->f. */
9046
9047 static void
9048 display_tool_bar_line (it)
9049 struct it *it;
9050 {
9051 struct glyph_row *row = it->glyph_row;
9052 int max_x = it->last_visible_x;
9053 struct glyph *last;
9054
9055 prepare_desired_row (row);
9056 row->y = it->current_y;
9057
9058 /* Note that this isn't made use of if the face hasn't a box,
9059 so there's no need to check the face here. */
9060 it->start_of_box_run_p = 1;
9061
9062 while (it->current_x < max_x)
9063 {
9064 int x_before, x, n_glyphs_before, i, nglyphs;
9065
9066 /* Get the next display element. */
9067 if (!get_next_display_element (it))
9068 break;
9069
9070 /* Produce glyphs. */
9071 x_before = it->current_x;
9072 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
9073 PRODUCE_GLYPHS (it);
9074
9075 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
9076 i = 0;
9077 x = x_before;
9078 while (i < nglyphs)
9079 {
9080 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
9081
9082 if (x + glyph->pixel_width > max_x)
9083 {
9084 /* Glyph doesn't fit on line. */
9085 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
9086 it->current_x = x;
9087 goto out;
9088 }
9089
9090 ++it->hpos;
9091 x += glyph->pixel_width;
9092 ++i;
9093 }
9094
9095 /* Stop at line ends. */
9096 if (ITERATOR_AT_END_OF_LINE_P (it))
9097 break;
9098
9099 set_iterator_to_next (it, 1);
9100 }
9101
9102 out:;
9103
9104 row->displays_text_p = row->used[TEXT_AREA] != 0;
9105 extend_face_to_end_of_line (it);
9106 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
9107 last->right_box_line_p = 1;
9108 if (last == row->glyphs[TEXT_AREA])
9109 last->left_box_line_p = 1;
9110 compute_line_metrics (it);
9111
9112 /* If line is empty, make it occupy the rest of the tool-bar. */
9113 if (!row->displays_text_p)
9114 {
9115 row->height = row->phys_height = it->last_visible_y - row->y;
9116 row->ascent = row->phys_ascent = 0;
9117 row->extra_line_spacing = 0;
9118 }
9119
9120 row->full_width_p = 1;
9121 row->continued_p = 0;
9122 row->truncated_on_left_p = 0;
9123 row->truncated_on_right_p = 0;
9124
9125 it->current_x = it->hpos = 0;
9126 it->current_y += row->height;
9127 ++it->vpos;
9128 ++it->glyph_row;
9129 }
9130
9131
9132 /* Value is the number of screen lines needed to make all tool-bar
9133 items of frame F visible. */
9134
9135 static int
9136 tool_bar_lines_needed (f)
9137 struct frame *f;
9138 {
9139 struct window *w = XWINDOW (f->tool_bar_window);
9140 struct it it;
9141
9142 /* Initialize an iterator for iteration over
9143 F->desired_tool_bar_string in the tool-bar window of frame F. */
9144 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9145 it.first_visible_x = 0;
9146 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9147 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9148
9149 while (!ITERATOR_AT_END_P (&it))
9150 {
9151 it.glyph_row = w->desired_matrix->rows;
9152 clear_glyph_row (it.glyph_row);
9153 display_tool_bar_line (&it);
9154 }
9155
9156 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
9157 }
9158
9159
9160 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
9161 0, 1, 0,
9162 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
9163 (frame)
9164 Lisp_Object frame;
9165 {
9166 struct frame *f;
9167 struct window *w;
9168 int nlines = 0;
9169
9170 if (NILP (frame))
9171 frame = selected_frame;
9172 else
9173 CHECK_FRAME (frame);
9174 f = XFRAME (frame);
9175
9176 if (WINDOWP (f->tool_bar_window)
9177 || (w = XWINDOW (f->tool_bar_window),
9178 WINDOW_TOTAL_LINES (w) > 0))
9179 {
9180 update_tool_bar (f, 1);
9181 if (f->n_tool_bar_items)
9182 {
9183 build_desired_tool_bar_string (f);
9184 nlines = tool_bar_lines_needed (f);
9185 }
9186 }
9187
9188 return make_number (nlines);
9189 }
9190
9191
9192 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9193 height should be changed. */
9194
9195 static int
9196 redisplay_tool_bar (f)
9197 struct frame *f;
9198 {
9199 struct window *w;
9200 struct it it;
9201 struct glyph_row *row;
9202 int change_height_p = 0;
9203
9204 #ifdef USE_GTK
9205 if (FRAME_EXTERNAL_TOOL_BAR (f))
9206 update_frame_tool_bar (f);
9207 return 0;
9208 #endif
9209
9210 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9211 do anything. This means you must start with tool-bar-lines
9212 non-zero to get the auto-sizing effect. Or in other words, you
9213 can turn off tool-bars by specifying tool-bar-lines zero. */
9214 if (!WINDOWP (f->tool_bar_window)
9215 || (w = XWINDOW (f->tool_bar_window),
9216 WINDOW_TOTAL_LINES (w) == 0))
9217 return 0;
9218
9219 /* Set up an iterator for the tool-bar window. */
9220 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9221 it.first_visible_x = 0;
9222 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9223 row = it.glyph_row;
9224
9225 /* Build a string that represents the contents of the tool-bar. */
9226 build_desired_tool_bar_string (f);
9227 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9228
9229 /* Display as many lines as needed to display all tool-bar items. */
9230 while (it.current_y < it.last_visible_y)
9231 display_tool_bar_line (&it);
9232
9233 /* It doesn't make much sense to try scrolling in the tool-bar
9234 window, so don't do it. */
9235 w->desired_matrix->no_scrolling_p = 1;
9236 w->must_be_updated_p = 1;
9237
9238 if (auto_resize_tool_bars_p)
9239 {
9240 int nlines;
9241
9242 /* If we couldn't display everything, change the tool-bar's
9243 height. */
9244 if (IT_STRING_CHARPOS (it) < it.end_charpos)
9245 change_height_p = 1;
9246
9247 /* If there are blank lines at the end, except for a partially
9248 visible blank line at the end that is smaller than
9249 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9250 row = it.glyph_row - 1;
9251 if (!row->displays_text_p
9252 && row->height >= FRAME_LINE_HEIGHT (f))
9253 change_height_p = 1;
9254
9255 /* If row displays tool-bar items, but is partially visible,
9256 change the tool-bar's height. */
9257 if (row->displays_text_p
9258 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
9259 change_height_p = 1;
9260
9261 /* Resize windows as needed by changing the `tool-bar-lines'
9262 frame parameter. */
9263 if (change_height_p
9264 && (nlines = tool_bar_lines_needed (f),
9265 nlines != WINDOW_TOTAL_LINES (w)))
9266 {
9267 extern Lisp_Object Qtool_bar_lines;
9268 Lisp_Object frame;
9269 int old_height = WINDOW_TOTAL_LINES (w);
9270
9271 XSETFRAME (frame, f);
9272 clear_glyph_matrix (w->desired_matrix);
9273 Fmodify_frame_parameters (frame,
9274 Fcons (Fcons (Qtool_bar_lines,
9275 make_number (nlines)),
9276 Qnil));
9277 if (WINDOW_TOTAL_LINES (w) != old_height)
9278 fonts_changed_p = 1;
9279 }
9280 }
9281
9282 return change_height_p;
9283 }
9284
9285
9286 /* Get information about the tool-bar item which is displayed in GLYPH
9287 on frame F. Return in *PROP_IDX the index where tool-bar item
9288 properties start in F->tool_bar_items. Value is zero if
9289 GLYPH doesn't display a tool-bar item. */
9290
9291 static int
9292 tool_bar_item_info (f, glyph, prop_idx)
9293 struct frame *f;
9294 struct glyph *glyph;
9295 int *prop_idx;
9296 {
9297 Lisp_Object prop;
9298 int success_p;
9299 int charpos;
9300
9301 /* This function can be called asynchronously, which means we must
9302 exclude any possibility that Fget_text_property signals an
9303 error. */
9304 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9305 charpos = max (0, charpos);
9306
9307 /* Get the text property `menu-item' at pos. The value of that
9308 property is the start index of this item's properties in
9309 F->tool_bar_items. */
9310 prop = Fget_text_property (make_number (charpos),
9311 Qmenu_item, f->current_tool_bar_string);
9312 if (INTEGERP (prop))
9313 {
9314 *prop_idx = XINT (prop);
9315 success_p = 1;
9316 }
9317 else
9318 success_p = 0;
9319
9320 return success_p;
9321 }
9322
9323 \f
9324 /* Get information about the tool-bar item at position X/Y on frame F.
9325 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9326 the current matrix of the tool-bar window of F, or NULL if not
9327 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9328 item in F->tool_bar_items. Value is
9329
9330 -1 if X/Y is not on a tool-bar item
9331 0 if X/Y is on the same item that was highlighted before.
9332 1 otherwise. */
9333
9334 static int
9335 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
9336 struct frame *f;
9337 int x, y;
9338 struct glyph **glyph;
9339 int *hpos, *vpos, *prop_idx;
9340 {
9341 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9342 struct window *w = XWINDOW (f->tool_bar_window);
9343 int area;
9344
9345 /* Find the glyph under X/Y. */
9346 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
9347 if (*glyph == NULL)
9348 return -1;
9349
9350 /* Get the start of this tool-bar item's properties in
9351 f->tool_bar_items. */
9352 if (!tool_bar_item_info (f, *glyph, prop_idx))
9353 return -1;
9354
9355 /* Is mouse on the highlighted item? */
9356 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9357 && *vpos >= dpyinfo->mouse_face_beg_row
9358 && *vpos <= dpyinfo->mouse_face_end_row
9359 && (*vpos > dpyinfo->mouse_face_beg_row
9360 || *hpos >= dpyinfo->mouse_face_beg_col)
9361 && (*vpos < dpyinfo->mouse_face_end_row
9362 || *hpos < dpyinfo->mouse_face_end_col
9363 || dpyinfo->mouse_face_past_end))
9364 return 0;
9365
9366 return 1;
9367 }
9368
9369
9370 /* EXPORT:
9371 Handle mouse button event on the tool-bar of frame F, at
9372 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9373 0 for button release. MODIFIERS is event modifiers for button
9374 release. */
9375
9376 void
9377 handle_tool_bar_click (f, x, y, down_p, modifiers)
9378 struct frame *f;
9379 int x, y, down_p;
9380 unsigned int modifiers;
9381 {
9382 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9383 struct window *w = XWINDOW (f->tool_bar_window);
9384 int hpos, vpos, prop_idx;
9385 struct glyph *glyph;
9386 Lisp_Object enabled_p;
9387
9388 /* If not on the highlighted tool-bar item, return. */
9389 frame_to_window_pixel_xy (w, &x, &y);
9390 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9391 return;
9392
9393 /* If item is disabled, do nothing. */
9394 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9395 if (NILP (enabled_p))
9396 return;
9397
9398 if (down_p)
9399 {
9400 /* Show item in pressed state. */
9401 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9402 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9403 last_tool_bar_item = prop_idx;
9404 }
9405 else
9406 {
9407 Lisp_Object key, frame;
9408 struct input_event event;
9409 EVENT_INIT (event);
9410
9411 /* Show item in released state. */
9412 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9413 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9414
9415 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9416
9417 XSETFRAME (frame, f);
9418 event.kind = TOOL_BAR_EVENT;
9419 event.frame_or_window = frame;
9420 event.arg = frame;
9421 kbd_buffer_store_event (&event);
9422
9423 event.kind = TOOL_BAR_EVENT;
9424 event.frame_or_window = frame;
9425 event.arg = key;
9426 event.modifiers = modifiers;
9427 kbd_buffer_store_event (&event);
9428 last_tool_bar_item = -1;
9429 }
9430 }
9431
9432
9433 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9434 tool-bar window-relative coordinates X/Y. Called from
9435 note_mouse_highlight. */
9436
9437 static void
9438 note_tool_bar_highlight (f, x, y)
9439 struct frame *f;
9440 int x, y;
9441 {
9442 Lisp_Object window = f->tool_bar_window;
9443 struct window *w = XWINDOW (window);
9444 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9445 int hpos, vpos;
9446 struct glyph *glyph;
9447 struct glyph_row *row;
9448 int i;
9449 Lisp_Object enabled_p;
9450 int prop_idx;
9451 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9452 int mouse_down_p, rc;
9453
9454 /* Function note_mouse_highlight is called with negative x(y
9455 values when mouse moves outside of the frame. */
9456 if (x <= 0 || y <= 0)
9457 {
9458 clear_mouse_face (dpyinfo);
9459 return;
9460 }
9461
9462 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9463 if (rc < 0)
9464 {
9465 /* Not on tool-bar item. */
9466 clear_mouse_face (dpyinfo);
9467 return;
9468 }
9469 else if (rc == 0)
9470 /* On same tool-bar item as before. */
9471 goto set_help_echo;
9472
9473 clear_mouse_face (dpyinfo);
9474
9475 /* Mouse is down, but on different tool-bar item? */
9476 mouse_down_p = (dpyinfo->grabbed
9477 && f == last_mouse_frame
9478 && FRAME_LIVE_P (f));
9479 if (mouse_down_p
9480 && last_tool_bar_item != prop_idx)
9481 return;
9482
9483 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9484 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9485
9486 /* If tool-bar item is not enabled, don't highlight it. */
9487 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9488 if (!NILP (enabled_p))
9489 {
9490 /* Compute the x-position of the glyph. In front and past the
9491 image is a space. We include this in the highlighted area. */
9492 row = MATRIX_ROW (w->current_matrix, vpos);
9493 for (i = x = 0; i < hpos; ++i)
9494 x += row->glyphs[TEXT_AREA][i].pixel_width;
9495
9496 /* Record this as the current active region. */
9497 dpyinfo->mouse_face_beg_col = hpos;
9498 dpyinfo->mouse_face_beg_row = vpos;
9499 dpyinfo->mouse_face_beg_x = x;
9500 dpyinfo->mouse_face_beg_y = row->y;
9501 dpyinfo->mouse_face_past_end = 0;
9502
9503 dpyinfo->mouse_face_end_col = hpos + 1;
9504 dpyinfo->mouse_face_end_row = vpos;
9505 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9506 dpyinfo->mouse_face_end_y = row->y;
9507 dpyinfo->mouse_face_window = window;
9508 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9509
9510 /* Display it as active. */
9511 show_mouse_face (dpyinfo, draw);
9512 dpyinfo->mouse_face_image_state = draw;
9513 }
9514
9515 set_help_echo:
9516
9517 /* Set help_echo_string to a help string to display for this tool-bar item.
9518 XTread_socket does the rest. */
9519 help_echo_object = help_echo_window = Qnil;
9520 help_echo_pos = -1;
9521 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9522 if (NILP (help_echo_string))
9523 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9524 }
9525
9526 #endif /* HAVE_WINDOW_SYSTEM */
9527
9528
9529 \f
9530 /************************************************************************
9531 Horizontal scrolling
9532 ************************************************************************/
9533
9534 static int hscroll_window_tree P_ ((Lisp_Object));
9535 static int hscroll_windows P_ ((Lisp_Object));
9536
9537 /* For all leaf windows in the window tree rooted at WINDOW, set their
9538 hscroll value so that PT is (i) visible in the window, and (ii) so
9539 that it is not within a certain margin at the window's left and
9540 right border. Value is non-zero if any window's hscroll has been
9541 changed. */
9542
9543 static int
9544 hscroll_window_tree (window)
9545 Lisp_Object window;
9546 {
9547 int hscrolled_p = 0;
9548 int hscroll_relative_p = FLOATP (Vhscroll_step);
9549 int hscroll_step_abs = 0;
9550 double hscroll_step_rel = 0;
9551
9552 if (hscroll_relative_p)
9553 {
9554 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9555 if (hscroll_step_rel < 0)
9556 {
9557 hscroll_relative_p = 0;
9558 hscroll_step_abs = 0;
9559 }
9560 }
9561 else if (INTEGERP (Vhscroll_step))
9562 {
9563 hscroll_step_abs = XINT (Vhscroll_step);
9564 if (hscroll_step_abs < 0)
9565 hscroll_step_abs = 0;
9566 }
9567 else
9568 hscroll_step_abs = 0;
9569
9570 while (WINDOWP (window))
9571 {
9572 struct window *w = XWINDOW (window);
9573
9574 if (WINDOWP (w->hchild))
9575 hscrolled_p |= hscroll_window_tree (w->hchild);
9576 else if (WINDOWP (w->vchild))
9577 hscrolled_p |= hscroll_window_tree (w->vchild);
9578 else if (w->cursor.vpos >= 0)
9579 {
9580 int h_margin;
9581 int text_area_width;
9582 struct glyph_row *current_cursor_row
9583 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9584 struct glyph_row *desired_cursor_row
9585 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9586 struct glyph_row *cursor_row
9587 = (desired_cursor_row->enabled_p
9588 ? desired_cursor_row
9589 : current_cursor_row);
9590
9591 text_area_width = window_box_width (w, TEXT_AREA);
9592
9593 /* Scroll when cursor is inside this scroll margin. */
9594 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9595
9596 if ((XFASTINT (w->hscroll)
9597 && w->cursor.x <= h_margin)
9598 || (cursor_row->enabled_p
9599 && cursor_row->truncated_on_right_p
9600 && (w->cursor.x >= text_area_width - h_margin)))
9601 {
9602 struct it it;
9603 int hscroll;
9604 struct buffer *saved_current_buffer;
9605 int pt;
9606 int wanted_x;
9607
9608 /* Find point in a display of infinite width. */
9609 saved_current_buffer = current_buffer;
9610 current_buffer = XBUFFER (w->buffer);
9611
9612 if (w == XWINDOW (selected_window))
9613 pt = BUF_PT (current_buffer);
9614 else
9615 {
9616 pt = marker_position (w->pointm);
9617 pt = max (BEGV, pt);
9618 pt = min (ZV, pt);
9619 }
9620
9621 /* Move iterator to pt starting at cursor_row->start in
9622 a line with infinite width. */
9623 init_to_row_start (&it, w, cursor_row);
9624 it.last_visible_x = INFINITY;
9625 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9626 current_buffer = saved_current_buffer;
9627
9628 /* Position cursor in window. */
9629 if (!hscroll_relative_p && hscroll_step_abs == 0)
9630 hscroll = max (0, (it.current_x
9631 - (ITERATOR_AT_END_OF_LINE_P (&it)
9632 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9633 : (text_area_width / 2))))
9634 / FRAME_COLUMN_WIDTH (it.f);
9635 else if (w->cursor.x >= text_area_width - h_margin)
9636 {
9637 if (hscroll_relative_p)
9638 wanted_x = text_area_width * (1 - hscroll_step_rel)
9639 - h_margin;
9640 else
9641 wanted_x = text_area_width
9642 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9643 - h_margin;
9644 hscroll
9645 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9646 }
9647 else
9648 {
9649 if (hscroll_relative_p)
9650 wanted_x = text_area_width * hscroll_step_rel
9651 + h_margin;
9652 else
9653 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9654 + h_margin;
9655 hscroll
9656 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9657 }
9658 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9659
9660 /* Don't call Fset_window_hscroll if value hasn't
9661 changed because it will prevent redisplay
9662 optimizations. */
9663 if (XFASTINT (w->hscroll) != hscroll)
9664 {
9665 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9666 w->hscroll = make_number (hscroll);
9667 hscrolled_p = 1;
9668 }
9669 }
9670 }
9671
9672 window = w->next;
9673 }
9674
9675 /* Value is non-zero if hscroll of any leaf window has been changed. */
9676 return hscrolled_p;
9677 }
9678
9679
9680 /* Set hscroll so that cursor is visible and not inside horizontal
9681 scroll margins for all windows in the tree rooted at WINDOW. See
9682 also hscroll_window_tree above. Value is non-zero if any window's
9683 hscroll has been changed. If it has, desired matrices on the frame
9684 of WINDOW are cleared. */
9685
9686 static int
9687 hscroll_windows (window)
9688 Lisp_Object window;
9689 {
9690 int hscrolled_p;
9691
9692 if (automatic_hscrolling_p)
9693 {
9694 hscrolled_p = hscroll_window_tree (window);
9695 if (hscrolled_p)
9696 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9697 }
9698 else
9699 hscrolled_p = 0;
9700 return hscrolled_p;
9701 }
9702
9703
9704 \f
9705 /************************************************************************
9706 Redisplay
9707 ************************************************************************/
9708
9709 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9710 to a non-zero value. This is sometimes handy to have in a debugger
9711 session. */
9712
9713 #if GLYPH_DEBUG
9714
9715 /* First and last unchanged row for try_window_id. */
9716
9717 int debug_first_unchanged_at_end_vpos;
9718 int debug_last_unchanged_at_beg_vpos;
9719
9720 /* Delta vpos and y. */
9721
9722 int debug_dvpos, debug_dy;
9723
9724 /* Delta in characters and bytes for try_window_id. */
9725
9726 int debug_delta, debug_delta_bytes;
9727
9728 /* Values of window_end_pos and window_end_vpos at the end of
9729 try_window_id. */
9730
9731 EMACS_INT debug_end_pos, debug_end_vpos;
9732
9733 /* Append a string to W->desired_matrix->method. FMT is a printf
9734 format string. A1...A9 are a supplement for a variable-length
9735 argument list. If trace_redisplay_p is non-zero also printf the
9736 resulting string to stderr. */
9737
9738 static void
9739 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9740 struct window *w;
9741 char *fmt;
9742 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9743 {
9744 char buffer[512];
9745 char *method = w->desired_matrix->method;
9746 int len = strlen (method);
9747 int size = sizeof w->desired_matrix->method;
9748 int remaining = size - len - 1;
9749
9750 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9751 if (len && remaining)
9752 {
9753 method[len] = '|';
9754 --remaining, ++len;
9755 }
9756
9757 strncpy (method + len, buffer, remaining);
9758
9759 if (trace_redisplay_p)
9760 fprintf (stderr, "%p (%s): %s\n",
9761 w,
9762 ((BUFFERP (w->buffer)
9763 && STRINGP (XBUFFER (w->buffer)->name))
9764 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9765 : "no buffer"),
9766 buffer);
9767 }
9768
9769 #endif /* GLYPH_DEBUG */
9770
9771
9772 /* Value is non-zero if all changes in window W, which displays
9773 current_buffer, are in the text between START and END. START is a
9774 buffer position, END is given as a distance from Z. Used in
9775 redisplay_internal for display optimization. */
9776
9777 static INLINE int
9778 text_outside_line_unchanged_p (w, start, end)
9779 struct window *w;
9780 int start, end;
9781 {
9782 int unchanged_p = 1;
9783
9784 /* If text or overlays have changed, see where. */
9785 if (XFASTINT (w->last_modified) < MODIFF
9786 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9787 {
9788 /* Gap in the line? */
9789 if (GPT < start || Z - GPT < end)
9790 unchanged_p = 0;
9791
9792 /* Changes start in front of the line, or end after it? */
9793 if (unchanged_p
9794 && (BEG_UNCHANGED < start - 1
9795 || END_UNCHANGED < end))
9796 unchanged_p = 0;
9797
9798 /* If selective display, can't optimize if changes start at the
9799 beginning of the line. */
9800 if (unchanged_p
9801 && INTEGERP (current_buffer->selective_display)
9802 && XINT (current_buffer->selective_display) > 0
9803 && (BEG_UNCHANGED < start || GPT <= start))
9804 unchanged_p = 0;
9805
9806 /* If there are overlays at the start or end of the line, these
9807 may have overlay strings with newlines in them. A change at
9808 START, for instance, may actually concern the display of such
9809 overlay strings as well, and they are displayed on different
9810 lines. So, quickly rule out this case. (For the future, it
9811 might be desirable to implement something more telling than
9812 just BEG/END_UNCHANGED.) */
9813 if (unchanged_p)
9814 {
9815 if (BEG + BEG_UNCHANGED == start
9816 && overlay_touches_p (start))
9817 unchanged_p = 0;
9818 if (END_UNCHANGED == end
9819 && overlay_touches_p (Z - end))
9820 unchanged_p = 0;
9821 }
9822 }
9823
9824 return unchanged_p;
9825 }
9826
9827
9828 /* Do a frame update, taking possible shortcuts into account. This is
9829 the main external entry point for redisplay.
9830
9831 If the last redisplay displayed an echo area message and that message
9832 is no longer requested, we clear the echo area or bring back the
9833 mini-buffer if that is in use. */
9834
9835 void
9836 redisplay ()
9837 {
9838 redisplay_internal (0);
9839 }
9840
9841
9842 static Lisp_Object
9843 overlay_arrow_string_or_property (var)
9844 Lisp_Object var;
9845 {
9846 Lisp_Object val;
9847
9848 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
9849 return val;
9850
9851 return Voverlay_arrow_string;
9852 }
9853
9854 /* Return 1 if there are any overlay-arrows in current_buffer. */
9855 static int
9856 overlay_arrow_in_current_buffer_p ()
9857 {
9858 Lisp_Object vlist;
9859
9860 for (vlist = Voverlay_arrow_variable_list;
9861 CONSP (vlist);
9862 vlist = XCDR (vlist))
9863 {
9864 Lisp_Object var = XCAR (vlist);
9865 Lisp_Object val;
9866
9867 if (!SYMBOLP (var))
9868 continue;
9869 val = find_symbol_value (var);
9870 if (MARKERP (val)
9871 && current_buffer == XMARKER (val)->buffer)
9872 return 1;
9873 }
9874 return 0;
9875 }
9876
9877
9878 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9879 has changed. */
9880
9881 static int
9882 overlay_arrows_changed_p ()
9883 {
9884 Lisp_Object vlist;
9885
9886 for (vlist = Voverlay_arrow_variable_list;
9887 CONSP (vlist);
9888 vlist = XCDR (vlist))
9889 {
9890 Lisp_Object var = XCAR (vlist);
9891 Lisp_Object val, pstr;
9892
9893 if (!SYMBOLP (var))
9894 continue;
9895 val = find_symbol_value (var);
9896 if (!MARKERP (val))
9897 continue;
9898 if (! EQ (COERCE_MARKER (val),
9899 Fget (var, Qlast_arrow_position))
9900 || ! (pstr = overlay_arrow_string_or_property (var),
9901 EQ (pstr, Fget (var, Qlast_arrow_string))))
9902 return 1;
9903 }
9904 return 0;
9905 }
9906
9907 /* Mark overlay arrows to be updated on next redisplay. */
9908
9909 static void
9910 update_overlay_arrows (up_to_date)
9911 int up_to_date;
9912 {
9913 Lisp_Object vlist;
9914
9915 for (vlist = Voverlay_arrow_variable_list;
9916 CONSP (vlist);
9917 vlist = XCDR (vlist))
9918 {
9919 Lisp_Object var = XCAR (vlist);
9920
9921 if (!SYMBOLP (var))
9922 continue;
9923
9924 if (up_to_date > 0)
9925 {
9926 Lisp_Object val = find_symbol_value (var);
9927 Fput (var, Qlast_arrow_position,
9928 COERCE_MARKER (val));
9929 Fput (var, Qlast_arrow_string,
9930 overlay_arrow_string_or_property (var));
9931 }
9932 else if (up_to_date < 0
9933 || !NILP (Fget (var, Qlast_arrow_position)))
9934 {
9935 Fput (var, Qlast_arrow_position, Qt);
9936 Fput (var, Qlast_arrow_string, Qt);
9937 }
9938 }
9939 }
9940
9941
9942 /* Return overlay arrow string to display at row.
9943 Return integer (bitmap number) for arrow bitmap in left fringe.
9944 Return nil if no overlay arrow. */
9945
9946 static Lisp_Object
9947 overlay_arrow_at_row (it, row)
9948 struct it *it;
9949 struct glyph_row *row;
9950 {
9951 Lisp_Object vlist;
9952
9953 for (vlist = Voverlay_arrow_variable_list;
9954 CONSP (vlist);
9955 vlist = XCDR (vlist))
9956 {
9957 Lisp_Object var = XCAR (vlist);
9958 Lisp_Object val;
9959
9960 if (!SYMBOLP (var))
9961 continue;
9962
9963 val = find_symbol_value (var);
9964
9965 if (MARKERP (val)
9966 && current_buffer == XMARKER (val)->buffer
9967 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9968 {
9969 if (FRAME_WINDOW_P (it->f)
9970 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9971 {
9972 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
9973 {
9974 int fringe_bitmap;
9975 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
9976 return make_number (fringe_bitmap);
9977 }
9978 return make_number (-1); /* Use default arrow bitmap */
9979 }
9980 return overlay_arrow_string_or_property (var);
9981 }
9982 }
9983
9984 return Qnil;
9985 }
9986
9987 /* Return 1 if point moved out of or into a composition. Otherwise
9988 return 0. PREV_BUF and PREV_PT are the last point buffer and
9989 position. BUF and PT are the current point buffer and position. */
9990
9991 int
9992 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9993 struct buffer *prev_buf, *buf;
9994 int prev_pt, pt;
9995 {
9996 int start, end;
9997 Lisp_Object prop;
9998 Lisp_Object buffer;
9999
10000 XSETBUFFER (buffer, buf);
10001 /* Check a composition at the last point if point moved within the
10002 same buffer. */
10003 if (prev_buf == buf)
10004 {
10005 if (prev_pt == pt)
10006 /* Point didn't move. */
10007 return 0;
10008
10009 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
10010 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
10011 && COMPOSITION_VALID_P (start, end, prop)
10012 && start < prev_pt && end > prev_pt)
10013 /* The last point was within the composition. Return 1 iff
10014 point moved out of the composition. */
10015 return (pt <= start || pt >= end);
10016 }
10017
10018 /* Check a composition at the current point. */
10019 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
10020 && find_composition (pt, -1, &start, &end, &prop, buffer)
10021 && COMPOSITION_VALID_P (start, end, prop)
10022 && start < pt && end > pt);
10023 }
10024
10025
10026 /* Reconsider the setting of B->clip_changed which is displayed
10027 in window W. */
10028
10029 static INLINE void
10030 reconsider_clip_changes (w, b)
10031 struct window *w;
10032 struct buffer *b;
10033 {
10034 if (b->clip_changed
10035 && !NILP (w->window_end_valid)
10036 && w->current_matrix->buffer == b
10037 && w->current_matrix->zv == BUF_ZV (b)
10038 && w->current_matrix->begv == BUF_BEGV (b))
10039 b->clip_changed = 0;
10040
10041 /* If display wasn't paused, and W is not a tool bar window, see if
10042 point has been moved into or out of a composition. In that case,
10043 we set b->clip_changed to 1 to force updating the screen. If
10044 b->clip_changed has already been set to 1, we can skip this
10045 check. */
10046 if (!b->clip_changed
10047 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
10048 {
10049 int pt;
10050
10051 if (w == XWINDOW (selected_window))
10052 pt = BUF_PT (current_buffer);
10053 else
10054 pt = marker_position (w->pointm);
10055
10056 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
10057 || pt != XINT (w->last_point))
10058 && check_point_in_composition (w->current_matrix->buffer,
10059 XINT (w->last_point),
10060 XBUFFER (w->buffer), pt))
10061 b->clip_changed = 1;
10062 }
10063 }
10064 \f
10065
10066 /* Select FRAME to forward the values of frame-local variables into C
10067 variables so that the redisplay routines can access those values
10068 directly. */
10069
10070 static void
10071 select_frame_for_redisplay (frame)
10072 Lisp_Object frame;
10073 {
10074 Lisp_Object tail, sym, val;
10075 Lisp_Object old = selected_frame;
10076
10077 selected_frame = frame;
10078
10079 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
10080 if (CONSP (XCAR (tail))
10081 && (sym = XCAR (XCAR (tail)),
10082 SYMBOLP (sym))
10083 && (sym = indirect_variable (sym),
10084 val = SYMBOL_VALUE (sym),
10085 (BUFFER_LOCAL_VALUEP (val)
10086 || SOME_BUFFER_LOCAL_VALUEP (val)))
10087 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10088 /* Use find_symbol_value rather than Fsymbol_value
10089 to avoid an error if it is void. */
10090 find_symbol_value (sym);
10091
10092 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
10093 if (CONSP (XCAR (tail))
10094 && (sym = XCAR (XCAR (tail)),
10095 SYMBOLP (sym))
10096 && (sym = indirect_variable (sym),
10097 val = SYMBOL_VALUE (sym),
10098 (BUFFER_LOCAL_VALUEP (val)
10099 || SOME_BUFFER_LOCAL_VALUEP (val)))
10100 && XBUFFER_LOCAL_VALUE (val)->check_frame)
10101 find_symbol_value (sym);
10102 }
10103
10104
10105 #define STOP_POLLING \
10106 do { if (! polling_stopped_here) stop_polling (); \
10107 polling_stopped_here = 1; } while (0)
10108
10109 #define RESUME_POLLING \
10110 do { if (polling_stopped_here) start_polling (); \
10111 polling_stopped_here = 0; } while (0)
10112
10113
10114 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
10115 response to any user action; therefore, we should preserve the echo
10116 area. (Actually, our caller does that job.) Perhaps in the future
10117 avoid recentering windows if it is not necessary; currently that
10118 causes some problems. */
10119
10120 static void
10121 redisplay_internal (preserve_echo_area)
10122 int preserve_echo_area;
10123 {
10124 struct window *w = XWINDOW (selected_window);
10125 struct frame *f = XFRAME (w->frame);
10126 int pause;
10127 int must_finish = 0;
10128 struct text_pos tlbufpos, tlendpos;
10129 int number_of_visible_frames;
10130 int count;
10131 struct frame *sf = SELECTED_FRAME ();
10132 int polling_stopped_here = 0;
10133
10134 /* Non-zero means redisplay has to consider all windows on all
10135 frames. Zero means, only selected_window is considered. */
10136 int consider_all_windows_p;
10137
10138 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
10139
10140 /* No redisplay if running in batch mode or frame is not yet fully
10141 initialized, or redisplay is explicitly turned off by setting
10142 Vinhibit_redisplay. */
10143 if (noninteractive
10144 || !NILP (Vinhibit_redisplay)
10145 || !f->glyphs_initialized_p)
10146 return;
10147
10148 /* The flag redisplay_performed_directly_p is set by
10149 direct_output_for_insert when it already did the whole screen
10150 update necessary. */
10151 if (redisplay_performed_directly_p)
10152 {
10153 redisplay_performed_directly_p = 0;
10154 if (!hscroll_windows (selected_window))
10155 return;
10156 }
10157
10158 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
10159 if (popup_activated ())
10160 return;
10161 #endif
10162
10163 /* I don't think this happens but let's be paranoid. */
10164 if (redisplaying_p)
10165 return;
10166
10167 /* Record a function that resets redisplaying_p to its old value
10168 when we leave this function. */
10169 count = SPECPDL_INDEX ();
10170 record_unwind_protect (unwind_redisplay,
10171 Fcons (make_number (redisplaying_p), selected_frame));
10172 ++redisplaying_p;
10173 specbind (Qinhibit_free_realized_faces, Qnil);
10174
10175 retry:
10176 pause = 0;
10177 reconsider_clip_changes (w, current_buffer);
10178
10179 /* If new fonts have been loaded that make a glyph matrix adjustment
10180 necessary, do it. */
10181 if (fonts_changed_p)
10182 {
10183 adjust_glyphs (NULL);
10184 ++windows_or_buffers_changed;
10185 fonts_changed_p = 0;
10186 }
10187
10188 /* If face_change_count is non-zero, init_iterator will free all
10189 realized faces, which includes the faces referenced from current
10190 matrices. So, we can't reuse current matrices in this case. */
10191 if (face_change_count)
10192 ++windows_or_buffers_changed;
10193
10194 if (! FRAME_WINDOW_P (sf)
10195 && previous_terminal_frame != sf)
10196 {
10197 /* Since frames on an ASCII terminal share the same display
10198 area, displaying a different frame means redisplay the whole
10199 thing. */
10200 windows_or_buffers_changed++;
10201 SET_FRAME_GARBAGED (sf);
10202 XSETFRAME (Vterminal_frame, sf);
10203 }
10204 previous_terminal_frame = sf;
10205
10206 /* Set the visible flags for all frames. Do this before checking
10207 for resized or garbaged frames; they want to know if their frames
10208 are visible. See the comment in frame.h for
10209 FRAME_SAMPLE_VISIBILITY. */
10210 {
10211 Lisp_Object tail, frame;
10212
10213 number_of_visible_frames = 0;
10214
10215 FOR_EACH_FRAME (tail, frame)
10216 {
10217 struct frame *f = XFRAME (frame);
10218
10219 FRAME_SAMPLE_VISIBILITY (f);
10220 if (FRAME_VISIBLE_P (f))
10221 ++number_of_visible_frames;
10222 clear_desired_matrices (f);
10223 }
10224 }
10225
10226 /* Notice any pending interrupt request to change frame size. */
10227 do_pending_window_change (1);
10228
10229 /* Clear frames marked as garbaged. */
10230 if (frame_garbaged)
10231 clear_garbaged_frames ();
10232
10233 /* Build menubar and tool-bar items. */
10234 prepare_menu_bars ();
10235
10236 if (windows_or_buffers_changed)
10237 update_mode_lines++;
10238
10239 /* Detect case that we need to write or remove a star in the mode line. */
10240 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10241 {
10242 w->update_mode_line = Qt;
10243 if (buffer_shared > 1)
10244 update_mode_lines++;
10245 }
10246
10247 /* If %c is in the mode line, update it if needed. */
10248 if (!NILP (w->column_number_displayed)
10249 /* This alternative quickly identifies a common case
10250 where no change is needed. */
10251 && !(PT == XFASTINT (w->last_point)
10252 && XFASTINT (w->last_modified) >= MODIFF
10253 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10254 && (XFASTINT (w->column_number_displayed)
10255 != (int) current_column ())) /* iftc */
10256 w->update_mode_line = Qt;
10257
10258 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10259
10260 /* The variable buffer_shared is set in redisplay_window and
10261 indicates that we redisplay a buffer in different windows. See
10262 there. */
10263 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10264 || cursor_type_changed);
10265
10266 /* If specs for an arrow have changed, do thorough redisplay
10267 to ensure we remove any arrow that should no longer exist. */
10268 if (overlay_arrows_changed_p ())
10269 consider_all_windows_p = windows_or_buffers_changed = 1;
10270
10271 /* Normally the message* functions will have already displayed and
10272 updated the echo area, but the frame may have been trashed, or
10273 the update may have been preempted, so display the echo area
10274 again here. Checking message_cleared_p captures the case that
10275 the echo area should be cleared. */
10276 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10277 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10278 || (message_cleared_p
10279 && minibuf_level == 0
10280 /* If the mini-window is currently selected, this means the
10281 echo-area doesn't show through. */
10282 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10283 {
10284 int window_height_changed_p = echo_area_display (0);
10285 must_finish = 1;
10286
10287 /* If we don't display the current message, don't clear the
10288 message_cleared_p flag, because, if we did, we wouldn't clear
10289 the echo area in the next redisplay which doesn't preserve
10290 the echo area. */
10291 if (!display_last_displayed_message_p)
10292 message_cleared_p = 0;
10293
10294 if (fonts_changed_p)
10295 goto retry;
10296 else if (window_height_changed_p)
10297 {
10298 consider_all_windows_p = 1;
10299 ++update_mode_lines;
10300 ++windows_or_buffers_changed;
10301
10302 /* If window configuration was changed, frames may have been
10303 marked garbaged. Clear them or we will experience
10304 surprises wrt scrolling. */
10305 if (frame_garbaged)
10306 clear_garbaged_frames ();
10307 }
10308 }
10309 else if (EQ (selected_window, minibuf_window)
10310 && (current_buffer->clip_changed
10311 || XFASTINT (w->last_modified) < MODIFF
10312 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10313 && resize_mini_window (w, 0))
10314 {
10315 /* Resized active mini-window to fit the size of what it is
10316 showing if its contents might have changed. */
10317 must_finish = 1;
10318 consider_all_windows_p = 1;
10319 ++windows_or_buffers_changed;
10320 ++update_mode_lines;
10321
10322 /* If window configuration was changed, frames may have been
10323 marked garbaged. Clear them or we will experience
10324 surprises wrt scrolling. */
10325 if (frame_garbaged)
10326 clear_garbaged_frames ();
10327 }
10328
10329
10330 /* If showing the region, and mark has changed, we must redisplay
10331 the whole window. The assignment to this_line_start_pos prevents
10332 the optimization directly below this if-statement. */
10333 if (((!NILP (Vtransient_mark_mode)
10334 && !NILP (XBUFFER (w->buffer)->mark_active))
10335 != !NILP (w->region_showing))
10336 || (!NILP (w->region_showing)
10337 && !EQ (w->region_showing,
10338 Fmarker_position (XBUFFER (w->buffer)->mark))))
10339 CHARPOS (this_line_start_pos) = 0;
10340
10341 /* Optimize the case that only the line containing the cursor in the
10342 selected window has changed. Variables starting with this_ are
10343 set in display_line and record information about the line
10344 containing the cursor. */
10345 tlbufpos = this_line_start_pos;
10346 tlendpos = this_line_end_pos;
10347 if (!consider_all_windows_p
10348 && CHARPOS (tlbufpos) > 0
10349 && NILP (w->update_mode_line)
10350 && !current_buffer->clip_changed
10351 && !current_buffer->prevent_redisplay_optimizations_p
10352 && FRAME_VISIBLE_P (XFRAME (w->frame))
10353 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10354 /* Make sure recorded data applies to current buffer, etc. */
10355 && this_line_buffer == current_buffer
10356 && current_buffer == XBUFFER (w->buffer)
10357 && NILP (w->force_start)
10358 && NILP (w->optional_new_start)
10359 /* Point must be on the line that we have info recorded about. */
10360 && PT >= CHARPOS (tlbufpos)
10361 && PT <= Z - CHARPOS (tlendpos)
10362 /* All text outside that line, including its final newline,
10363 must be unchanged */
10364 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10365 CHARPOS (tlendpos)))
10366 {
10367 if (CHARPOS (tlbufpos) > BEGV
10368 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10369 && (CHARPOS (tlbufpos) == ZV
10370 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10371 /* Former continuation line has disappeared by becoming empty */
10372 goto cancel;
10373 else if (XFASTINT (w->last_modified) < MODIFF
10374 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10375 || MINI_WINDOW_P (w))
10376 {
10377 /* We have to handle the case of continuation around a
10378 wide-column character (See the comment in indent.c around
10379 line 885).
10380
10381 For instance, in the following case:
10382
10383 -------- Insert --------
10384 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10385 J_I_ ==> J_I_ `^^' are cursors.
10386 ^^ ^^
10387 -------- --------
10388
10389 As we have to redraw the line above, we should goto cancel. */
10390
10391 struct it it;
10392 int line_height_before = this_line_pixel_height;
10393
10394 /* Note that start_display will handle the case that the
10395 line starting at tlbufpos is a continuation lines. */
10396 start_display (&it, w, tlbufpos);
10397
10398 /* Implementation note: It this still necessary? */
10399 if (it.current_x != this_line_start_x)
10400 goto cancel;
10401
10402 TRACE ((stderr, "trying display optimization 1\n"));
10403 w->cursor.vpos = -1;
10404 overlay_arrow_seen = 0;
10405 it.vpos = this_line_vpos;
10406 it.current_y = this_line_y;
10407 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10408 display_line (&it);
10409
10410 /* If line contains point, is not continued,
10411 and ends at same distance from eob as before, we win */
10412 if (w->cursor.vpos >= 0
10413 /* Line is not continued, otherwise this_line_start_pos
10414 would have been set to 0 in display_line. */
10415 && CHARPOS (this_line_start_pos)
10416 /* Line ends as before. */
10417 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10418 /* Line has same height as before. Otherwise other lines
10419 would have to be shifted up or down. */
10420 && this_line_pixel_height == line_height_before)
10421 {
10422 /* If this is not the window's last line, we must adjust
10423 the charstarts of the lines below. */
10424 if (it.current_y < it.last_visible_y)
10425 {
10426 struct glyph_row *row
10427 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10428 int delta, delta_bytes;
10429
10430 if (Z - CHARPOS (tlendpos) == ZV)
10431 {
10432 /* This line ends at end of (accessible part of)
10433 buffer. There is no newline to count. */
10434 delta = (Z
10435 - CHARPOS (tlendpos)
10436 - MATRIX_ROW_START_CHARPOS (row));
10437 delta_bytes = (Z_BYTE
10438 - BYTEPOS (tlendpos)
10439 - MATRIX_ROW_START_BYTEPOS (row));
10440 }
10441 else
10442 {
10443 /* This line ends in a newline. Must take
10444 account of the newline and the rest of the
10445 text that follows. */
10446 delta = (Z
10447 - CHARPOS (tlendpos)
10448 - MATRIX_ROW_START_CHARPOS (row));
10449 delta_bytes = (Z_BYTE
10450 - BYTEPOS (tlendpos)
10451 - MATRIX_ROW_START_BYTEPOS (row));
10452 }
10453
10454 increment_matrix_positions (w->current_matrix,
10455 this_line_vpos + 1,
10456 w->current_matrix->nrows,
10457 delta, delta_bytes);
10458 }
10459
10460 /* If this row displays text now but previously didn't,
10461 or vice versa, w->window_end_vpos may have to be
10462 adjusted. */
10463 if ((it.glyph_row - 1)->displays_text_p)
10464 {
10465 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10466 XSETINT (w->window_end_vpos, this_line_vpos);
10467 }
10468 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10469 && this_line_vpos > 0)
10470 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10471 w->window_end_valid = Qnil;
10472
10473 /* Update hint: No need to try to scroll in update_window. */
10474 w->desired_matrix->no_scrolling_p = 1;
10475
10476 #if GLYPH_DEBUG
10477 *w->desired_matrix->method = 0;
10478 debug_method_add (w, "optimization 1");
10479 #endif
10480 #ifdef HAVE_WINDOW_SYSTEM
10481 update_window_fringes (w, 0);
10482 #endif
10483 goto update;
10484 }
10485 else
10486 goto cancel;
10487 }
10488 else if (/* Cursor position hasn't changed. */
10489 PT == XFASTINT (w->last_point)
10490 /* Make sure the cursor was last displayed
10491 in this window. Otherwise we have to reposition it. */
10492 && 0 <= w->cursor.vpos
10493 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10494 {
10495 if (!must_finish)
10496 {
10497 do_pending_window_change (1);
10498
10499 /* We used to always goto end_of_redisplay here, but this
10500 isn't enough if we have a blinking cursor. */
10501 if (w->cursor_off_p == w->last_cursor_off_p)
10502 goto end_of_redisplay;
10503 }
10504 goto update;
10505 }
10506 /* If highlighting the region, or if the cursor is in the echo area,
10507 then we can't just move the cursor. */
10508 else if (! (!NILP (Vtransient_mark_mode)
10509 && !NILP (current_buffer->mark_active))
10510 && (EQ (selected_window, current_buffer->last_selected_window)
10511 || highlight_nonselected_windows)
10512 && NILP (w->region_showing)
10513 && NILP (Vshow_trailing_whitespace)
10514 && !cursor_in_echo_area)
10515 {
10516 struct it it;
10517 struct glyph_row *row;
10518
10519 /* Skip from tlbufpos to PT and see where it is. Note that
10520 PT may be in invisible text. If so, we will end at the
10521 next visible position. */
10522 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10523 NULL, DEFAULT_FACE_ID);
10524 it.current_x = this_line_start_x;
10525 it.current_y = this_line_y;
10526 it.vpos = this_line_vpos;
10527
10528 /* The call to move_it_to stops in front of PT, but
10529 moves over before-strings. */
10530 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10531
10532 if (it.vpos == this_line_vpos
10533 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10534 row->enabled_p))
10535 {
10536 xassert (this_line_vpos == it.vpos);
10537 xassert (this_line_y == it.current_y);
10538 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10539 #if GLYPH_DEBUG
10540 *w->desired_matrix->method = 0;
10541 debug_method_add (w, "optimization 3");
10542 #endif
10543 goto update;
10544 }
10545 else
10546 goto cancel;
10547 }
10548
10549 cancel:
10550 /* Text changed drastically or point moved off of line. */
10551 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10552 }
10553
10554 CHARPOS (this_line_start_pos) = 0;
10555 consider_all_windows_p |= buffer_shared > 1;
10556 ++clear_face_cache_count;
10557 #ifdef HAVE_WINDOW_SYSTEM
10558 ++clear_image_cache_count;
10559 #endif
10560
10561 /* Build desired matrices, and update the display. If
10562 consider_all_windows_p is non-zero, do it for all windows on all
10563 frames. Otherwise do it for selected_window, only. */
10564
10565 if (consider_all_windows_p)
10566 {
10567 Lisp_Object tail, frame;
10568 int i, n = 0, size = 50;
10569 struct frame **updated
10570 = (struct frame **) alloca (size * sizeof *updated);
10571
10572 /* Recompute # windows showing selected buffer. This will be
10573 incremented each time such a window is displayed. */
10574 buffer_shared = 0;
10575
10576 FOR_EACH_FRAME (tail, frame)
10577 {
10578 struct frame *f = XFRAME (frame);
10579
10580 if (FRAME_WINDOW_P (f) || f == sf)
10581 {
10582 if (! EQ (frame, selected_frame))
10583 /* Select the frame, for the sake of frame-local
10584 variables. */
10585 select_frame_for_redisplay (frame);
10586
10587 /* Mark all the scroll bars to be removed; we'll redeem
10588 the ones we want when we redisplay their windows. */
10589 if (condemn_scroll_bars_hook)
10590 condemn_scroll_bars_hook (f);
10591
10592 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10593 redisplay_windows (FRAME_ROOT_WINDOW (f));
10594
10595 /* Any scroll bars which redisplay_windows should have
10596 nuked should now go away. */
10597 if (judge_scroll_bars_hook)
10598 judge_scroll_bars_hook (f);
10599
10600 /* If fonts changed, display again. */
10601 /* ??? rms: I suspect it is a mistake to jump all the way
10602 back to retry here. It should just retry this frame. */
10603 if (fonts_changed_p)
10604 goto retry;
10605
10606 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10607 {
10608 /* See if we have to hscroll. */
10609 if (hscroll_windows (f->root_window))
10610 goto retry;
10611
10612 /* Prevent various kinds of signals during display
10613 update. stdio is not robust about handling
10614 signals, which can cause an apparent I/O
10615 error. */
10616 if (interrupt_input)
10617 unrequest_sigio ();
10618 STOP_POLLING;
10619
10620 /* Update the display. */
10621 set_window_update_flags (XWINDOW (f->root_window), 1);
10622 pause |= update_frame (f, 0, 0);
10623 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10624 if (pause)
10625 break;
10626 #endif
10627
10628 if (n == size)
10629 {
10630 int nbytes = size * sizeof *updated;
10631 struct frame **p = (struct frame **) alloca (2 * nbytes);
10632 bcopy (updated, p, nbytes);
10633 size *= 2;
10634 }
10635
10636 updated[n++] = f;
10637 }
10638 }
10639 }
10640
10641 if (!pause)
10642 {
10643 /* Do the mark_window_display_accurate after all windows have
10644 been redisplayed because this call resets flags in buffers
10645 which are needed for proper redisplay. */
10646 for (i = 0; i < n; ++i)
10647 {
10648 struct frame *f = updated[i];
10649 mark_window_display_accurate (f->root_window, 1);
10650 if (frame_up_to_date_hook)
10651 frame_up_to_date_hook (f);
10652 }
10653 }
10654 }
10655 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10656 {
10657 Lisp_Object mini_window;
10658 struct frame *mini_frame;
10659
10660 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10661 /* Use list_of_error, not Qerror, so that
10662 we catch only errors and don't run the debugger. */
10663 internal_condition_case_1 (redisplay_window_1, selected_window,
10664 list_of_error,
10665 redisplay_window_error);
10666
10667 /* Compare desired and current matrices, perform output. */
10668
10669 update:
10670 /* If fonts changed, display again. */
10671 if (fonts_changed_p)
10672 goto retry;
10673
10674 /* Prevent various kinds of signals during display update.
10675 stdio is not robust about handling signals,
10676 which can cause an apparent I/O error. */
10677 if (interrupt_input)
10678 unrequest_sigio ();
10679 STOP_POLLING;
10680
10681 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10682 {
10683 if (hscroll_windows (selected_window))
10684 goto retry;
10685
10686 XWINDOW (selected_window)->must_be_updated_p = 1;
10687 pause = update_frame (sf, 0, 0);
10688 }
10689
10690 /* We may have called echo_area_display at the top of this
10691 function. If the echo area is on another frame, that may
10692 have put text on a frame other than the selected one, so the
10693 above call to update_frame would not have caught it. Catch
10694 it here. */
10695 mini_window = FRAME_MINIBUF_WINDOW (sf);
10696 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10697
10698 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10699 {
10700 XWINDOW (mini_window)->must_be_updated_p = 1;
10701 pause |= update_frame (mini_frame, 0, 0);
10702 if (!pause && hscroll_windows (mini_window))
10703 goto retry;
10704 }
10705 }
10706
10707 /* If display was paused because of pending input, make sure we do a
10708 thorough update the next time. */
10709 if (pause)
10710 {
10711 /* Prevent the optimization at the beginning of
10712 redisplay_internal that tries a single-line update of the
10713 line containing the cursor in the selected window. */
10714 CHARPOS (this_line_start_pos) = 0;
10715
10716 /* Let the overlay arrow be updated the next time. */
10717 update_overlay_arrows (0);
10718
10719 /* If we pause after scrolling, some rows in the current
10720 matrices of some windows are not valid. */
10721 if (!WINDOW_FULL_WIDTH_P (w)
10722 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10723 update_mode_lines = 1;
10724 }
10725 else
10726 {
10727 if (!consider_all_windows_p)
10728 {
10729 /* This has already been done above if
10730 consider_all_windows_p is set. */
10731 mark_window_display_accurate_1 (w, 1);
10732
10733 /* Say overlay arrows are up to date. */
10734 update_overlay_arrows (1);
10735
10736 if (frame_up_to_date_hook != 0)
10737 frame_up_to_date_hook (sf);
10738 }
10739
10740 update_mode_lines = 0;
10741 windows_or_buffers_changed = 0;
10742 cursor_type_changed = 0;
10743 }
10744
10745 /* Start SIGIO interrupts coming again. Having them off during the
10746 code above makes it less likely one will discard output, but not
10747 impossible, since there might be stuff in the system buffer here.
10748 But it is much hairier to try to do anything about that. */
10749 if (interrupt_input)
10750 request_sigio ();
10751 RESUME_POLLING;
10752
10753 /* If a frame has become visible which was not before, redisplay
10754 again, so that we display it. Expose events for such a frame
10755 (which it gets when becoming visible) don't call the parts of
10756 redisplay constructing glyphs, so simply exposing a frame won't
10757 display anything in this case. So, we have to display these
10758 frames here explicitly. */
10759 if (!pause)
10760 {
10761 Lisp_Object tail, frame;
10762 int new_count = 0;
10763
10764 FOR_EACH_FRAME (tail, frame)
10765 {
10766 int this_is_visible = 0;
10767
10768 if (XFRAME (frame)->visible)
10769 this_is_visible = 1;
10770 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10771 if (XFRAME (frame)->visible)
10772 this_is_visible = 1;
10773
10774 if (this_is_visible)
10775 new_count++;
10776 }
10777
10778 if (new_count != number_of_visible_frames)
10779 windows_or_buffers_changed++;
10780 }
10781
10782 /* Change frame size now if a change is pending. */
10783 do_pending_window_change (1);
10784
10785 /* If we just did a pending size change, or have additional
10786 visible frames, redisplay again. */
10787 if (windows_or_buffers_changed && !pause)
10788 goto retry;
10789
10790 /* Clear the face cache eventually. */
10791 if (consider_all_windows_p)
10792 {
10793 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10794 {
10795 clear_face_cache (0);
10796 clear_face_cache_count = 0;
10797 }
10798 #ifdef HAVE_WINDOW_SYSTEM
10799 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
10800 {
10801 Lisp_Object tail, frame;
10802 FOR_EACH_FRAME (tail, frame)
10803 {
10804 struct frame *f = XFRAME (frame);
10805 if (FRAME_WINDOW_P (f))
10806 clear_image_cache (f, 0);
10807 }
10808 clear_image_cache_count = 0;
10809 }
10810 #endif /* HAVE_WINDOW_SYSTEM */
10811 }
10812
10813 end_of_redisplay:
10814 unbind_to (count, Qnil);
10815 RESUME_POLLING;
10816 }
10817
10818
10819 /* Redisplay, but leave alone any recent echo area message unless
10820 another message has been requested in its place.
10821
10822 This is useful in situations where you need to redisplay but no
10823 user action has occurred, making it inappropriate for the message
10824 area to be cleared. See tracking_off and
10825 wait_reading_process_output for examples of these situations.
10826
10827 FROM_WHERE is an integer saying from where this function was
10828 called. This is useful for debugging. */
10829
10830 void
10831 redisplay_preserve_echo_area (from_where)
10832 int from_where;
10833 {
10834 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10835
10836 if (!NILP (echo_area_buffer[1]))
10837 {
10838 /* We have a previously displayed message, but no current
10839 message. Redisplay the previous message. */
10840 display_last_displayed_message_p = 1;
10841 redisplay_internal (1);
10842 display_last_displayed_message_p = 0;
10843 }
10844 else
10845 redisplay_internal (1);
10846
10847 if (rif != NULL && rif->flush_display_optional)
10848 rif->flush_display_optional (NULL);
10849 }
10850
10851
10852 /* Function registered with record_unwind_protect in
10853 redisplay_internal. Reset redisplaying_p to the value it had
10854 before redisplay_internal was called, and clear
10855 prevent_freeing_realized_faces_p. It also selects the previously
10856 selected frame. */
10857
10858 static Lisp_Object
10859 unwind_redisplay (val)
10860 Lisp_Object val;
10861 {
10862 Lisp_Object old_redisplaying_p, old_frame;
10863
10864 old_redisplaying_p = XCAR (val);
10865 redisplaying_p = XFASTINT (old_redisplaying_p);
10866 old_frame = XCDR (val);
10867 if (! EQ (old_frame, selected_frame))
10868 select_frame_for_redisplay (old_frame);
10869 return Qnil;
10870 }
10871
10872
10873 /* Mark the display of window W as accurate or inaccurate. If
10874 ACCURATE_P is non-zero mark display of W as accurate. If
10875 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10876 redisplay_internal is called. */
10877
10878 static void
10879 mark_window_display_accurate_1 (w, accurate_p)
10880 struct window *w;
10881 int accurate_p;
10882 {
10883 if (BUFFERP (w->buffer))
10884 {
10885 struct buffer *b = XBUFFER (w->buffer);
10886
10887 w->last_modified
10888 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10889 w->last_overlay_modified
10890 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10891 w->last_had_star
10892 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10893
10894 if (accurate_p)
10895 {
10896 b->clip_changed = 0;
10897 b->prevent_redisplay_optimizations_p = 0;
10898
10899 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10900 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10901 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10902 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10903
10904 w->current_matrix->buffer = b;
10905 w->current_matrix->begv = BUF_BEGV (b);
10906 w->current_matrix->zv = BUF_ZV (b);
10907
10908 w->last_cursor = w->cursor;
10909 w->last_cursor_off_p = w->cursor_off_p;
10910
10911 if (w == XWINDOW (selected_window))
10912 w->last_point = make_number (BUF_PT (b));
10913 else
10914 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10915 }
10916 }
10917
10918 if (accurate_p)
10919 {
10920 w->window_end_valid = w->buffer;
10921 #if 0 /* This is incorrect with variable-height lines. */
10922 xassert (XINT (w->window_end_vpos)
10923 < (WINDOW_TOTAL_LINES (w)
10924 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10925 #endif
10926 w->update_mode_line = Qnil;
10927 }
10928 }
10929
10930
10931 /* Mark the display of windows in the window tree rooted at WINDOW as
10932 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10933 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10934 be redisplayed the next time redisplay_internal is called. */
10935
10936 void
10937 mark_window_display_accurate (window, accurate_p)
10938 Lisp_Object window;
10939 int accurate_p;
10940 {
10941 struct window *w;
10942
10943 for (; !NILP (window); window = w->next)
10944 {
10945 w = XWINDOW (window);
10946 mark_window_display_accurate_1 (w, accurate_p);
10947
10948 if (!NILP (w->vchild))
10949 mark_window_display_accurate (w->vchild, accurate_p);
10950 if (!NILP (w->hchild))
10951 mark_window_display_accurate (w->hchild, accurate_p);
10952 }
10953
10954 if (accurate_p)
10955 {
10956 update_overlay_arrows (1);
10957 }
10958 else
10959 {
10960 /* Force a thorough redisplay the next time by setting
10961 last_arrow_position and last_arrow_string to t, which is
10962 unequal to any useful value of Voverlay_arrow_... */
10963 update_overlay_arrows (-1);
10964 }
10965 }
10966
10967
10968 /* Return value in display table DP (Lisp_Char_Table *) for character
10969 C. Since a display table doesn't have any parent, we don't have to
10970 follow parent. Do not call this function directly but use the
10971 macro DISP_CHAR_VECTOR. */
10972
10973 Lisp_Object
10974 disp_char_vector (dp, c)
10975 struct Lisp_Char_Table *dp;
10976 int c;
10977 {
10978 int code[4], i;
10979 Lisp_Object val;
10980
10981 if (SINGLE_BYTE_CHAR_P (c))
10982 return (dp->contents[c]);
10983
10984 SPLIT_CHAR (c, code[0], code[1], code[2]);
10985 if (code[1] < 32)
10986 code[1] = -1;
10987 else if (code[2] < 32)
10988 code[2] = -1;
10989
10990 /* Here, the possible range of code[0] (== charset ID) is
10991 128..max_charset. Since the top level char table contains data
10992 for multibyte characters after 256th element, we must increment
10993 code[0] by 128 to get a correct index. */
10994 code[0] += 128;
10995 code[3] = -1; /* anchor */
10996
10997 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10998 {
10999 val = dp->contents[code[i]];
11000 if (!SUB_CHAR_TABLE_P (val))
11001 return (NILP (val) ? dp->defalt : val);
11002 }
11003
11004 /* Here, val is a sub char table. We return the default value of
11005 it. */
11006 return (dp->defalt);
11007 }
11008
11009
11010 \f
11011 /***********************************************************************
11012 Window Redisplay
11013 ***********************************************************************/
11014
11015 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
11016
11017 static void
11018 redisplay_windows (window)
11019 Lisp_Object window;
11020 {
11021 while (!NILP (window))
11022 {
11023 struct window *w = XWINDOW (window);
11024
11025 if (!NILP (w->hchild))
11026 redisplay_windows (w->hchild);
11027 else if (!NILP (w->vchild))
11028 redisplay_windows (w->vchild);
11029 else
11030 {
11031 displayed_buffer = XBUFFER (w->buffer);
11032 /* Use list_of_error, not Qerror, so that
11033 we catch only errors and don't run the debugger. */
11034 internal_condition_case_1 (redisplay_window_0, window,
11035 list_of_error,
11036 redisplay_window_error);
11037 }
11038
11039 window = w->next;
11040 }
11041 }
11042
11043 static Lisp_Object
11044 redisplay_window_error ()
11045 {
11046 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
11047 return Qnil;
11048 }
11049
11050 static Lisp_Object
11051 redisplay_window_0 (window)
11052 Lisp_Object window;
11053 {
11054 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11055 redisplay_window (window, 0);
11056 return Qnil;
11057 }
11058
11059 static Lisp_Object
11060 redisplay_window_1 (window)
11061 Lisp_Object window;
11062 {
11063 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
11064 redisplay_window (window, 1);
11065 return Qnil;
11066 }
11067 \f
11068
11069 /* Increment GLYPH until it reaches END or CONDITION fails while
11070 adding (GLYPH)->pixel_width to X. */
11071
11072 #define SKIP_GLYPHS(glyph, end, x, condition) \
11073 do \
11074 { \
11075 (x) += (glyph)->pixel_width; \
11076 ++(glyph); \
11077 } \
11078 while ((glyph) < (end) && (condition))
11079
11080
11081 /* Set cursor position of W. PT is assumed to be displayed in ROW.
11082 DELTA is the number of bytes by which positions recorded in ROW
11083 differ from current buffer positions. */
11084
11085 void
11086 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
11087 struct window *w;
11088 struct glyph_row *row;
11089 struct glyph_matrix *matrix;
11090 int delta, delta_bytes, dy, dvpos;
11091 {
11092 struct glyph *glyph = row->glyphs[TEXT_AREA];
11093 struct glyph *end = glyph + row->used[TEXT_AREA];
11094 struct glyph *cursor = NULL;
11095 /* The first glyph that starts a sequence of glyphs from string. */
11096 struct glyph *string_start;
11097 /* The X coordinate of string_start. */
11098 int string_start_x;
11099 /* The last known character position. */
11100 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
11101 /* The last known character position before string_start. */
11102 int string_before_pos;
11103 int x = row->x;
11104 int cursor_x = x;
11105 int cursor_from_overlay_pos = 0;
11106 int pt_old = PT - delta;
11107
11108 /* Skip over glyphs not having an object at the start of the row.
11109 These are special glyphs like truncation marks on terminal
11110 frames. */
11111 if (row->displays_text_p)
11112 while (glyph < end
11113 && INTEGERP (glyph->object)
11114 && glyph->charpos < 0)
11115 {
11116 x += glyph->pixel_width;
11117 ++glyph;
11118 }
11119
11120 string_start = NULL;
11121 while (glyph < end
11122 && !INTEGERP (glyph->object)
11123 && (!BUFFERP (glyph->object)
11124 || (last_pos = glyph->charpos) < pt_old))
11125 {
11126 if (! STRINGP (glyph->object))
11127 {
11128 string_start = NULL;
11129 x += glyph->pixel_width;
11130 ++glyph;
11131 if (cursor_from_overlay_pos
11132 && last_pos > cursor_from_overlay_pos)
11133 {
11134 cursor_from_overlay_pos = 0;
11135 cursor = 0;
11136 }
11137 }
11138 else
11139 {
11140 string_before_pos = last_pos;
11141 string_start = glyph;
11142 string_start_x = x;
11143 /* Skip all glyphs from string. */
11144 do
11145 {
11146 int pos;
11147 if ((cursor == NULL || glyph > cursor)
11148 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
11149 Qcursor, (glyph)->object))
11150 && (pos = string_buffer_position (w, glyph->object,
11151 string_before_pos),
11152 (pos == 0 /* From overlay */
11153 || pos == pt_old)))
11154 {
11155 /* Estimate overlay buffer position from the buffer
11156 positions of the glyphs before and after the overlay.
11157 Add 1 to last_pos so that if point corresponds to the
11158 glyph right after the overlay, we still use a 'cursor'
11159 property found in that overlay. */
11160 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
11161 cursor = glyph;
11162 cursor_x = x;
11163 }
11164 x += glyph->pixel_width;
11165 ++glyph;
11166 }
11167 while (glyph < end && STRINGP (glyph->object));
11168 }
11169 }
11170
11171 if (cursor != NULL)
11172 {
11173 glyph = cursor;
11174 x = cursor_x;
11175 }
11176 else if (row->ends_in_ellipsis_p && glyph == end)
11177 {
11178 /* Scan back over the ellipsis glyphs, decrementing positions. */
11179 while (glyph > row->glyphs[TEXT_AREA]
11180 && (glyph - 1)->charpos == last_pos)
11181 glyph--, x -= glyph->pixel_width;
11182 /* That loop always goes one position too far,
11183 including the glyph before the ellipsis.
11184 So scan forward over that one. */
11185 x += glyph->pixel_width;
11186 glyph++;
11187 }
11188 else if (string_start
11189 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
11190 {
11191 /* We may have skipped over point because the previous glyphs
11192 are from string. As there's no easy way to know the
11193 character position of the current glyph, find the correct
11194 glyph on point by scanning from string_start again. */
11195 Lisp_Object limit;
11196 Lisp_Object string;
11197 int pos;
11198
11199 limit = make_number (pt_old + 1);
11200 end = glyph;
11201 glyph = string_start;
11202 x = string_start_x;
11203 string = glyph->object;
11204 pos = string_buffer_position (w, string, string_before_pos);
11205 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11206 because we always put cursor after overlay strings. */
11207 while (pos == 0 && glyph < end)
11208 {
11209 string = glyph->object;
11210 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11211 if (glyph < end)
11212 pos = string_buffer_position (w, glyph->object, string_before_pos);
11213 }
11214
11215 while (glyph < end)
11216 {
11217 pos = XINT (Fnext_single_char_property_change
11218 (make_number (pos), Qdisplay, Qnil, limit));
11219 if (pos > pt_old)
11220 break;
11221 /* Skip glyphs from the same string. */
11222 string = glyph->object;
11223 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11224 /* Skip glyphs from an overlay. */
11225 while (glyph < end
11226 && ! string_buffer_position (w, glyph->object, pos))
11227 {
11228 string = glyph->object;
11229 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11230 }
11231 }
11232 }
11233
11234 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
11235 w->cursor.x = x;
11236 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
11237 w->cursor.y = row->y + dy;
11238
11239 if (w == XWINDOW (selected_window))
11240 {
11241 if (!row->continued_p
11242 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
11243 && row->x == 0)
11244 {
11245 this_line_buffer = XBUFFER (w->buffer);
11246
11247 CHARPOS (this_line_start_pos)
11248 = MATRIX_ROW_START_CHARPOS (row) + delta;
11249 BYTEPOS (this_line_start_pos)
11250 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
11251
11252 CHARPOS (this_line_end_pos)
11253 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
11254 BYTEPOS (this_line_end_pos)
11255 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
11256
11257 this_line_y = w->cursor.y;
11258 this_line_pixel_height = row->height;
11259 this_line_vpos = w->cursor.vpos;
11260 this_line_start_x = row->x;
11261 }
11262 else
11263 CHARPOS (this_line_start_pos) = 0;
11264 }
11265 }
11266
11267
11268 /* Run window scroll functions, if any, for WINDOW with new window
11269 start STARTP. Sets the window start of WINDOW to that position.
11270
11271 We assume that the window's buffer is really current. */
11272
11273 static INLINE struct text_pos
11274 run_window_scroll_functions (window, startp)
11275 Lisp_Object window;
11276 struct text_pos startp;
11277 {
11278 struct window *w = XWINDOW (window);
11279 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11280
11281 if (current_buffer != XBUFFER (w->buffer))
11282 abort ();
11283
11284 if (!NILP (Vwindow_scroll_functions))
11285 {
11286 run_hook_with_args_2 (Qwindow_scroll_functions, window,
11287 make_number (CHARPOS (startp)));
11288 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11289 /* In case the hook functions switch buffers. */
11290 if (current_buffer != XBUFFER (w->buffer))
11291 set_buffer_internal_1 (XBUFFER (w->buffer));
11292 }
11293
11294 return startp;
11295 }
11296
11297
11298 /* Make sure the line containing the cursor is fully visible.
11299 A value of 1 means there is nothing to be done.
11300 (Either the line is fully visible, or it cannot be made so,
11301 or we cannot tell.)
11302
11303 If FORCE_P is non-zero, return 0 even if partial visible cursor row
11304 is higher than window.
11305
11306 A value of 0 means the caller should do scrolling
11307 as if point had gone off the screen. */
11308
11309 static int
11310 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11311 struct window *w;
11312 int force_p;
11313 {
11314 struct glyph_matrix *matrix;
11315 struct glyph_row *row;
11316 int window_height;
11317
11318 if (!make_cursor_line_fully_visible_p)
11319 return 1;
11320
11321 /* It's not always possible to find the cursor, e.g, when a window
11322 is full of overlay strings. Don't do anything in that case. */
11323 if (w->cursor.vpos < 0)
11324 return 1;
11325
11326 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11327 row = MATRIX_ROW (matrix, w->cursor.vpos);
11328
11329 /* If the cursor row is not partially visible, there's nothing to do. */
11330 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
11331 return 1;
11332
11333 /* If the row the cursor is in is taller than the window's height,
11334 it's not clear what to do, so do nothing. */
11335 window_height = window_box_height (w);
11336 if (row->height >= window_height)
11337 {
11338 if (!force_p || MINI_WINDOW_P (w) || w->vscroll)
11339 return 1;
11340 }
11341 return 0;
11342
11343 #if 0
11344 /* This code used to try to scroll the window just enough to make
11345 the line visible. It returned 0 to say that the caller should
11346 allocate larger glyph matrices. */
11347
11348 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11349 {
11350 int dy = row->height - row->visible_height;
11351 w->vscroll = 0;
11352 w->cursor.y += dy;
11353 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11354 }
11355 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11356 {
11357 int dy = - (row->height - row->visible_height);
11358 w->vscroll = dy;
11359 w->cursor.y += dy;
11360 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11361 }
11362
11363 /* When we change the cursor y-position of the selected window,
11364 change this_line_y as well so that the display optimization for
11365 the cursor line of the selected window in redisplay_internal uses
11366 the correct y-position. */
11367 if (w == XWINDOW (selected_window))
11368 this_line_y = w->cursor.y;
11369
11370 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11371 redisplay with larger matrices. */
11372 if (matrix->nrows < required_matrix_height (w))
11373 {
11374 fonts_changed_p = 1;
11375 return 0;
11376 }
11377
11378 return 1;
11379 #endif /* 0 */
11380 }
11381
11382
11383 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11384 non-zero means only WINDOW is redisplayed in redisplay_internal.
11385 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11386 in redisplay_window to bring a partially visible line into view in
11387 the case that only the cursor has moved.
11388
11389 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11390 last screen line's vertical height extends past the end of the screen.
11391
11392 Value is
11393
11394 1 if scrolling succeeded
11395
11396 0 if scrolling didn't find point.
11397
11398 -1 if new fonts have been loaded so that we must interrupt
11399 redisplay, adjust glyph matrices, and try again. */
11400
11401 enum
11402 {
11403 SCROLLING_SUCCESS,
11404 SCROLLING_FAILED,
11405 SCROLLING_NEED_LARGER_MATRICES
11406 };
11407
11408 static int
11409 try_scrolling (window, just_this_one_p, scroll_conservatively,
11410 scroll_step, temp_scroll_step, last_line_misfit)
11411 Lisp_Object window;
11412 int just_this_one_p;
11413 EMACS_INT scroll_conservatively, scroll_step;
11414 int temp_scroll_step;
11415 int last_line_misfit;
11416 {
11417 struct window *w = XWINDOW (window);
11418 struct frame *f = XFRAME (w->frame);
11419 struct text_pos scroll_margin_pos;
11420 struct text_pos pos;
11421 struct text_pos startp;
11422 struct it it;
11423 Lisp_Object window_end;
11424 int this_scroll_margin;
11425 int dy = 0;
11426 int scroll_max;
11427 int rc;
11428 int amount_to_scroll = 0;
11429 Lisp_Object aggressive;
11430 int height;
11431 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11432
11433 #if GLYPH_DEBUG
11434 debug_method_add (w, "try_scrolling");
11435 #endif
11436
11437 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11438
11439 /* Compute scroll margin height in pixels. We scroll when point is
11440 within this distance from the top or bottom of the window. */
11441 if (scroll_margin > 0)
11442 {
11443 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11444 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11445 }
11446 else
11447 this_scroll_margin = 0;
11448
11449 /* Force scroll_conservatively to have a reasonable value so it doesn't
11450 cause an overflow while computing how much to scroll. */
11451 if (scroll_conservatively)
11452 scroll_conservatively = min (scroll_conservatively,
11453 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11454
11455 /* Compute how much we should try to scroll maximally to bring point
11456 into view. */
11457 if (scroll_step || scroll_conservatively || temp_scroll_step)
11458 scroll_max = max (scroll_step,
11459 max (scroll_conservatively, temp_scroll_step));
11460 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11461 || NUMBERP (current_buffer->scroll_up_aggressively))
11462 /* We're trying to scroll because of aggressive scrolling
11463 but no scroll_step is set. Choose an arbitrary one. Maybe
11464 there should be a variable for this. */
11465 scroll_max = 10;
11466 else
11467 scroll_max = 0;
11468 scroll_max *= FRAME_LINE_HEIGHT (f);
11469
11470 /* Decide whether we have to scroll down. Start at the window end
11471 and move this_scroll_margin up to find the position of the scroll
11472 margin. */
11473 window_end = Fwindow_end (window, Qt);
11474
11475 too_near_end:
11476
11477 CHARPOS (scroll_margin_pos) = XINT (window_end);
11478 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11479
11480 if (this_scroll_margin || extra_scroll_margin_lines)
11481 {
11482 start_display (&it, w, scroll_margin_pos);
11483 if (this_scroll_margin)
11484 move_it_vertically_backward (&it, this_scroll_margin);
11485 if (extra_scroll_margin_lines)
11486 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11487 scroll_margin_pos = it.current.pos;
11488 }
11489
11490 if (PT >= CHARPOS (scroll_margin_pos))
11491 {
11492 int y0;
11493
11494 /* Point is in the scroll margin at the bottom of the window, or
11495 below. Compute a new window start that makes point visible. */
11496
11497 /* Compute the distance from the scroll margin to PT.
11498 Give up if the distance is greater than scroll_max. */
11499 start_display (&it, w, scroll_margin_pos);
11500 y0 = it.current_y;
11501 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11502 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11503
11504 /* To make point visible, we have to move the window start
11505 down so that the line the cursor is in is visible, which
11506 means we have to add in the height of the cursor line. */
11507 dy = line_bottom_y (&it) - y0;
11508
11509 if (dy > scroll_max)
11510 return SCROLLING_FAILED;
11511
11512 /* Move the window start down. If scrolling conservatively,
11513 move it just enough down to make point visible. If
11514 scroll_step is set, move it down by scroll_step. */
11515 start_display (&it, w, startp);
11516
11517 if (scroll_conservatively)
11518 /* Set AMOUNT_TO_SCROLL to at least one line,
11519 and at most scroll_conservatively lines. */
11520 amount_to_scroll
11521 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11522 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11523 else if (scroll_step || temp_scroll_step)
11524 amount_to_scroll = scroll_max;
11525 else
11526 {
11527 aggressive = current_buffer->scroll_up_aggressively;
11528 height = WINDOW_BOX_TEXT_HEIGHT (w);
11529 if (NUMBERP (aggressive))
11530 {
11531 double float_amount = XFLOATINT (aggressive) * height;
11532 amount_to_scroll = float_amount;
11533 if (amount_to_scroll == 0 && float_amount > 0)
11534 amount_to_scroll = 1;
11535 }
11536 }
11537
11538 if (amount_to_scroll <= 0)
11539 return SCROLLING_FAILED;
11540
11541 /* If moving by amount_to_scroll leaves STARTP unchanged,
11542 move it down one screen line. */
11543
11544 move_it_vertically (&it, amount_to_scroll);
11545 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11546 move_it_by_lines (&it, 1, 1);
11547 startp = it.current.pos;
11548 }
11549 else
11550 {
11551 /* See if point is inside the scroll margin at the top of the
11552 window. */
11553 scroll_margin_pos = startp;
11554 if (this_scroll_margin)
11555 {
11556 start_display (&it, w, startp);
11557 move_it_vertically (&it, this_scroll_margin);
11558 scroll_margin_pos = it.current.pos;
11559 }
11560
11561 if (PT < CHARPOS (scroll_margin_pos))
11562 {
11563 /* Point is in the scroll margin at the top of the window or
11564 above what is displayed in the window. */
11565 int y0;
11566
11567 /* Compute the vertical distance from PT to the scroll
11568 margin position. Give up if distance is greater than
11569 scroll_max. */
11570 SET_TEXT_POS (pos, PT, PT_BYTE);
11571 start_display (&it, w, pos);
11572 y0 = it.current_y;
11573 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11574 it.last_visible_y, -1,
11575 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11576 dy = it.current_y - y0;
11577 if (dy > scroll_max)
11578 return SCROLLING_FAILED;
11579
11580 /* Compute new window start. */
11581 start_display (&it, w, startp);
11582
11583 if (scroll_conservatively)
11584 amount_to_scroll
11585 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11586 else if (scroll_step || temp_scroll_step)
11587 amount_to_scroll = scroll_max;
11588 else
11589 {
11590 aggressive = current_buffer->scroll_down_aggressively;
11591 height = WINDOW_BOX_TEXT_HEIGHT (w);
11592 if (NUMBERP (aggressive))
11593 {
11594 double float_amount = XFLOATINT (aggressive) * height;
11595 amount_to_scroll = float_amount;
11596 if (amount_to_scroll == 0 && float_amount > 0)
11597 amount_to_scroll = 1;
11598 }
11599 }
11600
11601 if (amount_to_scroll <= 0)
11602 return SCROLLING_FAILED;
11603
11604 move_it_vertically_backward (&it, amount_to_scroll);
11605 startp = it.current.pos;
11606 }
11607 }
11608
11609 /* Run window scroll functions. */
11610 startp = run_window_scroll_functions (window, startp);
11611
11612 /* Display the window. Give up if new fonts are loaded, or if point
11613 doesn't appear. */
11614 if (!try_window (window, startp, 0))
11615 rc = SCROLLING_NEED_LARGER_MATRICES;
11616 else if (w->cursor.vpos < 0)
11617 {
11618 clear_glyph_matrix (w->desired_matrix);
11619 rc = SCROLLING_FAILED;
11620 }
11621 else
11622 {
11623 /* Maybe forget recorded base line for line number display. */
11624 if (!just_this_one_p
11625 || current_buffer->clip_changed
11626 || BEG_UNCHANGED < CHARPOS (startp))
11627 w->base_line_number = Qnil;
11628
11629 /* If cursor ends up on a partially visible line,
11630 treat that as being off the bottom of the screen. */
11631 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
11632 {
11633 clear_glyph_matrix (w->desired_matrix);
11634 ++extra_scroll_margin_lines;
11635 goto too_near_end;
11636 }
11637 rc = SCROLLING_SUCCESS;
11638 }
11639
11640 return rc;
11641 }
11642
11643
11644 /* Compute a suitable window start for window W if display of W starts
11645 on a continuation line. Value is non-zero if a new window start
11646 was computed.
11647
11648 The new window start will be computed, based on W's width, starting
11649 from the start of the continued line. It is the start of the
11650 screen line with the minimum distance from the old start W->start. */
11651
11652 static int
11653 compute_window_start_on_continuation_line (w)
11654 struct window *w;
11655 {
11656 struct text_pos pos, start_pos;
11657 int window_start_changed_p = 0;
11658
11659 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11660
11661 /* If window start is on a continuation line... Window start may be
11662 < BEGV in case there's invisible text at the start of the
11663 buffer (M-x rmail, for example). */
11664 if (CHARPOS (start_pos) > BEGV
11665 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11666 {
11667 struct it it;
11668 struct glyph_row *row;
11669
11670 /* Handle the case that the window start is out of range. */
11671 if (CHARPOS (start_pos) < BEGV)
11672 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11673 else if (CHARPOS (start_pos) > ZV)
11674 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11675
11676 /* Find the start of the continued line. This should be fast
11677 because scan_buffer is fast (newline cache). */
11678 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11679 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11680 row, DEFAULT_FACE_ID);
11681 reseat_at_previous_visible_line_start (&it);
11682
11683 /* If the line start is "too far" away from the window start,
11684 say it takes too much time to compute a new window start. */
11685 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11686 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11687 {
11688 int min_distance, distance;
11689
11690 /* Move forward by display lines to find the new window
11691 start. If window width was enlarged, the new start can
11692 be expected to be > the old start. If window width was
11693 decreased, the new window start will be < the old start.
11694 So, we're looking for the display line start with the
11695 minimum distance from the old window start. */
11696 pos = it.current.pos;
11697 min_distance = INFINITY;
11698 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11699 distance < min_distance)
11700 {
11701 min_distance = distance;
11702 pos = it.current.pos;
11703 move_it_by_lines (&it, 1, 0);
11704 }
11705
11706 /* Set the window start there. */
11707 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11708 window_start_changed_p = 1;
11709 }
11710 }
11711
11712 return window_start_changed_p;
11713 }
11714
11715
11716 /* Try cursor movement in case text has not changed in window WINDOW,
11717 with window start STARTP. Value is
11718
11719 CURSOR_MOVEMENT_SUCCESS if successful
11720
11721 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11722
11723 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11724 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11725 we want to scroll as if scroll-step were set to 1. See the code.
11726
11727 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11728 which case we have to abort this redisplay, and adjust matrices
11729 first. */
11730
11731 enum
11732 {
11733 CURSOR_MOVEMENT_SUCCESS,
11734 CURSOR_MOVEMENT_CANNOT_BE_USED,
11735 CURSOR_MOVEMENT_MUST_SCROLL,
11736 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11737 };
11738
11739 static int
11740 try_cursor_movement (window, startp, scroll_step)
11741 Lisp_Object window;
11742 struct text_pos startp;
11743 int *scroll_step;
11744 {
11745 struct window *w = XWINDOW (window);
11746 struct frame *f = XFRAME (w->frame);
11747 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11748
11749 #if GLYPH_DEBUG
11750 if (inhibit_try_cursor_movement)
11751 return rc;
11752 #endif
11753
11754 /* Handle case where text has not changed, only point, and it has
11755 not moved off the frame. */
11756 if (/* Point may be in this window. */
11757 PT >= CHARPOS (startp)
11758 /* Selective display hasn't changed. */
11759 && !current_buffer->clip_changed
11760 /* Function force-mode-line-update is used to force a thorough
11761 redisplay. It sets either windows_or_buffers_changed or
11762 update_mode_lines. So don't take a shortcut here for these
11763 cases. */
11764 && !update_mode_lines
11765 && !windows_or_buffers_changed
11766 && !cursor_type_changed
11767 /* Can't use this case if highlighting a region. When a
11768 region exists, cursor movement has to do more than just
11769 set the cursor. */
11770 && !(!NILP (Vtransient_mark_mode)
11771 && !NILP (current_buffer->mark_active))
11772 && NILP (w->region_showing)
11773 && NILP (Vshow_trailing_whitespace)
11774 /* Right after splitting windows, last_point may be nil. */
11775 && INTEGERP (w->last_point)
11776 /* This code is not used for mini-buffer for the sake of the case
11777 of redisplaying to replace an echo area message; since in
11778 that case the mini-buffer contents per se are usually
11779 unchanged. This code is of no real use in the mini-buffer
11780 since the handling of this_line_start_pos, etc., in redisplay
11781 handles the same cases. */
11782 && !EQ (window, minibuf_window)
11783 /* When splitting windows or for new windows, it happens that
11784 redisplay is called with a nil window_end_vpos or one being
11785 larger than the window. This should really be fixed in
11786 window.c. I don't have this on my list, now, so we do
11787 approximately the same as the old redisplay code. --gerd. */
11788 && INTEGERP (w->window_end_vpos)
11789 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11790 && (FRAME_WINDOW_P (f)
11791 || !overlay_arrow_in_current_buffer_p ()))
11792 {
11793 int this_scroll_margin, top_scroll_margin;
11794 struct glyph_row *row = NULL;
11795
11796 #if GLYPH_DEBUG
11797 debug_method_add (w, "cursor movement");
11798 #endif
11799
11800 /* Scroll if point within this distance from the top or bottom
11801 of the window. This is a pixel value. */
11802 this_scroll_margin = max (0, scroll_margin);
11803 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11804 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11805
11806 top_scroll_margin = this_scroll_margin;
11807 if (WINDOW_WANTS_HEADER_LINE_P (w))
11808 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11809
11810 /* Start with the row the cursor was displayed during the last
11811 not paused redisplay. Give up if that row is not valid. */
11812 if (w->last_cursor.vpos < 0
11813 || w->last_cursor.vpos >= w->current_matrix->nrows)
11814 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11815 else
11816 {
11817 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11818 if (row->mode_line_p)
11819 ++row;
11820 if (!row->enabled_p)
11821 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11822 }
11823
11824 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11825 {
11826 int scroll_p = 0;
11827 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11828
11829 if (PT > XFASTINT (w->last_point))
11830 {
11831 /* Point has moved forward. */
11832 while (MATRIX_ROW_END_CHARPOS (row) < PT
11833 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11834 {
11835 xassert (row->enabled_p);
11836 ++row;
11837 }
11838
11839 /* The end position of a row equals the start position
11840 of the next row. If PT is there, we would rather
11841 display it in the next line. */
11842 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11843 && MATRIX_ROW_END_CHARPOS (row) == PT
11844 && !cursor_row_p (w, row))
11845 ++row;
11846
11847 /* If within the scroll margin, scroll. Note that
11848 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11849 the next line would be drawn, and that
11850 this_scroll_margin can be zero. */
11851 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11852 || PT > MATRIX_ROW_END_CHARPOS (row)
11853 /* Line is completely visible last line in window
11854 and PT is to be set in the next line. */
11855 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11856 && PT == MATRIX_ROW_END_CHARPOS (row)
11857 && !row->ends_at_zv_p
11858 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11859 scroll_p = 1;
11860 }
11861 else if (PT < XFASTINT (w->last_point))
11862 {
11863 /* Cursor has to be moved backward. Note that PT >=
11864 CHARPOS (startp) because of the outer if-statement. */
11865 while (!row->mode_line_p
11866 && (MATRIX_ROW_START_CHARPOS (row) > PT
11867 || (MATRIX_ROW_START_CHARPOS (row) == PT
11868 && (MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)
11869 || (/* STARTS_IN_MIDDLE_OF_STRING_P (row) */
11870 row > w->current_matrix->rows
11871 && (row-1)->ends_in_newline_from_string_p))))
11872 && (row->y > top_scroll_margin
11873 || CHARPOS (startp) == BEGV))
11874 {
11875 xassert (row->enabled_p);
11876 --row;
11877 }
11878
11879 /* Consider the following case: Window starts at BEGV,
11880 there is invisible, intangible text at BEGV, so that
11881 display starts at some point START > BEGV. It can
11882 happen that we are called with PT somewhere between
11883 BEGV and START. Try to handle that case. */
11884 if (row < w->current_matrix->rows
11885 || row->mode_line_p)
11886 {
11887 row = w->current_matrix->rows;
11888 if (row->mode_line_p)
11889 ++row;
11890 }
11891
11892 /* Due to newlines in overlay strings, we may have to
11893 skip forward over overlay strings. */
11894 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11895 && MATRIX_ROW_END_CHARPOS (row) == PT
11896 && !cursor_row_p (w, row))
11897 ++row;
11898
11899 /* If within the scroll margin, scroll. */
11900 if (row->y < top_scroll_margin
11901 && CHARPOS (startp) != BEGV)
11902 scroll_p = 1;
11903 }
11904 else
11905 {
11906 /* Cursor did not move. So don't scroll even if cursor line
11907 is partially visible, as it was so before. */
11908 rc = CURSOR_MOVEMENT_SUCCESS;
11909 }
11910
11911 if (PT < MATRIX_ROW_START_CHARPOS (row)
11912 || PT > MATRIX_ROW_END_CHARPOS (row))
11913 {
11914 /* if PT is not in the glyph row, give up. */
11915 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11916 }
11917 else if (rc != CURSOR_MOVEMENT_SUCCESS
11918 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11919 && make_cursor_line_fully_visible_p)
11920 {
11921 if (PT == MATRIX_ROW_END_CHARPOS (row)
11922 && !row->ends_at_zv_p
11923 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11924 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11925 else if (row->height > window_box_height (w))
11926 {
11927 /* If we end up in a partially visible line, let's
11928 make it fully visible, except when it's taller
11929 than the window, in which case we can't do much
11930 about it. */
11931 *scroll_step = 1;
11932 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11933 }
11934 else
11935 {
11936 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11937 if (!cursor_row_fully_visible_p (w, 0, 1))
11938 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11939 else
11940 rc = CURSOR_MOVEMENT_SUCCESS;
11941 }
11942 }
11943 else if (scroll_p)
11944 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11945 else
11946 {
11947 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11948 rc = CURSOR_MOVEMENT_SUCCESS;
11949 }
11950 }
11951 }
11952
11953 return rc;
11954 }
11955
11956 void
11957 set_vertical_scroll_bar (w)
11958 struct window *w;
11959 {
11960 int start, end, whole;
11961
11962 /* Calculate the start and end positions for the current window.
11963 At some point, it would be nice to choose between scrollbars
11964 which reflect the whole buffer size, with special markers
11965 indicating narrowing, and scrollbars which reflect only the
11966 visible region.
11967
11968 Note that mini-buffers sometimes aren't displaying any text. */
11969 if (!MINI_WINDOW_P (w)
11970 || (w == XWINDOW (minibuf_window)
11971 && NILP (echo_area_buffer[0])))
11972 {
11973 struct buffer *buf = XBUFFER (w->buffer);
11974 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11975 start = marker_position (w->start) - BUF_BEGV (buf);
11976 /* I don't think this is guaranteed to be right. For the
11977 moment, we'll pretend it is. */
11978 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11979
11980 if (end < start)
11981 end = start;
11982 if (whole < (end - start))
11983 whole = end - start;
11984 }
11985 else
11986 start = end = whole = 0;
11987
11988 /* Indicate what this scroll bar ought to be displaying now. */
11989 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11990 }
11991
11992
11993 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11994 selected_window is redisplayed.
11995
11996 We can return without actually redisplaying the window if
11997 fonts_changed_p is nonzero. In that case, redisplay_internal will
11998 retry. */
11999
12000 static void
12001 redisplay_window (window, just_this_one_p)
12002 Lisp_Object window;
12003 int just_this_one_p;
12004 {
12005 struct window *w = XWINDOW (window);
12006 struct frame *f = XFRAME (w->frame);
12007 struct buffer *buffer = XBUFFER (w->buffer);
12008 struct buffer *old = current_buffer;
12009 struct text_pos lpoint, opoint, startp;
12010 int update_mode_line;
12011 int tem;
12012 struct it it;
12013 /* Record it now because it's overwritten. */
12014 int current_matrix_up_to_date_p = 0;
12015 int used_current_matrix_p = 0;
12016 /* This is less strict than current_matrix_up_to_date_p.
12017 It indictes that the buffer contents and narrowing are unchanged. */
12018 int buffer_unchanged_p = 0;
12019 int temp_scroll_step = 0;
12020 int count = SPECPDL_INDEX ();
12021 int rc;
12022 int centering_position = -1;
12023 int last_line_misfit = 0;
12024
12025 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12026 opoint = lpoint;
12027
12028 /* W must be a leaf window here. */
12029 xassert (!NILP (w->buffer));
12030 #if GLYPH_DEBUG
12031 *w->desired_matrix->method = 0;
12032 #endif
12033
12034 specbind (Qinhibit_point_motion_hooks, Qt);
12035
12036 reconsider_clip_changes (w, buffer);
12037
12038 /* Has the mode line to be updated? */
12039 update_mode_line = (!NILP (w->update_mode_line)
12040 || update_mode_lines
12041 || buffer->clip_changed
12042 || buffer->prevent_redisplay_optimizations_p);
12043
12044 if (MINI_WINDOW_P (w))
12045 {
12046 if (w == XWINDOW (echo_area_window)
12047 && !NILP (echo_area_buffer[0]))
12048 {
12049 if (update_mode_line)
12050 /* We may have to update a tty frame's menu bar or a
12051 tool-bar. Example `M-x C-h C-h C-g'. */
12052 goto finish_menu_bars;
12053 else
12054 /* We've already displayed the echo area glyphs in this window. */
12055 goto finish_scroll_bars;
12056 }
12057 else if ((w != XWINDOW (minibuf_window)
12058 || minibuf_level == 0)
12059 /* When buffer is nonempty, redisplay window normally. */
12060 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
12061 /* Quail displays non-mini buffers in minibuffer window.
12062 In that case, redisplay the window normally. */
12063 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
12064 {
12065 /* W is a mini-buffer window, but it's not active, so clear
12066 it. */
12067 int yb = window_text_bottom_y (w);
12068 struct glyph_row *row;
12069 int y;
12070
12071 for (y = 0, row = w->desired_matrix->rows;
12072 y < yb;
12073 y += row->height, ++row)
12074 blank_row (w, row, y);
12075 goto finish_scroll_bars;
12076 }
12077
12078 clear_glyph_matrix (w->desired_matrix);
12079 }
12080
12081 /* Otherwise set up data on this window; select its buffer and point
12082 value. */
12083 /* Really select the buffer, for the sake of buffer-local
12084 variables. */
12085 set_buffer_internal_1 (XBUFFER (w->buffer));
12086 SET_TEXT_POS (opoint, PT, PT_BYTE);
12087
12088 current_matrix_up_to_date_p
12089 = (!NILP (w->window_end_valid)
12090 && !current_buffer->clip_changed
12091 && !current_buffer->prevent_redisplay_optimizations_p
12092 && XFASTINT (w->last_modified) >= MODIFF
12093 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12094
12095 buffer_unchanged_p
12096 = (!NILP (w->window_end_valid)
12097 && !current_buffer->clip_changed
12098 && XFASTINT (w->last_modified) >= MODIFF
12099 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
12100
12101 /* When windows_or_buffers_changed is non-zero, we can't rely on
12102 the window end being valid, so set it to nil there. */
12103 if (windows_or_buffers_changed)
12104 {
12105 /* If window starts on a continuation line, maybe adjust the
12106 window start in case the window's width changed. */
12107 if (XMARKER (w->start)->buffer == current_buffer)
12108 compute_window_start_on_continuation_line (w);
12109
12110 w->window_end_valid = Qnil;
12111 }
12112
12113 /* Some sanity checks. */
12114 CHECK_WINDOW_END (w);
12115 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
12116 abort ();
12117 if (BYTEPOS (opoint) < CHARPOS (opoint))
12118 abort ();
12119
12120 /* If %c is in mode line, update it if needed. */
12121 if (!NILP (w->column_number_displayed)
12122 /* This alternative quickly identifies a common case
12123 where no change is needed. */
12124 && !(PT == XFASTINT (w->last_point)
12125 && XFASTINT (w->last_modified) >= MODIFF
12126 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
12127 && (XFASTINT (w->column_number_displayed)
12128 != (int) current_column ())) /* iftc */
12129 update_mode_line = 1;
12130
12131 /* Count number of windows showing the selected buffer. An indirect
12132 buffer counts as its base buffer. */
12133 if (!just_this_one_p)
12134 {
12135 struct buffer *current_base, *window_base;
12136 current_base = current_buffer;
12137 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
12138 if (current_base->base_buffer)
12139 current_base = current_base->base_buffer;
12140 if (window_base->base_buffer)
12141 window_base = window_base->base_buffer;
12142 if (current_base == window_base)
12143 buffer_shared++;
12144 }
12145
12146 /* Point refers normally to the selected window. For any other
12147 window, set up appropriate value. */
12148 if (!EQ (window, selected_window))
12149 {
12150 int new_pt = XMARKER (w->pointm)->charpos;
12151 int new_pt_byte = marker_byte_position (w->pointm);
12152 if (new_pt < BEGV)
12153 {
12154 new_pt = BEGV;
12155 new_pt_byte = BEGV_BYTE;
12156 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
12157 }
12158 else if (new_pt > (ZV - 1))
12159 {
12160 new_pt = ZV;
12161 new_pt_byte = ZV_BYTE;
12162 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
12163 }
12164
12165 /* We don't use SET_PT so that the point-motion hooks don't run. */
12166 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
12167 }
12168
12169 /* If any of the character widths specified in the display table
12170 have changed, invalidate the width run cache. It's true that
12171 this may be a bit late to catch such changes, but the rest of
12172 redisplay goes (non-fatally) haywire when the display table is
12173 changed, so why should we worry about doing any better? */
12174 if (current_buffer->width_run_cache)
12175 {
12176 struct Lisp_Char_Table *disptab = buffer_display_table ();
12177
12178 if (! disptab_matches_widthtab (disptab,
12179 XVECTOR (current_buffer->width_table)))
12180 {
12181 invalidate_region_cache (current_buffer,
12182 current_buffer->width_run_cache,
12183 BEG, Z);
12184 recompute_width_table (current_buffer, disptab);
12185 }
12186 }
12187
12188 /* If window-start is screwed up, choose a new one. */
12189 if (XMARKER (w->start)->buffer != current_buffer)
12190 goto recenter;
12191
12192 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12193
12194 /* If someone specified a new starting point but did not insist,
12195 check whether it can be used. */
12196 if (!NILP (w->optional_new_start)
12197 && CHARPOS (startp) >= BEGV
12198 && CHARPOS (startp) <= ZV)
12199 {
12200 w->optional_new_start = Qnil;
12201 start_display (&it, w, startp);
12202 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12203 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12204 if (IT_CHARPOS (it) == PT)
12205 w->force_start = Qt;
12206 /* IT may overshoot PT if text at PT is invisible. */
12207 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12208 w->force_start = Qt;
12209
12210
12211 }
12212
12213 /* Handle case where place to start displaying has been specified,
12214 unless the specified location is outside the accessible range. */
12215 if (!NILP (w->force_start)
12216 || w->frozen_window_start_p)
12217 {
12218 /* We set this later on if we have to adjust point. */
12219 int new_vpos = -1;
12220 int val;
12221
12222 w->force_start = Qnil;
12223 w->vscroll = 0;
12224 w->window_end_valid = Qnil;
12225
12226 /* Forget any recorded base line for line number display. */
12227 if (!buffer_unchanged_p)
12228 w->base_line_number = Qnil;
12229
12230 /* Redisplay the mode line. Select the buffer properly for that.
12231 Also, run the hook window-scroll-functions
12232 because we have scrolled. */
12233 /* Note, we do this after clearing force_start because
12234 if there's an error, it is better to forget about force_start
12235 than to get into an infinite loop calling the hook functions
12236 and having them get more errors. */
12237 if (!update_mode_line
12238 || ! NILP (Vwindow_scroll_functions))
12239 {
12240 update_mode_line = 1;
12241 w->update_mode_line = Qt;
12242 startp = run_window_scroll_functions (window, startp);
12243 }
12244
12245 w->last_modified = make_number (0);
12246 w->last_overlay_modified = make_number (0);
12247 if (CHARPOS (startp) < BEGV)
12248 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12249 else if (CHARPOS (startp) > ZV)
12250 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12251
12252 /* Redisplay, then check if cursor has been set during the
12253 redisplay. Give up if new fonts were loaded. */
12254 val = try_window (window, startp, 1);
12255 if (!val)
12256 {
12257 w->force_start = Qt;
12258 clear_glyph_matrix (w->desired_matrix);
12259 goto need_larger_matrices;
12260 }
12261 /* Point was outside the scroll margins. */
12262 if (val < 0)
12263 new_vpos = window_box_height (w) / 2;
12264
12265 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12266 {
12267 /* If point does not appear, try to move point so it does
12268 appear. The desired matrix has been built above, so we
12269 can use it here. */
12270 new_vpos = window_box_height (w) / 2;
12271 }
12272
12273 if (!cursor_row_fully_visible_p (w, 0, 0))
12274 {
12275 /* Point does appear, but on a line partly visible at end of window.
12276 Move it back to a fully-visible line. */
12277 new_vpos = window_box_height (w);
12278 }
12279
12280 /* If we need to move point for either of the above reasons,
12281 now actually do it. */
12282 if (new_vpos >= 0)
12283 {
12284 struct glyph_row *row;
12285
12286 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
12287 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
12288 ++row;
12289
12290 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
12291 MATRIX_ROW_START_BYTEPOS (row));
12292
12293 if (w != XWINDOW (selected_window))
12294 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
12295 else if (current_buffer == old)
12296 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12297
12298 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
12299
12300 /* If we are highlighting the region, then we just changed
12301 the region, so redisplay to show it. */
12302 if (!NILP (Vtransient_mark_mode)
12303 && !NILP (current_buffer->mark_active))
12304 {
12305 clear_glyph_matrix (w->desired_matrix);
12306 if (!try_window (window, startp, 0))
12307 goto need_larger_matrices;
12308 }
12309 }
12310
12311 #if GLYPH_DEBUG
12312 debug_method_add (w, "forced window start");
12313 #endif
12314 goto done;
12315 }
12316
12317 /* Handle case where text has not changed, only point, and it has
12318 not moved off the frame, and we are not retrying after hscroll.
12319 (current_matrix_up_to_date_p is nonzero when retrying.) */
12320 if (current_matrix_up_to_date_p
12321 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
12322 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
12323 {
12324 switch (rc)
12325 {
12326 case CURSOR_MOVEMENT_SUCCESS:
12327 used_current_matrix_p = 1;
12328 goto done;
12329
12330 #if 0 /* try_cursor_movement never returns this value. */
12331 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
12332 goto need_larger_matrices;
12333 #endif
12334
12335 case CURSOR_MOVEMENT_MUST_SCROLL:
12336 goto try_to_scroll;
12337
12338 default:
12339 abort ();
12340 }
12341 }
12342 /* If current starting point was originally the beginning of a line
12343 but no longer is, find a new starting point. */
12344 else if (!NILP (w->start_at_line_beg)
12345 && !(CHARPOS (startp) <= BEGV
12346 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
12347 {
12348 #if GLYPH_DEBUG
12349 debug_method_add (w, "recenter 1");
12350 #endif
12351 goto recenter;
12352 }
12353
12354 /* Try scrolling with try_window_id. Value is > 0 if update has
12355 been done, it is -1 if we know that the same window start will
12356 not work. It is 0 if unsuccessful for some other reason. */
12357 else if ((tem = try_window_id (w)) != 0)
12358 {
12359 #if GLYPH_DEBUG
12360 debug_method_add (w, "try_window_id %d", tem);
12361 #endif
12362
12363 if (fonts_changed_p)
12364 goto need_larger_matrices;
12365 if (tem > 0)
12366 goto done;
12367
12368 /* Otherwise try_window_id has returned -1 which means that we
12369 don't want the alternative below this comment to execute. */
12370 }
12371 else if (CHARPOS (startp) >= BEGV
12372 && CHARPOS (startp) <= ZV
12373 && PT >= CHARPOS (startp)
12374 && (CHARPOS (startp) < ZV
12375 /* Avoid starting at end of buffer. */
12376 || CHARPOS (startp) == BEGV
12377 || (XFASTINT (w->last_modified) >= MODIFF
12378 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12379 {
12380 #if GLYPH_DEBUG
12381 debug_method_add (w, "same window start");
12382 #endif
12383
12384 /* Try to redisplay starting at same place as before.
12385 If point has not moved off frame, accept the results. */
12386 if (!current_matrix_up_to_date_p
12387 /* Don't use try_window_reusing_current_matrix in this case
12388 because a window scroll function can have changed the
12389 buffer. */
12390 || !NILP (Vwindow_scroll_functions)
12391 || MINI_WINDOW_P (w)
12392 || !(used_current_matrix_p
12393 = try_window_reusing_current_matrix (w)))
12394 {
12395 IF_DEBUG (debug_method_add (w, "1"));
12396 if (try_window (window, startp, 1) < 0)
12397 /* -1 means we need to scroll.
12398 0 means we need new matrices, but fonts_changed_p
12399 is set in that case, so we will detect it below. */
12400 goto try_to_scroll;
12401 }
12402
12403 if (fonts_changed_p)
12404 goto need_larger_matrices;
12405
12406 if (w->cursor.vpos >= 0)
12407 {
12408 if (!just_this_one_p
12409 || current_buffer->clip_changed
12410 || BEG_UNCHANGED < CHARPOS (startp))
12411 /* Forget any recorded base line for line number display. */
12412 w->base_line_number = Qnil;
12413
12414 if (!cursor_row_fully_visible_p (w, 1, 0))
12415 {
12416 clear_glyph_matrix (w->desired_matrix);
12417 last_line_misfit = 1;
12418 }
12419 /* Drop through and scroll. */
12420 else
12421 goto done;
12422 }
12423 else
12424 clear_glyph_matrix (w->desired_matrix);
12425 }
12426
12427 try_to_scroll:
12428
12429 w->last_modified = make_number (0);
12430 w->last_overlay_modified = make_number (0);
12431
12432 /* Redisplay the mode line. Select the buffer properly for that. */
12433 if (!update_mode_line)
12434 {
12435 update_mode_line = 1;
12436 w->update_mode_line = Qt;
12437 }
12438
12439 /* Try to scroll by specified few lines. */
12440 if ((scroll_conservatively
12441 || scroll_step
12442 || temp_scroll_step
12443 || NUMBERP (current_buffer->scroll_up_aggressively)
12444 || NUMBERP (current_buffer->scroll_down_aggressively))
12445 && !current_buffer->clip_changed
12446 && CHARPOS (startp) >= BEGV
12447 && CHARPOS (startp) <= ZV)
12448 {
12449 /* The function returns -1 if new fonts were loaded, 1 if
12450 successful, 0 if not successful. */
12451 int rc = try_scrolling (window, just_this_one_p,
12452 scroll_conservatively,
12453 scroll_step,
12454 temp_scroll_step, last_line_misfit);
12455 switch (rc)
12456 {
12457 case SCROLLING_SUCCESS:
12458 goto done;
12459
12460 case SCROLLING_NEED_LARGER_MATRICES:
12461 goto need_larger_matrices;
12462
12463 case SCROLLING_FAILED:
12464 break;
12465
12466 default:
12467 abort ();
12468 }
12469 }
12470
12471 /* Finally, just choose place to start which centers point */
12472
12473 recenter:
12474 if (centering_position < 0)
12475 centering_position = window_box_height (w) / 2;
12476
12477 #if GLYPH_DEBUG
12478 debug_method_add (w, "recenter");
12479 #endif
12480
12481 /* w->vscroll = 0; */
12482
12483 /* Forget any previously recorded base line for line number display. */
12484 if (!buffer_unchanged_p)
12485 w->base_line_number = Qnil;
12486
12487 /* Move backward half the height of the window. */
12488 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12489 it.current_y = it.last_visible_y;
12490 move_it_vertically_backward (&it, centering_position);
12491 xassert (IT_CHARPOS (it) >= BEGV);
12492
12493 /* The function move_it_vertically_backward may move over more
12494 than the specified y-distance. If it->w is small, e.g. a
12495 mini-buffer window, we may end up in front of the window's
12496 display area. Start displaying at the start of the line
12497 containing PT in this case. */
12498 if (it.current_y <= 0)
12499 {
12500 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12501 move_it_vertically_backward (&it, 0);
12502 #if 0
12503 /* I think this assert is bogus if buffer contains
12504 invisible text or images. KFS. */
12505 xassert (IT_CHARPOS (it) <= PT);
12506 #endif
12507 it.current_y = 0;
12508 }
12509
12510 it.current_x = it.hpos = 0;
12511
12512 /* Set startp here explicitly in case that helps avoid an infinite loop
12513 in case the window-scroll-functions functions get errors. */
12514 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12515
12516 /* Run scroll hooks. */
12517 startp = run_window_scroll_functions (window, it.current.pos);
12518
12519 /* Redisplay the window. */
12520 if (!current_matrix_up_to_date_p
12521 || windows_or_buffers_changed
12522 || cursor_type_changed
12523 /* Don't use try_window_reusing_current_matrix in this case
12524 because it can have changed the buffer. */
12525 || !NILP (Vwindow_scroll_functions)
12526 || !just_this_one_p
12527 || MINI_WINDOW_P (w)
12528 || !(used_current_matrix_p
12529 = try_window_reusing_current_matrix (w)))
12530 try_window (window, startp, 0);
12531
12532 /* If new fonts have been loaded (due to fontsets), give up. We
12533 have to start a new redisplay since we need to re-adjust glyph
12534 matrices. */
12535 if (fonts_changed_p)
12536 goto need_larger_matrices;
12537
12538 /* If cursor did not appear assume that the middle of the window is
12539 in the first line of the window. Do it again with the next line.
12540 (Imagine a window of height 100, displaying two lines of height
12541 60. Moving back 50 from it->last_visible_y will end in the first
12542 line.) */
12543 if (w->cursor.vpos < 0)
12544 {
12545 if (!NILP (w->window_end_valid)
12546 && PT >= Z - XFASTINT (w->window_end_pos))
12547 {
12548 clear_glyph_matrix (w->desired_matrix);
12549 move_it_by_lines (&it, 1, 0);
12550 try_window (window, it.current.pos, 0);
12551 }
12552 else if (PT < IT_CHARPOS (it))
12553 {
12554 clear_glyph_matrix (w->desired_matrix);
12555 move_it_by_lines (&it, -1, 0);
12556 try_window (window, it.current.pos, 0);
12557 }
12558 else
12559 {
12560 /* Not much we can do about it. */
12561 }
12562 }
12563
12564 /* Consider the following case: Window starts at BEGV, there is
12565 invisible, intangible text at BEGV, so that display starts at
12566 some point START > BEGV. It can happen that we are called with
12567 PT somewhere between BEGV and START. Try to handle that case. */
12568 if (w->cursor.vpos < 0)
12569 {
12570 struct glyph_row *row = w->current_matrix->rows;
12571 if (row->mode_line_p)
12572 ++row;
12573 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12574 }
12575
12576 if (!cursor_row_fully_visible_p (w, 0, 0))
12577 {
12578 /* If vscroll is enabled, disable it and try again. */
12579 if (w->vscroll)
12580 {
12581 w->vscroll = 0;
12582 clear_glyph_matrix (w->desired_matrix);
12583 goto recenter;
12584 }
12585
12586 /* If centering point failed to make the whole line visible,
12587 put point at the top instead. That has to make the whole line
12588 visible, if it can be done. */
12589 if (centering_position == 0)
12590 goto done;
12591
12592 clear_glyph_matrix (w->desired_matrix);
12593 centering_position = 0;
12594 goto recenter;
12595 }
12596
12597 done:
12598
12599 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12600 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12601 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12602 ? Qt : Qnil);
12603
12604 /* Display the mode line, if we must. */
12605 if ((update_mode_line
12606 /* If window not full width, must redo its mode line
12607 if (a) the window to its side is being redone and
12608 (b) we do a frame-based redisplay. This is a consequence
12609 of how inverted lines are drawn in frame-based redisplay. */
12610 || (!just_this_one_p
12611 && !FRAME_WINDOW_P (f)
12612 && !WINDOW_FULL_WIDTH_P (w))
12613 /* Line number to display. */
12614 || INTEGERP (w->base_line_pos)
12615 /* Column number is displayed and different from the one displayed. */
12616 || (!NILP (w->column_number_displayed)
12617 && (XFASTINT (w->column_number_displayed)
12618 != (int) current_column ()))) /* iftc */
12619 /* This means that the window has a mode line. */
12620 && (WINDOW_WANTS_MODELINE_P (w)
12621 || WINDOW_WANTS_HEADER_LINE_P (w)))
12622 {
12623 display_mode_lines (w);
12624
12625 /* If mode line height has changed, arrange for a thorough
12626 immediate redisplay using the correct mode line height. */
12627 if (WINDOW_WANTS_MODELINE_P (w)
12628 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12629 {
12630 fonts_changed_p = 1;
12631 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12632 = DESIRED_MODE_LINE_HEIGHT (w);
12633 }
12634
12635 /* If top line height has changed, arrange for a thorough
12636 immediate redisplay using the correct mode line height. */
12637 if (WINDOW_WANTS_HEADER_LINE_P (w)
12638 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12639 {
12640 fonts_changed_p = 1;
12641 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12642 = DESIRED_HEADER_LINE_HEIGHT (w);
12643 }
12644
12645 if (fonts_changed_p)
12646 goto need_larger_matrices;
12647 }
12648
12649 if (!line_number_displayed
12650 && !BUFFERP (w->base_line_pos))
12651 {
12652 w->base_line_pos = Qnil;
12653 w->base_line_number = Qnil;
12654 }
12655
12656 finish_menu_bars:
12657
12658 /* When we reach a frame's selected window, redo the frame's menu bar. */
12659 if (update_mode_line
12660 && EQ (FRAME_SELECTED_WINDOW (f), window))
12661 {
12662 int redisplay_menu_p = 0;
12663 int redisplay_tool_bar_p = 0;
12664
12665 if (FRAME_WINDOW_P (f))
12666 {
12667 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12668 || defined (USE_GTK)
12669 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12670 #else
12671 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12672 #endif
12673 }
12674 else
12675 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12676
12677 if (redisplay_menu_p)
12678 display_menu_bar (w);
12679
12680 #ifdef HAVE_WINDOW_SYSTEM
12681 #ifdef USE_GTK
12682 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12683 #else
12684 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12685 && (FRAME_TOOL_BAR_LINES (f) > 0
12686 || auto_resize_tool_bars_p);
12687
12688 #endif
12689
12690 if (redisplay_tool_bar_p)
12691 redisplay_tool_bar (f);
12692 #endif
12693 }
12694
12695 #ifdef HAVE_WINDOW_SYSTEM
12696 if (FRAME_WINDOW_P (f)
12697 && update_window_fringes (w, 0)
12698 && !just_this_one_p
12699 && (used_current_matrix_p || overlay_arrow_seen)
12700 && !w->pseudo_window_p)
12701 {
12702 update_begin (f);
12703 BLOCK_INPUT;
12704 if (draw_window_fringes (w, 1))
12705 x_draw_vertical_border (w);
12706 UNBLOCK_INPUT;
12707 update_end (f);
12708 }
12709 #endif /* HAVE_WINDOW_SYSTEM */
12710
12711 /* We go to this label, with fonts_changed_p nonzero,
12712 if it is necessary to try again using larger glyph matrices.
12713 We have to redeem the scroll bar even in this case,
12714 because the loop in redisplay_internal expects that. */
12715 need_larger_matrices:
12716 ;
12717 finish_scroll_bars:
12718
12719 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12720 {
12721 /* Set the thumb's position and size. */
12722 set_vertical_scroll_bar (w);
12723
12724 /* Note that we actually used the scroll bar attached to this
12725 window, so it shouldn't be deleted at the end of redisplay. */
12726 redeem_scroll_bar_hook (w);
12727 }
12728
12729 /* Restore current_buffer and value of point in it. */
12730 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12731 set_buffer_internal_1 (old);
12732 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12733
12734 unbind_to (count, Qnil);
12735 }
12736
12737
12738 /* Build the complete desired matrix of WINDOW with a window start
12739 buffer position POS.
12740
12741 Value is 1 if successful. It is zero if fonts were loaded during
12742 redisplay which makes re-adjusting glyph matrices necessary, and -1
12743 if point would appear in the scroll margins.
12744 (We check that only if CHECK_MARGINS is nonzero. */
12745
12746 int
12747 try_window (window, pos, check_margins)
12748 Lisp_Object window;
12749 struct text_pos pos;
12750 int check_margins;
12751 {
12752 struct window *w = XWINDOW (window);
12753 struct it it;
12754 struct glyph_row *last_text_row = NULL;
12755
12756 /* Make POS the new window start. */
12757 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12758
12759 /* Mark cursor position as unknown. No overlay arrow seen. */
12760 w->cursor.vpos = -1;
12761 overlay_arrow_seen = 0;
12762
12763 /* Initialize iterator and info to start at POS. */
12764 start_display (&it, w, pos);
12765
12766 /* Display all lines of W. */
12767 while (it.current_y < it.last_visible_y)
12768 {
12769 if (display_line (&it))
12770 last_text_row = it.glyph_row - 1;
12771 if (fonts_changed_p)
12772 return 0;
12773 }
12774
12775 /* Don't let the cursor end in the scroll margins. */
12776 if (check_margins
12777 && !MINI_WINDOW_P (w))
12778 {
12779 int this_scroll_margin, cursor_height;
12780
12781 this_scroll_margin = max (0, scroll_margin);
12782 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
12783 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
12784 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
12785
12786 if ((w->cursor.y < this_scroll_margin
12787 && CHARPOS (pos) > BEGV)
12788 /* rms: considering make_cursor_line_fully_visible_p here
12789 seems to give wrong results. We don't want to recenter
12790 when the last line is partly visible, we want to allow
12791 that case to be handled in the usual way. */
12792 || (w->cursor.y + 1) > it.last_visible_y)
12793 {
12794 w->cursor.vpos = -1;
12795 clear_glyph_matrix (w->desired_matrix);
12796 return -1;
12797 }
12798 }
12799
12800 /* If bottom moved off end of frame, change mode line percentage. */
12801 if (XFASTINT (w->window_end_pos) <= 0
12802 && Z != IT_CHARPOS (it))
12803 w->update_mode_line = Qt;
12804
12805 /* Set window_end_pos to the offset of the last character displayed
12806 on the window from the end of current_buffer. Set
12807 window_end_vpos to its row number. */
12808 if (last_text_row)
12809 {
12810 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12811 w->window_end_bytepos
12812 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12813 w->window_end_pos
12814 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12815 w->window_end_vpos
12816 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12817 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12818 ->displays_text_p);
12819 }
12820 else
12821 {
12822 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12823 w->window_end_pos = make_number (Z - ZV);
12824 w->window_end_vpos = make_number (0);
12825 }
12826
12827 /* But that is not valid info until redisplay finishes. */
12828 w->window_end_valid = Qnil;
12829 return 1;
12830 }
12831
12832
12833 \f
12834 /************************************************************************
12835 Window redisplay reusing current matrix when buffer has not changed
12836 ************************************************************************/
12837
12838 /* Try redisplay of window W showing an unchanged buffer with a
12839 different window start than the last time it was displayed by
12840 reusing its current matrix. Value is non-zero if successful.
12841 W->start is the new window start. */
12842
12843 static int
12844 try_window_reusing_current_matrix (w)
12845 struct window *w;
12846 {
12847 struct frame *f = XFRAME (w->frame);
12848 struct glyph_row *row, *bottom_row;
12849 struct it it;
12850 struct run run;
12851 struct text_pos start, new_start;
12852 int nrows_scrolled, i;
12853 struct glyph_row *last_text_row;
12854 struct glyph_row *last_reused_text_row;
12855 struct glyph_row *start_row;
12856 int start_vpos, min_y, max_y;
12857
12858 #if GLYPH_DEBUG
12859 if (inhibit_try_window_reusing)
12860 return 0;
12861 #endif
12862
12863 if (/* This function doesn't handle terminal frames. */
12864 !FRAME_WINDOW_P (f)
12865 /* Don't try to reuse the display if windows have been split
12866 or such. */
12867 || windows_or_buffers_changed
12868 || cursor_type_changed)
12869 return 0;
12870
12871 /* Can't do this if region may have changed. */
12872 if ((!NILP (Vtransient_mark_mode)
12873 && !NILP (current_buffer->mark_active))
12874 || !NILP (w->region_showing)
12875 || !NILP (Vshow_trailing_whitespace))
12876 return 0;
12877
12878 /* If top-line visibility has changed, give up. */
12879 if (WINDOW_WANTS_HEADER_LINE_P (w)
12880 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12881 return 0;
12882
12883 /* Give up if old or new display is scrolled vertically. We could
12884 make this function handle this, but right now it doesn't. */
12885 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12886 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12887 return 0;
12888
12889 /* The variable new_start now holds the new window start. The old
12890 start `start' can be determined from the current matrix. */
12891 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12892 start = start_row->start.pos;
12893 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12894
12895 /* Clear the desired matrix for the display below. */
12896 clear_glyph_matrix (w->desired_matrix);
12897
12898 if (CHARPOS (new_start) <= CHARPOS (start))
12899 {
12900 int first_row_y;
12901
12902 /* Don't use this method if the display starts with an ellipsis
12903 displayed for invisible text. It's not easy to handle that case
12904 below, and it's certainly not worth the effort since this is
12905 not a frequent case. */
12906 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12907 return 0;
12908
12909 IF_DEBUG (debug_method_add (w, "twu1"));
12910
12911 /* Display up to a row that can be reused. The variable
12912 last_text_row is set to the last row displayed that displays
12913 text. Note that it.vpos == 0 if or if not there is a
12914 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12915 start_display (&it, w, new_start);
12916 first_row_y = it.current_y;
12917 w->cursor.vpos = -1;
12918 last_text_row = last_reused_text_row = NULL;
12919
12920 while (it.current_y < it.last_visible_y
12921 && !fonts_changed_p)
12922 {
12923 /* If we have reached into the characters in the START row,
12924 that means the line boundaries have changed. So we
12925 can't start copying with the row START. Maybe it will
12926 work to start copying with the following row. */
12927 while (IT_CHARPOS (it) > CHARPOS (start))
12928 {
12929 /* Advance to the next row as the "start". */
12930 start_row++;
12931 start = start_row->start.pos;
12932 /* If there are no more rows to try, or just one, give up. */
12933 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12934 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12935 || CHARPOS (start) == ZV)
12936 {
12937 clear_glyph_matrix (w->desired_matrix);
12938 return 0;
12939 }
12940
12941 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12942 }
12943 /* If we have reached alignment,
12944 we can copy the rest of the rows. */
12945 if (IT_CHARPOS (it) == CHARPOS (start))
12946 break;
12947
12948 if (display_line (&it))
12949 last_text_row = it.glyph_row - 1;
12950 }
12951
12952 /* A value of current_y < last_visible_y means that we stopped
12953 at the previous window start, which in turn means that we
12954 have at least one reusable row. */
12955 if (it.current_y < it.last_visible_y)
12956 {
12957 /* IT.vpos always starts from 0; it counts text lines. */
12958 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12959
12960 /* Find PT if not already found in the lines displayed. */
12961 if (w->cursor.vpos < 0)
12962 {
12963 int dy = it.current_y - start_row->y;
12964
12965 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12966 row = row_containing_pos (w, PT, row, NULL, dy);
12967 if (row)
12968 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12969 dy, nrows_scrolled);
12970 else
12971 {
12972 clear_glyph_matrix (w->desired_matrix);
12973 return 0;
12974 }
12975 }
12976
12977 /* Scroll the display. Do it before the current matrix is
12978 changed. The problem here is that update has not yet
12979 run, i.e. part of the current matrix is not up to date.
12980 scroll_run_hook will clear the cursor, and use the
12981 current matrix to get the height of the row the cursor is
12982 in. */
12983 run.current_y = start_row->y;
12984 run.desired_y = it.current_y;
12985 run.height = it.last_visible_y - it.current_y;
12986
12987 if (run.height > 0 && run.current_y != run.desired_y)
12988 {
12989 update_begin (f);
12990 rif->update_window_begin_hook (w);
12991 rif->clear_window_mouse_face (w);
12992 rif->scroll_run_hook (w, &run);
12993 rif->update_window_end_hook (w, 0, 0);
12994 update_end (f);
12995 }
12996
12997 /* Shift current matrix down by nrows_scrolled lines. */
12998 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12999 rotate_matrix (w->current_matrix,
13000 start_vpos,
13001 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13002 nrows_scrolled);
13003
13004 /* Disable lines that must be updated. */
13005 for (i = 0; i < it.vpos; ++i)
13006 (start_row + i)->enabled_p = 0;
13007
13008 /* Re-compute Y positions. */
13009 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13010 max_y = it.last_visible_y;
13011 for (row = start_row + nrows_scrolled;
13012 row < bottom_row;
13013 ++row)
13014 {
13015 row->y = it.current_y;
13016 row->visible_height = row->height;
13017
13018 if (row->y < min_y)
13019 row->visible_height -= min_y - row->y;
13020 if (row->y + row->height > max_y)
13021 row->visible_height -= row->y + row->height - max_y;
13022 row->redraw_fringe_bitmaps_p = 1;
13023
13024 it.current_y += row->height;
13025
13026 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13027 last_reused_text_row = row;
13028 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
13029 break;
13030 }
13031
13032 /* Disable lines in the current matrix which are now
13033 below the window. */
13034 for (++row; row < bottom_row; ++row)
13035 row->enabled_p = 0;
13036 }
13037
13038 /* Update window_end_pos etc.; last_reused_text_row is the last
13039 reused row from the current matrix containing text, if any.
13040 The value of last_text_row is the last displayed line
13041 containing text. */
13042 if (last_reused_text_row)
13043 {
13044 w->window_end_bytepos
13045 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
13046 w->window_end_pos
13047 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
13048 w->window_end_vpos
13049 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
13050 w->current_matrix));
13051 }
13052 else if (last_text_row)
13053 {
13054 w->window_end_bytepos
13055 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13056 w->window_end_pos
13057 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13058 w->window_end_vpos
13059 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13060 }
13061 else
13062 {
13063 /* This window must be completely empty. */
13064 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
13065 w->window_end_pos = make_number (Z - ZV);
13066 w->window_end_vpos = make_number (0);
13067 }
13068 w->window_end_valid = Qnil;
13069
13070 /* Update hint: don't try scrolling again in update_window. */
13071 w->desired_matrix->no_scrolling_p = 1;
13072
13073 #if GLYPH_DEBUG
13074 debug_method_add (w, "try_window_reusing_current_matrix 1");
13075 #endif
13076 return 1;
13077 }
13078 else if (CHARPOS (new_start) > CHARPOS (start))
13079 {
13080 struct glyph_row *pt_row, *row;
13081 struct glyph_row *first_reusable_row;
13082 struct glyph_row *first_row_to_display;
13083 int dy;
13084 int yb = window_text_bottom_y (w);
13085
13086 /* Find the row starting at new_start, if there is one. Don't
13087 reuse a partially visible line at the end. */
13088 first_reusable_row = start_row;
13089 while (first_reusable_row->enabled_p
13090 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
13091 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13092 < CHARPOS (new_start)))
13093 ++first_reusable_row;
13094
13095 /* Give up if there is no row to reuse. */
13096 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
13097 || !first_reusable_row->enabled_p
13098 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
13099 != CHARPOS (new_start)))
13100 return 0;
13101
13102 /* We can reuse fully visible rows beginning with
13103 first_reusable_row to the end of the window. Set
13104 first_row_to_display to the first row that cannot be reused.
13105 Set pt_row to the row containing point, if there is any. */
13106 pt_row = NULL;
13107 for (first_row_to_display = first_reusable_row;
13108 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
13109 ++first_row_to_display)
13110 {
13111 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
13112 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
13113 pt_row = first_row_to_display;
13114 }
13115
13116 /* Start displaying at the start of first_row_to_display. */
13117 xassert (first_row_to_display->y < yb);
13118 init_to_row_start (&it, w, first_row_to_display);
13119
13120 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
13121 - start_vpos);
13122 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
13123 - nrows_scrolled);
13124 it.current_y = (first_row_to_display->y - first_reusable_row->y
13125 + WINDOW_HEADER_LINE_HEIGHT (w));
13126
13127 /* Display lines beginning with first_row_to_display in the
13128 desired matrix. Set last_text_row to the last row displayed
13129 that displays text. */
13130 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
13131 if (pt_row == NULL)
13132 w->cursor.vpos = -1;
13133 last_text_row = NULL;
13134 while (it.current_y < it.last_visible_y && !fonts_changed_p)
13135 if (display_line (&it))
13136 last_text_row = it.glyph_row - 1;
13137
13138 /* Give up If point isn't in a row displayed or reused. */
13139 if (w->cursor.vpos < 0)
13140 {
13141 clear_glyph_matrix (w->desired_matrix);
13142 return 0;
13143 }
13144
13145 /* If point is in a reused row, adjust y and vpos of the cursor
13146 position. */
13147 if (pt_row)
13148 {
13149 w->cursor.vpos -= nrows_scrolled;
13150 w->cursor.y -= first_reusable_row->y - start_row->y;
13151 }
13152
13153 /* Scroll the display. */
13154 run.current_y = first_reusable_row->y;
13155 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
13156 run.height = it.last_visible_y - run.current_y;
13157 dy = run.current_y - run.desired_y;
13158
13159 if (run.height)
13160 {
13161 update_begin (f);
13162 rif->update_window_begin_hook (w);
13163 rif->clear_window_mouse_face (w);
13164 rif->scroll_run_hook (w, &run);
13165 rif->update_window_end_hook (w, 0, 0);
13166 update_end (f);
13167 }
13168
13169 /* Adjust Y positions of reused rows. */
13170 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
13171 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
13172 max_y = it.last_visible_y;
13173 for (row = first_reusable_row; row < first_row_to_display; ++row)
13174 {
13175 row->y -= dy;
13176 row->visible_height = row->height;
13177 if (row->y < min_y)
13178 row->visible_height -= min_y - row->y;
13179 if (row->y + row->height > max_y)
13180 row->visible_height -= row->y + row->height - max_y;
13181 row->redraw_fringe_bitmaps_p = 1;
13182 }
13183
13184 /* Scroll the current matrix. */
13185 xassert (nrows_scrolled > 0);
13186 rotate_matrix (w->current_matrix,
13187 start_vpos,
13188 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
13189 -nrows_scrolled);
13190
13191 /* Disable rows not reused. */
13192 for (row -= nrows_scrolled; row < bottom_row; ++row)
13193 row->enabled_p = 0;
13194
13195 /* Point may have moved to a different line, so we cannot assume that
13196 the previous cursor position is valid; locate the correct row. */
13197 if (pt_row)
13198 {
13199 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
13200 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
13201 row++)
13202 {
13203 w->cursor.vpos++;
13204 w->cursor.y = row->y;
13205 }
13206 if (row < bottom_row)
13207 {
13208 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
13209 while (glyph->charpos < PT)
13210 {
13211 w->cursor.hpos++;
13212 w->cursor.x += glyph->pixel_width;
13213 glyph++;
13214 }
13215 }
13216 }
13217
13218 /* Adjust window end. A null value of last_text_row means that
13219 the window end is in reused rows which in turn means that
13220 only its vpos can have changed. */
13221 if (last_text_row)
13222 {
13223 w->window_end_bytepos
13224 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13225 w->window_end_pos
13226 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13227 w->window_end_vpos
13228 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
13229 }
13230 else
13231 {
13232 w->window_end_vpos
13233 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
13234 }
13235
13236 w->window_end_valid = Qnil;
13237 w->desired_matrix->no_scrolling_p = 1;
13238
13239 #if GLYPH_DEBUG
13240 debug_method_add (w, "try_window_reusing_current_matrix 2");
13241 #endif
13242 return 1;
13243 }
13244
13245 return 0;
13246 }
13247
13248
13249 \f
13250 /************************************************************************
13251 Window redisplay reusing current matrix when buffer has changed
13252 ************************************************************************/
13253
13254 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
13255 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
13256 int *, int *));
13257 static struct glyph_row *
13258 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
13259 struct glyph_row *));
13260
13261
13262 /* Return the last row in MATRIX displaying text. If row START is
13263 non-null, start searching with that row. IT gives the dimensions
13264 of the display. Value is null if matrix is empty; otherwise it is
13265 a pointer to the row found. */
13266
13267 static struct glyph_row *
13268 find_last_row_displaying_text (matrix, it, start)
13269 struct glyph_matrix *matrix;
13270 struct it *it;
13271 struct glyph_row *start;
13272 {
13273 struct glyph_row *row, *row_found;
13274
13275 /* Set row_found to the last row in IT->w's current matrix
13276 displaying text. The loop looks funny but think of partially
13277 visible lines. */
13278 row_found = NULL;
13279 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
13280 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13281 {
13282 xassert (row->enabled_p);
13283 row_found = row;
13284 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
13285 break;
13286 ++row;
13287 }
13288
13289 return row_found;
13290 }
13291
13292
13293 /* Return the last row in the current matrix of W that is not affected
13294 by changes at the start of current_buffer that occurred since W's
13295 current matrix was built. Value is null if no such row exists.
13296
13297 BEG_UNCHANGED us the number of characters unchanged at the start of
13298 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13299 first changed character in current_buffer. Characters at positions <
13300 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13301 when the current matrix was built. */
13302
13303 static struct glyph_row *
13304 find_last_unchanged_at_beg_row (w)
13305 struct window *w;
13306 {
13307 int first_changed_pos = BEG + BEG_UNCHANGED;
13308 struct glyph_row *row;
13309 struct glyph_row *row_found = NULL;
13310 int yb = window_text_bottom_y (w);
13311
13312 /* Find the last row displaying unchanged text. */
13313 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13314 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13315 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
13316 {
13317 if (/* If row ends before first_changed_pos, it is unchanged,
13318 except in some case. */
13319 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
13320 /* When row ends in ZV and we write at ZV it is not
13321 unchanged. */
13322 && !row->ends_at_zv_p
13323 /* When first_changed_pos is the end of a continued line,
13324 row is not unchanged because it may be no longer
13325 continued. */
13326 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
13327 && (row->continued_p
13328 || row->exact_window_width_line_p)))
13329 row_found = row;
13330
13331 /* Stop if last visible row. */
13332 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
13333 break;
13334
13335 ++row;
13336 }
13337
13338 return row_found;
13339 }
13340
13341
13342 /* Find the first glyph row in the current matrix of W that is not
13343 affected by changes at the end of current_buffer since the
13344 time W's current matrix was built.
13345
13346 Return in *DELTA the number of chars by which buffer positions in
13347 unchanged text at the end of current_buffer must be adjusted.
13348
13349 Return in *DELTA_BYTES the corresponding number of bytes.
13350
13351 Value is null if no such row exists, i.e. all rows are affected by
13352 changes. */
13353
13354 static struct glyph_row *
13355 find_first_unchanged_at_end_row (w, delta, delta_bytes)
13356 struct window *w;
13357 int *delta, *delta_bytes;
13358 {
13359 struct glyph_row *row;
13360 struct glyph_row *row_found = NULL;
13361
13362 *delta = *delta_bytes = 0;
13363
13364 /* Display must not have been paused, otherwise the current matrix
13365 is not up to date. */
13366 if (NILP (w->window_end_valid))
13367 abort ();
13368
13369 /* A value of window_end_pos >= END_UNCHANGED means that the window
13370 end is in the range of changed text. If so, there is no
13371 unchanged row at the end of W's current matrix. */
13372 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
13373 return NULL;
13374
13375 /* Set row to the last row in W's current matrix displaying text. */
13376 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13377
13378 /* If matrix is entirely empty, no unchanged row exists. */
13379 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13380 {
13381 /* The value of row is the last glyph row in the matrix having a
13382 meaningful buffer position in it. The end position of row
13383 corresponds to window_end_pos. This allows us to translate
13384 buffer positions in the current matrix to current buffer
13385 positions for characters not in changed text. */
13386 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13387 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13388 int last_unchanged_pos, last_unchanged_pos_old;
13389 struct glyph_row *first_text_row
13390 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13391
13392 *delta = Z - Z_old;
13393 *delta_bytes = Z_BYTE - Z_BYTE_old;
13394
13395 /* Set last_unchanged_pos to the buffer position of the last
13396 character in the buffer that has not been changed. Z is the
13397 index + 1 of the last character in current_buffer, i.e. by
13398 subtracting END_UNCHANGED we get the index of the last
13399 unchanged character, and we have to add BEG to get its buffer
13400 position. */
13401 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13402 last_unchanged_pos_old = last_unchanged_pos - *delta;
13403
13404 /* Search backward from ROW for a row displaying a line that
13405 starts at a minimum position >= last_unchanged_pos_old. */
13406 for (; row > first_text_row; --row)
13407 {
13408 /* This used to abort, but it can happen.
13409 It is ok to just stop the search instead here. KFS. */
13410 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13411 break;
13412
13413 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13414 row_found = row;
13415 }
13416 }
13417
13418 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13419 abort ();
13420
13421 return row_found;
13422 }
13423
13424
13425 /* Make sure that glyph rows in the current matrix of window W
13426 reference the same glyph memory as corresponding rows in the
13427 frame's frame matrix. This function is called after scrolling W's
13428 current matrix on a terminal frame in try_window_id and
13429 try_window_reusing_current_matrix. */
13430
13431 static void
13432 sync_frame_with_window_matrix_rows (w)
13433 struct window *w;
13434 {
13435 struct frame *f = XFRAME (w->frame);
13436 struct glyph_row *window_row, *window_row_end, *frame_row;
13437
13438 /* Preconditions: W must be a leaf window and full-width. Its frame
13439 must have a frame matrix. */
13440 xassert (NILP (w->hchild) && NILP (w->vchild));
13441 xassert (WINDOW_FULL_WIDTH_P (w));
13442 xassert (!FRAME_WINDOW_P (f));
13443
13444 /* If W is a full-width window, glyph pointers in W's current matrix
13445 have, by definition, to be the same as glyph pointers in the
13446 corresponding frame matrix. Note that frame matrices have no
13447 marginal areas (see build_frame_matrix). */
13448 window_row = w->current_matrix->rows;
13449 window_row_end = window_row + w->current_matrix->nrows;
13450 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13451 while (window_row < window_row_end)
13452 {
13453 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13454 struct glyph *end = window_row->glyphs[LAST_AREA];
13455
13456 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13457 frame_row->glyphs[TEXT_AREA] = start;
13458 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13459 frame_row->glyphs[LAST_AREA] = end;
13460
13461 /* Disable frame rows whose corresponding window rows have
13462 been disabled in try_window_id. */
13463 if (!window_row->enabled_p)
13464 frame_row->enabled_p = 0;
13465
13466 ++window_row, ++frame_row;
13467 }
13468 }
13469
13470
13471 /* Find the glyph row in window W containing CHARPOS. Consider all
13472 rows between START and END (not inclusive). END null means search
13473 all rows to the end of the display area of W. Value is the row
13474 containing CHARPOS or null. */
13475
13476 struct glyph_row *
13477 row_containing_pos (w, charpos, start, end, dy)
13478 struct window *w;
13479 int charpos;
13480 struct glyph_row *start, *end;
13481 int dy;
13482 {
13483 struct glyph_row *row = start;
13484 int last_y;
13485
13486 /* If we happen to start on a header-line, skip that. */
13487 if (row->mode_line_p)
13488 ++row;
13489
13490 if ((end && row >= end) || !row->enabled_p)
13491 return NULL;
13492
13493 last_y = window_text_bottom_y (w) - dy;
13494
13495 while (1)
13496 {
13497 /* Give up if we have gone too far. */
13498 if (end && row >= end)
13499 return NULL;
13500 /* This formerly returned if they were equal.
13501 I think that both quantities are of a "last plus one" type;
13502 if so, when they are equal, the row is within the screen. -- rms. */
13503 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13504 return NULL;
13505
13506 /* If it is in this row, return this row. */
13507 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13508 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13509 /* The end position of a row equals the start
13510 position of the next row. If CHARPOS is there, we
13511 would rather display it in the next line, except
13512 when this line ends in ZV. */
13513 && !row->ends_at_zv_p
13514 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13515 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13516 return row;
13517 ++row;
13518 }
13519 }
13520
13521
13522 /* Try to redisplay window W by reusing its existing display. W's
13523 current matrix must be up to date when this function is called,
13524 i.e. window_end_valid must not be nil.
13525
13526 Value is
13527
13528 1 if display has been updated
13529 0 if otherwise unsuccessful
13530 -1 if redisplay with same window start is known not to succeed
13531
13532 The following steps are performed:
13533
13534 1. Find the last row in the current matrix of W that is not
13535 affected by changes at the start of current_buffer. If no such row
13536 is found, give up.
13537
13538 2. Find the first row in W's current matrix that is not affected by
13539 changes at the end of current_buffer. Maybe there is no such row.
13540
13541 3. Display lines beginning with the row + 1 found in step 1 to the
13542 row found in step 2 or, if step 2 didn't find a row, to the end of
13543 the window.
13544
13545 4. If cursor is not known to appear on the window, give up.
13546
13547 5. If display stopped at the row found in step 2, scroll the
13548 display and current matrix as needed.
13549
13550 6. Maybe display some lines at the end of W, if we must. This can
13551 happen under various circumstances, like a partially visible line
13552 becoming fully visible, or because newly displayed lines are displayed
13553 in smaller font sizes.
13554
13555 7. Update W's window end information. */
13556
13557 static int
13558 try_window_id (w)
13559 struct window *w;
13560 {
13561 struct frame *f = XFRAME (w->frame);
13562 struct glyph_matrix *current_matrix = w->current_matrix;
13563 struct glyph_matrix *desired_matrix = w->desired_matrix;
13564 struct glyph_row *last_unchanged_at_beg_row;
13565 struct glyph_row *first_unchanged_at_end_row;
13566 struct glyph_row *row;
13567 struct glyph_row *bottom_row;
13568 int bottom_vpos;
13569 struct it it;
13570 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13571 struct text_pos start_pos;
13572 struct run run;
13573 int first_unchanged_at_end_vpos = 0;
13574 struct glyph_row *last_text_row, *last_text_row_at_end;
13575 struct text_pos start;
13576 int first_changed_charpos, last_changed_charpos;
13577
13578 #if GLYPH_DEBUG
13579 if (inhibit_try_window_id)
13580 return 0;
13581 #endif
13582
13583 /* This is handy for debugging. */
13584 #if 0
13585 #define GIVE_UP(X) \
13586 do { \
13587 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13588 return 0; \
13589 } while (0)
13590 #else
13591 #define GIVE_UP(X) return 0
13592 #endif
13593
13594 SET_TEXT_POS_FROM_MARKER (start, w->start);
13595
13596 /* Don't use this for mini-windows because these can show
13597 messages and mini-buffers, and we don't handle that here. */
13598 if (MINI_WINDOW_P (w))
13599 GIVE_UP (1);
13600
13601 /* This flag is used to prevent redisplay optimizations. */
13602 if (windows_or_buffers_changed || cursor_type_changed)
13603 GIVE_UP (2);
13604
13605 /* Verify that narrowing has not changed.
13606 Also verify that we were not told to prevent redisplay optimizations.
13607 It would be nice to further
13608 reduce the number of cases where this prevents try_window_id. */
13609 if (current_buffer->clip_changed
13610 || current_buffer->prevent_redisplay_optimizations_p)
13611 GIVE_UP (3);
13612
13613 /* Window must either use window-based redisplay or be full width. */
13614 if (!FRAME_WINDOW_P (f)
13615 && (!line_ins_del_ok
13616 || !WINDOW_FULL_WIDTH_P (w)))
13617 GIVE_UP (4);
13618
13619 /* Give up if point is not known NOT to appear in W. */
13620 if (PT < CHARPOS (start))
13621 GIVE_UP (5);
13622
13623 /* Another way to prevent redisplay optimizations. */
13624 if (XFASTINT (w->last_modified) == 0)
13625 GIVE_UP (6);
13626
13627 /* Verify that window is not hscrolled. */
13628 if (XFASTINT (w->hscroll) != 0)
13629 GIVE_UP (7);
13630
13631 /* Verify that display wasn't paused. */
13632 if (NILP (w->window_end_valid))
13633 GIVE_UP (8);
13634
13635 /* Can't use this if highlighting a region because a cursor movement
13636 will do more than just set the cursor. */
13637 if (!NILP (Vtransient_mark_mode)
13638 && !NILP (current_buffer->mark_active))
13639 GIVE_UP (9);
13640
13641 /* Likewise if highlighting trailing whitespace. */
13642 if (!NILP (Vshow_trailing_whitespace))
13643 GIVE_UP (11);
13644
13645 /* Likewise if showing a region. */
13646 if (!NILP (w->region_showing))
13647 GIVE_UP (10);
13648
13649 /* Can use this if overlay arrow position and or string have changed. */
13650 if (overlay_arrows_changed_p ())
13651 GIVE_UP (12);
13652
13653
13654 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13655 only if buffer has really changed. The reason is that the gap is
13656 initially at Z for freshly visited files. The code below would
13657 set end_unchanged to 0 in that case. */
13658 if (MODIFF > SAVE_MODIFF
13659 /* This seems to happen sometimes after saving a buffer. */
13660 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13661 {
13662 if (GPT - BEG < BEG_UNCHANGED)
13663 BEG_UNCHANGED = GPT - BEG;
13664 if (Z - GPT < END_UNCHANGED)
13665 END_UNCHANGED = Z - GPT;
13666 }
13667
13668 /* The position of the first and last character that has been changed. */
13669 first_changed_charpos = BEG + BEG_UNCHANGED;
13670 last_changed_charpos = Z - END_UNCHANGED;
13671
13672 /* If window starts after a line end, and the last change is in
13673 front of that newline, then changes don't affect the display.
13674 This case happens with stealth-fontification. Note that although
13675 the display is unchanged, glyph positions in the matrix have to
13676 be adjusted, of course. */
13677 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13678 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13679 && ((last_changed_charpos < CHARPOS (start)
13680 && CHARPOS (start) == BEGV)
13681 || (last_changed_charpos < CHARPOS (start) - 1
13682 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13683 {
13684 int Z_old, delta, Z_BYTE_old, delta_bytes;
13685 struct glyph_row *r0;
13686
13687 /* Compute how many chars/bytes have been added to or removed
13688 from the buffer. */
13689 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13690 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13691 delta = Z - Z_old;
13692 delta_bytes = Z_BYTE - Z_BYTE_old;
13693
13694 /* Give up if PT is not in the window. Note that it already has
13695 been checked at the start of try_window_id that PT is not in
13696 front of the window start. */
13697 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13698 GIVE_UP (13);
13699
13700 /* If window start is unchanged, we can reuse the whole matrix
13701 as is, after adjusting glyph positions. No need to compute
13702 the window end again, since its offset from Z hasn't changed. */
13703 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13704 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13705 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13706 /* PT must not be in a partially visible line. */
13707 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13708 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13709 {
13710 /* Adjust positions in the glyph matrix. */
13711 if (delta || delta_bytes)
13712 {
13713 struct glyph_row *r1
13714 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13715 increment_matrix_positions (w->current_matrix,
13716 MATRIX_ROW_VPOS (r0, current_matrix),
13717 MATRIX_ROW_VPOS (r1, current_matrix),
13718 delta, delta_bytes);
13719 }
13720
13721 /* Set the cursor. */
13722 row = row_containing_pos (w, PT, r0, NULL, 0);
13723 if (row)
13724 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13725 else
13726 abort ();
13727 return 1;
13728 }
13729 }
13730
13731 /* Handle the case that changes are all below what is displayed in
13732 the window, and that PT is in the window. This shortcut cannot
13733 be taken if ZV is visible in the window, and text has been added
13734 there that is visible in the window. */
13735 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13736 /* ZV is not visible in the window, or there are no
13737 changes at ZV, actually. */
13738 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13739 || first_changed_charpos == last_changed_charpos))
13740 {
13741 struct glyph_row *r0;
13742
13743 /* Give up if PT is not in the window. Note that it already has
13744 been checked at the start of try_window_id that PT is not in
13745 front of the window start. */
13746 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13747 GIVE_UP (14);
13748
13749 /* If window start is unchanged, we can reuse the whole matrix
13750 as is, without changing glyph positions since no text has
13751 been added/removed in front of the window end. */
13752 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13753 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13754 /* PT must not be in a partially visible line. */
13755 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13756 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13757 {
13758 /* We have to compute the window end anew since text
13759 can have been added/removed after it. */
13760 w->window_end_pos
13761 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13762 w->window_end_bytepos
13763 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13764
13765 /* Set the cursor. */
13766 row = row_containing_pos (w, PT, r0, NULL, 0);
13767 if (row)
13768 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13769 else
13770 abort ();
13771 return 2;
13772 }
13773 }
13774
13775 /* Give up if window start is in the changed area.
13776
13777 The condition used to read
13778
13779 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13780
13781 but why that was tested escapes me at the moment. */
13782 if (CHARPOS (start) >= first_changed_charpos
13783 && CHARPOS (start) <= last_changed_charpos)
13784 GIVE_UP (15);
13785
13786 /* Check that window start agrees with the start of the first glyph
13787 row in its current matrix. Check this after we know the window
13788 start is not in changed text, otherwise positions would not be
13789 comparable. */
13790 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13791 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13792 GIVE_UP (16);
13793
13794 /* Give up if the window ends in strings. Overlay strings
13795 at the end are difficult to handle, so don't try. */
13796 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13797 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13798 GIVE_UP (20);
13799
13800 /* Compute the position at which we have to start displaying new
13801 lines. Some of the lines at the top of the window might be
13802 reusable because they are not displaying changed text. Find the
13803 last row in W's current matrix not affected by changes at the
13804 start of current_buffer. Value is null if changes start in the
13805 first line of window. */
13806 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13807 if (last_unchanged_at_beg_row)
13808 {
13809 /* Avoid starting to display in the moddle of a character, a TAB
13810 for instance. This is easier than to set up the iterator
13811 exactly, and it's not a frequent case, so the additional
13812 effort wouldn't really pay off. */
13813 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13814 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13815 && last_unchanged_at_beg_row > w->current_matrix->rows)
13816 --last_unchanged_at_beg_row;
13817
13818 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13819 GIVE_UP (17);
13820
13821 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13822 GIVE_UP (18);
13823 start_pos = it.current.pos;
13824
13825 /* Start displaying new lines in the desired matrix at the same
13826 vpos we would use in the current matrix, i.e. below
13827 last_unchanged_at_beg_row. */
13828 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13829 current_matrix);
13830 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13831 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13832
13833 xassert (it.hpos == 0 && it.current_x == 0);
13834 }
13835 else
13836 {
13837 /* There are no reusable lines at the start of the window.
13838 Start displaying in the first text line. */
13839 start_display (&it, w, start);
13840 it.vpos = it.first_vpos;
13841 start_pos = it.current.pos;
13842 }
13843
13844 /* Find the first row that is not affected by changes at the end of
13845 the buffer. Value will be null if there is no unchanged row, in
13846 which case we must redisplay to the end of the window. delta
13847 will be set to the value by which buffer positions beginning with
13848 first_unchanged_at_end_row have to be adjusted due to text
13849 changes. */
13850 first_unchanged_at_end_row
13851 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13852 IF_DEBUG (debug_delta = delta);
13853 IF_DEBUG (debug_delta_bytes = delta_bytes);
13854
13855 /* Set stop_pos to the buffer position up to which we will have to
13856 display new lines. If first_unchanged_at_end_row != NULL, this
13857 is the buffer position of the start of the line displayed in that
13858 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13859 that we don't stop at a buffer position. */
13860 stop_pos = 0;
13861 if (first_unchanged_at_end_row)
13862 {
13863 xassert (last_unchanged_at_beg_row == NULL
13864 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13865
13866 /* If this is a continuation line, move forward to the next one
13867 that isn't. Changes in lines above affect this line.
13868 Caution: this may move first_unchanged_at_end_row to a row
13869 not displaying text. */
13870 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13871 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13872 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13873 < it.last_visible_y))
13874 ++first_unchanged_at_end_row;
13875
13876 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13877 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13878 >= it.last_visible_y))
13879 first_unchanged_at_end_row = NULL;
13880 else
13881 {
13882 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13883 + delta);
13884 first_unchanged_at_end_vpos
13885 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13886 xassert (stop_pos >= Z - END_UNCHANGED);
13887 }
13888 }
13889 else if (last_unchanged_at_beg_row == NULL)
13890 GIVE_UP (19);
13891
13892
13893 #if GLYPH_DEBUG
13894
13895 /* Either there is no unchanged row at the end, or the one we have
13896 now displays text. This is a necessary condition for the window
13897 end pos calculation at the end of this function. */
13898 xassert (first_unchanged_at_end_row == NULL
13899 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13900
13901 debug_last_unchanged_at_beg_vpos
13902 = (last_unchanged_at_beg_row
13903 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13904 : -1);
13905 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13906
13907 #endif /* GLYPH_DEBUG != 0 */
13908
13909
13910 /* Display new lines. Set last_text_row to the last new line
13911 displayed which has text on it, i.e. might end up as being the
13912 line where the window_end_vpos is. */
13913 w->cursor.vpos = -1;
13914 last_text_row = NULL;
13915 overlay_arrow_seen = 0;
13916 while (it.current_y < it.last_visible_y
13917 && !fonts_changed_p
13918 && (first_unchanged_at_end_row == NULL
13919 || IT_CHARPOS (it) < stop_pos))
13920 {
13921 if (display_line (&it))
13922 last_text_row = it.glyph_row - 1;
13923 }
13924
13925 if (fonts_changed_p)
13926 return -1;
13927
13928
13929 /* Compute differences in buffer positions, y-positions etc. for
13930 lines reused at the bottom of the window. Compute what we can
13931 scroll. */
13932 if (first_unchanged_at_end_row
13933 /* No lines reused because we displayed everything up to the
13934 bottom of the window. */
13935 && it.current_y < it.last_visible_y)
13936 {
13937 dvpos = (it.vpos
13938 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13939 current_matrix));
13940 dy = it.current_y - first_unchanged_at_end_row->y;
13941 run.current_y = first_unchanged_at_end_row->y;
13942 run.desired_y = run.current_y + dy;
13943 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13944 }
13945 else
13946 {
13947 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13948 first_unchanged_at_end_row = NULL;
13949 }
13950 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13951
13952
13953 /* Find the cursor if not already found. We have to decide whether
13954 PT will appear on this window (it sometimes doesn't, but this is
13955 not a very frequent case.) This decision has to be made before
13956 the current matrix is altered. A value of cursor.vpos < 0 means
13957 that PT is either in one of the lines beginning at
13958 first_unchanged_at_end_row or below the window. Don't care for
13959 lines that might be displayed later at the window end; as
13960 mentioned, this is not a frequent case. */
13961 if (w->cursor.vpos < 0)
13962 {
13963 /* Cursor in unchanged rows at the top? */
13964 if (PT < CHARPOS (start_pos)
13965 && last_unchanged_at_beg_row)
13966 {
13967 row = row_containing_pos (w, PT,
13968 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13969 last_unchanged_at_beg_row + 1, 0);
13970 if (row)
13971 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13972 }
13973
13974 /* Start from first_unchanged_at_end_row looking for PT. */
13975 else if (first_unchanged_at_end_row)
13976 {
13977 row = row_containing_pos (w, PT - delta,
13978 first_unchanged_at_end_row, NULL, 0);
13979 if (row)
13980 set_cursor_from_row (w, row, w->current_matrix, delta,
13981 delta_bytes, dy, dvpos);
13982 }
13983
13984 /* Give up if cursor was not found. */
13985 if (w->cursor.vpos < 0)
13986 {
13987 clear_glyph_matrix (w->desired_matrix);
13988 return -1;
13989 }
13990 }
13991
13992 /* Don't let the cursor end in the scroll margins. */
13993 {
13994 int this_scroll_margin, cursor_height;
13995
13996 this_scroll_margin = max (0, scroll_margin);
13997 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13998 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13999 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
14000
14001 if ((w->cursor.y < this_scroll_margin
14002 && CHARPOS (start) > BEGV)
14003 /* Old redisplay didn't take scroll margin into account at the bottom,
14004 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
14005 || (w->cursor.y + (make_cursor_line_fully_visible_p
14006 ? cursor_height + this_scroll_margin
14007 : 1)) > it.last_visible_y)
14008 {
14009 w->cursor.vpos = -1;
14010 clear_glyph_matrix (w->desired_matrix);
14011 return -1;
14012 }
14013 }
14014
14015 /* Scroll the display. Do it before changing the current matrix so
14016 that xterm.c doesn't get confused about where the cursor glyph is
14017 found. */
14018 if (dy && run.height)
14019 {
14020 update_begin (f);
14021
14022 if (FRAME_WINDOW_P (f))
14023 {
14024 rif->update_window_begin_hook (w);
14025 rif->clear_window_mouse_face (w);
14026 rif->scroll_run_hook (w, &run);
14027 rif->update_window_end_hook (w, 0, 0);
14028 }
14029 else
14030 {
14031 /* Terminal frame. In this case, dvpos gives the number of
14032 lines to scroll by; dvpos < 0 means scroll up. */
14033 int first_unchanged_at_end_vpos
14034 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
14035 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
14036 int end = (WINDOW_TOP_EDGE_LINE (w)
14037 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
14038 + window_internal_height (w));
14039
14040 /* Perform the operation on the screen. */
14041 if (dvpos > 0)
14042 {
14043 /* Scroll last_unchanged_at_beg_row to the end of the
14044 window down dvpos lines. */
14045 set_terminal_window (end);
14046
14047 /* On dumb terminals delete dvpos lines at the end
14048 before inserting dvpos empty lines. */
14049 if (!scroll_region_ok)
14050 ins_del_lines (end - dvpos, -dvpos);
14051
14052 /* Insert dvpos empty lines in front of
14053 last_unchanged_at_beg_row. */
14054 ins_del_lines (from, dvpos);
14055 }
14056 else if (dvpos < 0)
14057 {
14058 /* Scroll up last_unchanged_at_beg_vpos to the end of
14059 the window to last_unchanged_at_beg_vpos - |dvpos|. */
14060 set_terminal_window (end);
14061
14062 /* Delete dvpos lines in front of
14063 last_unchanged_at_beg_vpos. ins_del_lines will set
14064 the cursor to the given vpos and emit |dvpos| delete
14065 line sequences. */
14066 ins_del_lines (from + dvpos, dvpos);
14067
14068 /* On a dumb terminal insert dvpos empty lines at the
14069 end. */
14070 if (!scroll_region_ok)
14071 ins_del_lines (end + dvpos, -dvpos);
14072 }
14073
14074 set_terminal_window (0);
14075 }
14076
14077 update_end (f);
14078 }
14079
14080 /* Shift reused rows of the current matrix to the right position.
14081 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
14082 text. */
14083 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
14084 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
14085 if (dvpos < 0)
14086 {
14087 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
14088 bottom_vpos, dvpos);
14089 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
14090 bottom_vpos, 0);
14091 }
14092 else if (dvpos > 0)
14093 {
14094 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
14095 bottom_vpos, dvpos);
14096 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
14097 first_unchanged_at_end_vpos + dvpos, 0);
14098 }
14099
14100 /* For frame-based redisplay, make sure that current frame and window
14101 matrix are in sync with respect to glyph memory. */
14102 if (!FRAME_WINDOW_P (f))
14103 sync_frame_with_window_matrix_rows (w);
14104
14105 /* Adjust buffer positions in reused rows. */
14106 if (delta)
14107 increment_matrix_positions (current_matrix,
14108 first_unchanged_at_end_vpos + dvpos,
14109 bottom_vpos, delta, delta_bytes);
14110
14111 /* Adjust Y positions. */
14112 if (dy)
14113 shift_glyph_matrix (w, current_matrix,
14114 first_unchanged_at_end_vpos + dvpos,
14115 bottom_vpos, dy);
14116
14117 if (first_unchanged_at_end_row)
14118 {
14119 first_unchanged_at_end_row += dvpos;
14120 if (first_unchanged_at_end_row->y >= it.last_visible_y
14121 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
14122 first_unchanged_at_end_row = NULL;
14123 }
14124
14125 /* If scrolling up, there may be some lines to display at the end of
14126 the window. */
14127 last_text_row_at_end = NULL;
14128 if (dy < 0)
14129 {
14130 /* Scrolling up can leave for example a partially visible line
14131 at the end of the window to be redisplayed. */
14132 /* Set last_row to the glyph row in the current matrix where the
14133 window end line is found. It has been moved up or down in
14134 the matrix by dvpos. */
14135 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
14136 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
14137
14138 /* If last_row is the window end line, it should display text. */
14139 xassert (last_row->displays_text_p);
14140
14141 /* If window end line was partially visible before, begin
14142 displaying at that line. Otherwise begin displaying with the
14143 line following it. */
14144 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
14145 {
14146 init_to_row_start (&it, w, last_row);
14147 it.vpos = last_vpos;
14148 it.current_y = last_row->y;
14149 }
14150 else
14151 {
14152 init_to_row_end (&it, w, last_row);
14153 it.vpos = 1 + last_vpos;
14154 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
14155 ++last_row;
14156 }
14157
14158 /* We may start in a continuation line. If so, we have to
14159 get the right continuation_lines_width and current_x. */
14160 it.continuation_lines_width = last_row->continuation_lines_width;
14161 it.hpos = it.current_x = 0;
14162
14163 /* Display the rest of the lines at the window end. */
14164 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
14165 while (it.current_y < it.last_visible_y
14166 && !fonts_changed_p)
14167 {
14168 /* Is it always sure that the display agrees with lines in
14169 the current matrix? I don't think so, so we mark rows
14170 displayed invalid in the current matrix by setting their
14171 enabled_p flag to zero. */
14172 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
14173 if (display_line (&it))
14174 last_text_row_at_end = it.glyph_row - 1;
14175 }
14176 }
14177
14178 /* Update window_end_pos and window_end_vpos. */
14179 if (first_unchanged_at_end_row
14180 && !last_text_row_at_end)
14181 {
14182 /* Window end line if one of the preserved rows from the current
14183 matrix. Set row to the last row displaying text in current
14184 matrix starting at first_unchanged_at_end_row, after
14185 scrolling. */
14186 xassert (first_unchanged_at_end_row->displays_text_p);
14187 row = find_last_row_displaying_text (w->current_matrix, &it,
14188 first_unchanged_at_end_row);
14189 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
14190
14191 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14192 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14193 w->window_end_vpos
14194 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
14195 xassert (w->window_end_bytepos >= 0);
14196 IF_DEBUG (debug_method_add (w, "A"));
14197 }
14198 else if (last_text_row_at_end)
14199 {
14200 w->window_end_pos
14201 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
14202 w->window_end_bytepos
14203 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
14204 w->window_end_vpos
14205 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
14206 xassert (w->window_end_bytepos >= 0);
14207 IF_DEBUG (debug_method_add (w, "B"));
14208 }
14209 else if (last_text_row)
14210 {
14211 /* We have displayed either to the end of the window or at the
14212 end of the window, i.e. the last row with text is to be found
14213 in the desired matrix. */
14214 w->window_end_pos
14215 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
14216 w->window_end_bytepos
14217 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
14218 w->window_end_vpos
14219 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
14220 xassert (w->window_end_bytepos >= 0);
14221 }
14222 else if (first_unchanged_at_end_row == NULL
14223 && last_text_row == NULL
14224 && last_text_row_at_end == NULL)
14225 {
14226 /* Displayed to end of window, but no line containing text was
14227 displayed. Lines were deleted at the end of the window. */
14228 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
14229 int vpos = XFASTINT (w->window_end_vpos);
14230 struct glyph_row *current_row = current_matrix->rows + vpos;
14231 struct glyph_row *desired_row = desired_matrix->rows + vpos;
14232
14233 for (row = NULL;
14234 row == NULL && vpos >= first_vpos;
14235 --vpos, --current_row, --desired_row)
14236 {
14237 if (desired_row->enabled_p)
14238 {
14239 if (desired_row->displays_text_p)
14240 row = desired_row;
14241 }
14242 else if (current_row->displays_text_p)
14243 row = current_row;
14244 }
14245
14246 xassert (row != NULL);
14247 w->window_end_vpos = make_number (vpos + 1);
14248 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14249 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14250 xassert (w->window_end_bytepos >= 0);
14251 IF_DEBUG (debug_method_add (w, "C"));
14252 }
14253 else
14254 abort ();
14255
14256 #if 0 /* This leads to problems, for instance when the cursor is
14257 at ZV, and the cursor line displays no text. */
14258 /* Disable rows below what's displayed in the window. This makes
14259 debugging easier. */
14260 enable_glyph_matrix_rows (current_matrix,
14261 XFASTINT (w->window_end_vpos) + 1,
14262 bottom_vpos, 0);
14263 #endif
14264
14265 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
14266 debug_end_vpos = XFASTINT (w->window_end_vpos));
14267
14268 /* Record that display has not been completed. */
14269 w->window_end_valid = Qnil;
14270 w->desired_matrix->no_scrolling_p = 1;
14271 return 3;
14272
14273 #undef GIVE_UP
14274 }
14275
14276
14277 \f
14278 /***********************************************************************
14279 More debugging support
14280 ***********************************************************************/
14281
14282 #if GLYPH_DEBUG
14283
14284 void dump_glyph_row P_ ((struct glyph_row *, int, int));
14285 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
14286 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
14287
14288
14289 /* Dump the contents of glyph matrix MATRIX on stderr.
14290
14291 GLYPHS 0 means don't show glyph contents.
14292 GLYPHS 1 means show glyphs in short form
14293 GLYPHS > 1 means show glyphs in long form. */
14294
14295 void
14296 dump_glyph_matrix (matrix, glyphs)
14297 struct glyph_matrix *matrix;
14298 int glyphs;
14299 {
14300 int i;
14301 for (i = 0; i < matrix->nrows; ++i)
14302 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
14303 }
14304
14305
14306 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14307 the glyph row and area where the glyph comes from. */
14308
14309 void
14310 dump_glyph (row, glyph, area)
14311 struct glyph_row *row;
14312 struct glyph *glyph;
14313 int area;
14314 {
14315 if (glyph->type == CHAR_GLYPH)
14316 {
14317 fprintf (stderr,
14318 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14319 glyph - row->glyphs[TEXT_AREA],
14320 'C',
14321 glyph->charpos,
14322 (BUFFERP (glyph->object)
14323 ? 'B'
14324 : (STRINGP (glyph->object)
14325 ? 'S'
14326 : '-')),
14327 glyph->pixel_width,
14328 glyph->u.ch,
14329 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
14330 ? glyph->u.ch
14331 : '.'),
14332 glyph->face_id,
14333 glyph->left_box_line_p,
14334 glyph->right_box_line_p);
14335 }
14336 else if (glyph->type == STRETCH_GLYPH)
14337 {
14338 fprintf (stderr,
14339 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14340 glyph - row->glyphs[TEXT_AREA],
14341 'S',
14342 glyph->charpos,
14343 (BUFFERP (glyph->object)
14344 ? 'B'
14345 : (STRINGP (glyph->object)
14346 ? 'S'
14347 : '-')),
14348 glyph->pixel_width,
14349 0,
14350 '.',
14351 glyph->face_id,
14352 glyph->left_box_line_p,
14353 glyph->right_box_line_p);
14354 }
14355 else if (glyph->type == IMAGE_GLYPH)
14356 {
14357 fprintf (stderr,
14358 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14359 glyph - row->glyphs[TEXT_AREA],
14360 'I',
14361 glyph->charpos,
14362 (BUFFERP (glyph->object)
14363 ? 'B'
14364 : (STRINGP (glyph->object)
14365 ? 'S'
14366 : '-')),
14367 glyph->pixel_width,
14368 glyph->u.img_id,
14369 '.',
14370 glyph->face_id,
14371 glyph->left_box_line_p,
14372 glyph->right_box_line_p);
14373 }
14374 }
14375
14376
14377 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14378 GLYPHS 0 means don't show glyph contents.
14379 GLYPHS 1 means show glyphs in short form
14380 GLYPHS > 1 means show glyphs in long form. */
14381
14382 void
14383 dump_glyph_row (row, vpos, glyphs)
14384 struct glyph_row *row;
14385 int vpos, glyphs;
14386 {
14387 if (glyphs != 1)
14388 {
14389 fprintf (stderr, "Row Start End Used oEI><\\CTZFesm X Y W H V A P\n");
14390 fprintf (stderr, "======================================================================\n");
14391
14392 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
14393 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14394 vpos,
14395 MATRIX_ROW_START_CHARPOS (row),
14396 MATRIX_ROW_END_CHARPOS (row),
14397 row->used[TEXT_AREA],
14398 row->contains_overlapping_glyphs_p,
14399 row->enabled_p,
14400 row->truncated_on_left_p,
14401 row->truncated_on_right_p,
14402 row->continued_p,
14403 MATRIX_ROW_CONTINUATION_LINE_P (row),
14404 row->displays_text_p,
14405 row->ends_at_zv_p,
14406 row->fill_line_p,
14407 row->ends_in_middle_of_char_p,
14408 row->starts_in_middle_of_char_p,
14409 row->mouse_face_p,
14410 row->x,
14411 row->y,
14412 row->pixel_width,
14413 row->height,
14414 row->visible_height,
14415 row->ascent,
14416 row->phys_ascent);
14417 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14418 row->end.overlay_string_index,
14419 row->continuation_lines_width);
14420 fprintf (stderr, "%9d %5d\n",
14421 CHARPOS (row->start.string_pos),
14422 CHARPOS (row->end.string_pos));
14423 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14424 row->end.dpvec_index);
14425 }
14426
14427 if (glyphs > 1)
14428 {
14429 int area;
14430
14431 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14432 {
14433 struct glyph *glyph = row->glyphs[area];
14434 struct glyph *glyph_end = glyph + row->used[area];
14435
14436 /* Glyph for a line end in text. */
14437 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14438 ++glyph_end;
14439
14440 if (glyph < glyph_end)
14441 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14442
14443 for (; glyph < glyph_end; ++glyph)
14444 dump_glyph (row, glyph, area);
14445 }
14446 }
14447 else if (glyphs == 1)
14448 {
14449 int area;
14450
14451 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14452 {
14453 char *s = (char *) alloca (row->used[area] + 1);
14454 int i;
14455
14456 for (i = 0; i < row->used[area]; ++i)
14457 {
14458 struct glyph *glyph = row->glyphs[area] + i;
14459 if (glyph->type == CHAR_GLYPH
14460 && glyph->u.ch < 0x80
14461 && glyph->u.ch >= ' ')
14462 s[i] = glyph->u.ch;
14463 else
14464 s[i] = '.';
14465 }
14466
14467 s[i] = '\0';
14468 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14469 }
14470 }
14471 }
14472
14473
14474 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14475 Sdump_glyph_matrix, 0, 1, "p",
14476 doc: /* Dump the current matrix of the selected window to stderr.
14477 Shows contents of glyph row structures. With non-nil
14478 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14479 glyphs in short form, otherwise show glyphs in long form. */)
14480 (glyphs)
14481 Lisp_Object glyphs;
14482 {
14483 struct window *w = XWINDOW (selected_window);
14484 struct buffer *buffer = XBUFFER (w->buffer);
14485
14486 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14487 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14488 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14489 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14490 fprintf (stderr, "=============================================\n");
14491 dump_glyph_matrix (w->current_matrix,
14492 NILP (glyphs) ? 0 : XINT (glyphs));
14493 return Qnil;
14494 }
14495
14496
14497 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14498 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14499 ()
14500 {
14501 struct frame *f = XFRAME (selected_frame);
14502 dump_glyph_matrix (f->current_matrix, 1);
14503 return Qnil;
14504 }
14505
14506
14507 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14508 doc: /* Dump glyph row ROW to stderr.
14509 GLYPH 0 means don't dump glyphs.
14510 GLYPH 1 means dump glyphs in short form.
14511 GLYPH > 1 or omitted means dump glyphs in long form. */)
14512 (row, glyphs)
14513 Lisp_Object row, glyphs;
14514 {
14515 struct glyph_matrix *matrix;
14516 int vpos;
14517
14518 CHECK_NUMBER (row);
14519 matrix = XWINDOW (selected_window)->current_matrix;
14520 vpos = XINT (row);
14521 if (vpos >= 0 && vpos < matrix->nrows)
14522 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14523 vpos,
14524 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14525 return Qnil;
14526 }
14527
14528
14529 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14530 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14531 GLYPH 0 means don't dump glyphs.
14532 GLYPH 1 means dump glyphs in short form.
14533 GLYPH > 1 or omitted means dump glyphs in long form. */)
14534 (row, glyphs)
14535 Lisp_Object row, glyphs;
14536 {
14537 struct frame *sf = SELECTED_FRAME ();
14538 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14539 int vpos;
14540
14541 CHECK_NUMBER (row);
14542 vpos = XINT (row);
14543 if (vpos >= 0 && vpos < m->nrows)
14544 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14545 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14546 return Qnil;
14547 }
14548
14549
14550 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14551 doc: /* Toggle tracing of redisplay.
14552 With ARG, turn tracing on if and only if ARG is positive. */)
14553 (arg)
14554 Lisp_Object arg;
14555 {
14556 if (NILP (arg))
14557 trace_redisplay_p = !trace_redisplay_p;
14558 else
14559 {
14560 arg = Fprefix_numeric_value (arg);
14561 trace_redisplay_p = XINT (arg) > 0;
14562 }
14563
14564 return Qnil;
14565 }
14566
14567
14568 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14569 doc: /* Like `format', but print result to stderr.
14570 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14571 (nargs, args)
14572 int nargs;
14573 Lisp_Object *args;
14574 {
14575 Lisp_Object s = Fformat (nargs, args);
14576 fprintf (stderr, "%s", SDATA (s));
14577 return Qnil;
14578 }
14579
14580 #endif /* GLYPH_DEBUG */
14581
14582
14583 \f
14584 /***********************************************************************
14585 Building Desired Matrix Rows
14586 ***********************************************************************/
14587
14588 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14589 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14590
14591 static struct glyph_row *
14592 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14593 struct window *w;
14594 Lisp_Object overlay_arrow_string;
14595 {
14596 struct frame *f = XFRAME (WINDOW_FRAME (w));
14597 struct buffer *buffer = XBUFFER (w->buffer);
14598 struct buffer *old = current_buffer;
14599 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14600 int arrow_len = SCHARS (overlay_arrow_string);
14601 const unsigned char *arrow_end = arrow_string + arrow_len;
14602 const unsigned char *p;
14603 struct it it;
14604 int multibyte_p;
14605 int n_glyphs_before;
14606
14607 set_buffer_temp (buffer);
14608 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14609 it.glyph_row->used[TEXT_AREA] = 0;
14610 SET_TEXT_POS (it.position, 0, 0);
14611
14612 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14613 p = arrow_string;
14614 while (p < arrow_end)
14615 {
14616 Lisp_Object face, ilisp;
14617
14618 /* Get the next character. */
14619 if (multibyte_p)
14620 it.c = string_char_and_length (p, arrow_len, &it.len);
14621 else
14622 it.c = *p, it.len = 1;
14623 p += it.len;
14624
14625 /* Get its face. */
14626 ilisp = make_number (p - arrow_string);
14627 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14628 it.face_id = compute_char_face (f, it.c, face);
14629
14630 /* Compute its width, get its glyphs. */
14631 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14632 SET_TEXT_POS (it.position, -1, -1);
14633 PRODUCE_GLYPHS (&it);
14634
14635 /* If this character doesn't fit any more in the line, we have
14636 to remove some glyphs. */
14637 if (it.current_x > it.last_visible_x)
14638 {
14639 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14640 break;
14641 }
14642 }
14643
14644 set_buffer_temp (old);
14645 return it.glyph_row;
14646 }
14647
14648
14649 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14650 glyphs are only inserted for terminal frames since we can't really
14651 win with truncation glyphs when partially visible glyphs are
14652 involved. Which glyphs to insert is determined by
14653 produce_special_glyphs. */
14654
14655 static void
14656 insert_left_trunc_glyphs (it)
14657 struct it *it;
14658 {
14659 struct it truncate_it;
14660 struct glyph *from, *end, *to, *toend;
14661
14662 xassert (!FRAME_WINDOW_P (it->f));
14663
14664 /* Get the truncation glyphs. */
14665 truncate_it = *it;
14666 truncate_it.current_x = 0;
14667 truncate_it.face_id = DEFAULT_FACE_ID;
14668 truncate_it.glyph_row = &scratch_glyph_row;
14669 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14670 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14671 truncate_it.object = make_number (0);
14672 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14673
14674 /* Overwrite glyphs from IT with truncation glyphs. */
14675 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14676 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14677 to = it->glyph_row->glyphs[TEXT_AREA];
14678 toend = to + it->glyph_row->used[TEXT_AREA];
14679
14680 while (from < end)
14681 *to++ = *from++;
14682
14683 /* There may be padding glyphs left over. Overwrite them too. */
14684 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14685 {
14686 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14687 while (from < end)
14688 *to++ = *from++;
14689 }
14690
14691 if (to > toend)
14692 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14693 }
14694
14695
14696 /* Compute the pixel height and width of IT->glyph_row.
14697
14698 Most of the time, ascent and height of a display line will be equal
14699 to the max_ascent and max_height values of the display iterator
14700 structure. This is not the case if
14701
14702 1. We hit ZV without displaying anything. In this case, max_ascent
14703 and max_height will be zero.
14704
14705 2. We have some glyphs that don't contribute to the line height.
14706 (The glyph row flag contributes_to_line_height_p is for future
14707 pixmap extensions).
14708
14709 The first case is easily covered by using default values because in
14710 these cases, the line height does not really matter, except that it
14711 must not be zero. */
14712
14713 static void
14714 compute_line_metrics (it)
14715 struct it *it;
14716 {
14717 struct glyph_row *row = it->glyph_row;
14718 int area, i;
14719
14720 if (FRAME_WINDOW_P (it->f))
14721 {
14722 int i, min_y, max_y;
14723
14724 /* The line may consist of one space only, that was added to
14725 place the cursor on it. If so, the row's height hasn't been
14726 computed yet. */
14727 if (row->height == 0)
14728 {
14729 if (it->max_ascent + it->max_descent == 0)
14730 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14731 row->ascent = it->max_ascent;
14732 row->height = it->max_ascent + it->max_descent;
14733 row->phys_ascent = it->max_phys_ascent;
14734 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14735 row->extra_line_spacing = it->max_extra_line_spacing;
14736 }
14737
14738 /* Compute the width of this line. */
14739 row->pixel_width = row->x;
14740 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14741 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14742
14743 xassert (row->pixel_width >= 0);
14744 xassert (row->ascent >= 0 && row->height > 0);
14745
14746 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14747 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14748
14749 /* If first line's physical ascent is larger than its logical
14750 ascent, use the physical ascent, and make the row taller.
14751 This makes accented characters fully visible. */
14752 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14753 && row->phys_ascent > row->ascent)
14754 {
14755 row->height += row->phys_ascent - row->ascent;
14756 row->ascent = row->phys_ascent;
14757 }
14758
14759 /* Compute how much of the line is visible. */
14760 row->visible_height = row->height;
14761
14762 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14763 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14764
14765 if (row->y < min_y)
14766 row->visible_height -= min_y - row->y;
14767 if (row->y + row->height > max_y)
14768 row->visible_height -= row->y + row->height - max_y;
14769 }
14770 else
14771 {
14772 row->pixel_width = row->used[TEXT_AREA];
14773 if (row->continued_p)
14774 row->pixel_width -= it->continuation_pixel_width;
14775 else if (row->truncated_on_right_p)
14776 row->pixel_width -= it->truncation_pixel_width;
14777 row->ascent = row->phys_ascent = 0;
14778 row->height = row->phys_height = row->visible_height = 1;
14779 row->extra_line_spacing = 0;
14780 }
14781
14782 /* Compute a hash code for this row. */
14783 row->hash = 0;
14784 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14785 for (i = 0; i < row->used[area]; ++i)
14786 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14787 + row->glyphs[area][i].u.val
14788 + row->glyphs[area][i].face_id
14789 + row->glyphs[area][i].padding_p
14790 + (row->glyphs[area][i].type << 2));
14791
14792 it->max_ascent = it->max_descent = 0;
14793 it->max_phys_ascent = it->max_phys_descent = 0;
14794 }
14795
14796
14797 /* Append one space to the glyph row of iterator IT if doing a
14798 window-based redisplay. The space has the same face as
14799 IT->face_id. Value is non-zero if a space was added.
14800
14801 This function is called to make sure that there is always one glyph
14802 at the end of a glyph row that the cursor can be set on under
14803 window-systems. (If there weren't such a glyph we would not know
14804 how wide and tall a box cursor should be displayed).
14805
14806 At the same time this space let's a nicely handle clearing to the
14807 end of the line if the row ends in italic text. */
14808
14809 static int
14810 append_space_for_newline (it, default_face_p)
14811 struct it *it;
14812 int default_face_p;
14813 {
14814 if (FRAME_WINDOW_P (it->f))
14815 {
14816 int n = it->glyph_row->used[TEXT_AREA];
14817
14818 if (it->glyph_row->glyphs[TEXT_AREA] + n
14819 < it->glyph_row->glyphs[1 + TEXT_AREA])
14820 {
14821 /* Save some values that must not be changed.
14822 Must save IT->c and IT->len because otherwise
14823 ITERATOR_AT_END_P wouldn't work anymore after
14824 append_space_for_newline has been called. */
14825 enum display_element_type saved_what = it->what;
14826 int saved_c = it->c, saved_len = it->len;
14827 int saved_x = it->current_x;
14828 int saved_face_id = it->face_id;
14829 struct text_pos saved_pos;
14830 Lisp_Object saved_object;
14831 struct face *face;
14832
14833 saved_object = it->object;
14834 saved_pos = it->position;
14835
14836 it->what = IT_CHARACTER;
14837 bzero (&it->position, sizeof it->position);
14838 it->object = make_number (0);
14839 it->c = ' ';
14840 it->len = 1;
14841
14842 if (default_face_p)
14843 it->face_id = DEFAULT_FACE_ID;
14844 else if (it->face_before_selective_p)
14845 it->face_id = it->saved_face_id;
14846 face = FACE_FROM_ID (it->f, it->face_id);
14847 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14848
14849 PRODUCE_GLYPHS (it);
14850
14851 it->override_ascent = -1;
14852 it->constrain_row_ascent_descent_p = 0;
14853 it->current_x = saved_x;
14854 it->object = saved_object;
14855 it->position = saved_pos;
14856 it->what = saved_what;
14857 it->face_id = saved_face_id;
14858 it->len = saved_len;
14859 it->c = saved_c;
14860 return 1;
14861 }
14862 }
14863
14864 return 0;
14865 }
14866
14867
14868 /* Extend the face of the last glyph in the text area of IT->glyph_row
14869 to the end of the display line. Called from display_line.
14870 If the glyph row is empty, add a space glyph to it so that we
14871 know the face to draw. Set the glyph row flag fill_line_p. */
14872
14873 static void
14874 extend_face_to_end_of_line (it)
14875 struct it *it;
14876 {
14877 struct face *face;
14878 struct frame *f = it->f;
14879
14880 /* If line is already filled, do nothing. */
14881 if (it->current_x >= it->last_visible_x)
14882 return;
14883
14884 /* Face extension extends the background and box of IT->face_id
14885 to the end of the line. If the background equals the background
14886 of the frame, we don't have to do anything. */
14887 if (it->face_before_selective_p)
14888 face = FACE_FROM_ID (it->f, it->saved_face_id);
14889 else
14890 face = FACE_FROM_ID (f, it->face_id);
14891
14892 if (FRAME_WINDOW_P (f)
14893 && face->box == FACE_NO_BOX
14894 && face->background == FRAME_BACKGROUND_PIXEL (f)
14895 && !face->stipple)
14896 return;
14897
14898 /* Set the glyph row flag indicating that the face of the last glyph
14899 in the text area has to be drawn to the end of the text area. */
14900 it->glyph_row->fill_line_p = 1;
14901
14902 /* If current character of IT is not ASCII, make sure we have the
14903 ASCII face. This will be automatically undone the next time
14904 get_next_display_element returns a multibyte character. Note
14905 that the character will always be single byte in unibyte text. */
14906 if (!SINGLE_BYTE_CHAR_P (it->c))
14907 {
14908 it->face_id = FACE_FOR_CHAR (f, face, 0);
14909 }
14910
14911 if (FRAME_WINDOW_P (f))
14912 {
14913 /* If the row is empty, add a space with the current face of IT,
14914 so that we know which face to draw. */
14915 if (it->glyph_row->used[TEXT_AREA] == 0)
14916 {
14917 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14918 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14919 it->glyph_row->used[TEXT_AREA] = 1;
14920 }
14921 }
14922 else
14923 {
14924 /* Save some values that must not be changed. */
14925 int saved_x = it->current_x;
14926 struct text_pos saved_pos;
14927 Lisp_Object saved_object;
14928 enum display_element_type saved_what = it->what;
14929 int saved_face_id = it->face_id;
14930
14931 saved_object = it->object;
14932 saved_pos = it->position;
14933
14934 it->what = IT_CHARACTER;
14935 bzero (&it->position, sizeof it->position);
14936 it->object = make_number (0);
14937 it->c = ' ';
14938 it->len = 1;
14939 it->face_id = face->id;
14940
14941 PRODUCE_GLYPHS (it);
14942
14943 while (it->current_x <= it->last_visible_x)
14944 PRODUCE_GLYPHS (it);
14945
14946 /* Don't count these blanks really. It would let us insert a left
14947 truncation glyph below and make us set the cursor on them, maybe. */
14948 it->current_x = saved_x;
14949 it->object = saved_object;
14950 it->position = saved_pos;
14951 it->what = saved_what;
14952 it->face_id = saved_face_id;
14953 }
14954 }
14955
14956
14957 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14958 trailing whitespace. */
14959
14960 static int
14961 trailing_whitespace_p (charpos)
14962 int charpos;
14963 {
14964 int bytepos = CHAR_TO_BYTE (charpos);
14965 int c = 0;
14966
14967 while (bytepos < ZV_BYTE
14968 && (c = FETCH_CHAR (bytepos),
14969 c == ' ' || c == '\t'))
14970 ++bytepos;
14971
14972 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14973 {
14974 if (bytepos != PT_BYTE)
14975 return 1;
14976 }
14977 return 0;
14978 }
14979
14980
14981 /* Highlight trailing whitespace, if any, in ROW. */
14982
14983 void
14984 highlight_trailing_whitespace (f, row)
14985 struct frame *f;
14986 struct glyph_row *row;
14987 {
14988 int used = row->used[TEXT_AREA];
14989
14990 if (used)
14991 {
14992 struct glyph *start = row->glyphs[TEXT_AREA];
14993 struct glyph *glyph = start + used - 1;
14994
14995 /* Skip over glyphs inserted to display the cursor at the
14996 end of a line, for extending the face of the last glyph
14997 to the end of the line on terminals, and for truncation
14998 and continuation glyphs. */
14999 while (glyph >= start
15000 && glyph->type == CHAR_GLYPH
15001 && INTEGERP (glyph->object))
15002 --glyph;
15003
15004 /* If last glyph is a space or stretch, and it's trailing
15005 whitespace, set the face of all trailing whitespace glyphs in
15006 IT->glyph_row to `trailing-whitespace'. */
15007 if (glyph >= start
15008 && BUFFERP (glyph->object)
15009 && (glyph->type == STRETCH_GLYPH
15010 || (glyph->type == CHAR_GLYPH
15011 && glyph->u.ch == ' '))
15012 && trailing_whitespace_p (glyph->charpos))
15013 {
15014 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
15015 if (face_id < 0)
15016 return;
15017
15018 while (glyph >= start
15019 && BUFFERP (glyph->object)
15020 && (glyph->type == STRETCH_GLYPH
15021 || (glyph->type == CHAR_GLYPH
15022 && glyph->u.ch == ' ')))
15023 (glyph--)->face_id = face_id;
15024 }
15025 }
15026 }
15027
15028
15029 /* Value is non-zero if glyph row ROW in window W should be
15030 used to hold the cursor. */
15031
15032 static int
15033 cursor_row_p (w, row)
15034 struct window *w;
15035 struct glyph_row *row;
15036 {
15037 int cursor_row_p = 1;
15038
15039 if (PT == MATRIX_ROW_END_CHARPOS (row))
15040 {
15041 /* If the row ends with a newline from a string, we don't want
15042 the cursor there, but we still want it at the start of the
15043 string if the string starts in this row.
15044 If the row is continued it doesn't end in a newline. */
15045 if (CHARPOS (row->end.string_pos) >= 0)
15046 cursor_row_p = (row->continued_p
15047 || PT >= MATRIX_ROW_START_CHARPOS (row));
15048 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
15049 {
15050 /* If the row ends in middle of a real character,
15051 and the line is continued, we want the cursor here.
15052 That's because MATRIX_ROW_END_CHARPOS would equal
15053 PT if PT is before the character. */
15054 if (!row->ends_in_ellipsis_p)
15055 cursor_row_p = row->continued_p;
15056 else
15057 /* If the row ends in an ellipsis, then
15058 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
15059 We want that position to be displayed after the ellipsis. */
15060 cursor_row_p = 0;
15061 }
15062 /* If the row ends at ZV, display the cursor at the end of that
15063 row instead of at the start of the row below. */
15064 else if (row->ends_at_zv_p)
15065 cursor_row_p = 1;
15066 else
15067 cursor_row_p = 0;
15068 }
15069
15070 return cursor_row_p;
15071 }
15072
15073
15074 /* Construct the glyph row IT->glyph_row in the desired matrix of
15075 IT->w from text at the current position of IT. See dispextern.h
15076 for an overview of struct it. Value is non-zero if
15077 IT->glyph_row displays text, as opposed to a line displaying ZV
15078 only. */
15079
15080 static int
15081 display_line (it)
15082 struct it *it;
15083 {
15084 struct glyph_row *row = it->glyph_row;
15085 Lisp_Object overlay_arrow_string;
15086
15087 /* We always start displaying at hpos zero even if hscrolled. */
15088 xassert (it->hpos == 0 && it->current_x == 0);
15089
15090 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
15091 >= it->w->desired_matrix->nrows)
15092 {
15093 it->w->nrows_scale_factor++;
15094 fonts_changed_p = 1;
15095 return 0;
15096 }
15097
15098 /* Is IT->w showing the region? */
15099 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
15100
15101 /* Clear the result glyph row and enable it. */
15102 prepare_desired_row (row);
15103
15104 row->y = it->current_y;
15105 row->start = it->start;
15106 row->continuation_lines_width = it->continuation_lines_width;
15107 row->displays_text_p = 1;
15108 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
15109 it->starts_in_middle_of_char_p = 0;
15110
15111 /* Arrange the overlays nicely for our purposes. Usually, we call
15112 display_line on only one line at a time, in which case this
15113 can't really hurt too much, or we call it on lines which appear
15114 one after another in the buffer, in which case all calls to
15115 recenter_overlay_lists but the first will be pretty cheap. */
15116 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
15117
15118 /* Move over display elements that are not visible because we are
15119 hscrolled. This may stop at an x-position < IT->first_visible_x
15120 if the first glyph is partially visible or if we hit a line end. */
15121 if (it->current_x < it->first_visible_x)
15122 {
15123 move_it_in_display_line_to (it, ZV, it->first_visible_x,
15124 MOVE_TO_POS | MOVE_TO_X);
15125 }
15126
15127 /* Get the initial row height. This is either the height of the
15128 text hscrolled, if there is any, or zero. */
15129 row->ascent = it->max_ascent;
15130 row->height = it->max_ascent + it->max_descent;
15131 row->phys_ascent = it->max_phys_ascent;
15132 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
15133 row->extra_line_spacing = it->max_extra_line_spacing;
15134
15135 /* Loop generating characters. The loop is left with IT on the next
15136 character to display. */
15137 while (1)
15138 {
15139 int n_glyphs_before, hpos_before, x_before;
15140 int x, i, nglyphs;
15141 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
15142
15143 /* Retrieve the next thing to display. Value is zero if end of
15144 buffer reached. */
15145 if (!get_next_display_element (it))
15146 {
15147 /* Maybe add a space at the end of this line that is used to
15148 display the cursor there under X. Set the charpos of the
15149 first glyph of blank lines not corresponding to any text
15150 to -1. */
15151 #ifdef HAVE_WINDOW_SYSTEM
15152 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15153 row->exact_window_width_line_p = 1;
15154 else
15155 #endif /* HAVE_WINDOW_SYSTEM */
15156 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
15157 || row->used[TEXT_AREA] == 0)
15158 {
15159 row->glyphs[TEXT_AREA]->charpos = -1;
15160 row->displays_text_p = 0;
15161
15162 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
15163 && (!MINI_WINDOW_P (it->w)
15164 || (minibuf_level && EQ (it->window, minibuf_window))))
15165 row->indicate_empty_line_p = 1;
15166 }
15167
15168 it->continuation_lines_width = 0;
15169 row->ends_at_zv_p = 1;
15170 break;
15171 }
15172
15173 /* Now, get the metrics of what we want to display. This also
15174 generates glyphs in `row' (which is IT->glyph_row). */
15175 n_glyphs_before = row->used[TEXT_AREA];
15176 x = it->current_x;
15177
15178 /* Remember the line height so far in case the next element doesn't
15179 fit on the line. */
15180 if (!it->truncate_lines_p)
15181 {
15182 ascent = it->max_ascent;
15183 descent = it->max_descent;
15184 phys_ascent = it->max_phys_ascent;
15185 phys_descent = it->max_phys_descent;
15186 }
15187
15188 PRODUCE_GLYPHS (it);
15189
15190 /* If this display element was in marginal areas, continue with
15191 the next one. */
15192 if (it->area != TEXT_AREA)
15193 {
15194 row->ascent = max (row->ascent, it->max_ascent);
15195 row->height = max (row->height, it->max_ascent + it->max_descent);
15196 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15197 row->phys_height = max (row->phys_height,
15198 it->max_phys_ascent + it->max_phys_descent);
15199 row->extra_line_spacing = max (row->extra_line_spacing,
15200 it->max_extra_line_spacing);
15201 set_iterator_to_next (it, 1);
15202 continue;
15203 }
15204
15205 /* Does the display element fit on the line? If we truncate
15206 lines, we should draw past the right edge of the window. If
15207 we don't truncate, we want to stop so that we can display the
15208 continuation glyph before the right margin. If lines are
15209 continued, there are two possible strategies for characters
15210 resulting in more than 1 glyph (e.g. tabs): Display as many
15211 glyphs as possible in this line and leave the rest for the
15212 continuation line, or display the whole element in the next
15213 line. Original redisplay did the former, so we do it also. */
15214 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
15215 hpos_before = it->hpos;
15216 x_before = x;
15217
15218 if (/* Not a newline. */
15219 nglyphs > 0
15220 /* Glyphs produced fit entirely in the line. */
15221 && it->current_x < it->last_visible_x)
15222 {
15223 it->hpos += nglyphs;
15224 row->ascent = max (row->ascent, it->max_ascent);
15225 row->height = max (row->height, it->max_ascent + it->max_descent);
15226 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15227 row->phys_height = max (row->phys_height,
15228 it->max_phys_ascent + it->max_phys_descent);
15229 row->extra_line_spacing = max (row->extra_line_spacing,
15230 it->max_extra_line_spacing);
15231 if (it->current_x - it->pixel_width < it->first_visible_x)
15232 row->x = x - it->first_visible_x;
15233 }
15234 else
15235 {
15236 int new_x;
15237 struct glyph *glyph;
15238
15239 for (i = 0; i < nglyphs; ++i, x = new_x)
15240 {
15241 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
15242 new_x = x + glyph->pixel_width;
15243
15244 if (/* Lines are continued. */
15245 !it->truncate_lines_p
15246 && (/* Glyph doesn't fit on the line. */
15247 new_x > it->last_visible_x
15248 /* Or it fits exactly on a window system frame. */
15249 || (new_x == it->last_visible_x
15250 && FRAME_WINDOW_P (it->f))))
15251 {
15252 /* End of a continued line. */
15253
15254 if (it->hpos == 0
15255 || (new_x == it->last_visible_x
15256 && FRAME_WINDOW_P (it->f)))
15257 {
15258 /* Current glyph is the only one on the line or
15259 fits exactly on the line. We must continue
15260 the line because we can't draw the cursor
15261 after the glyph. */
15262 row->continued_p = 1;
15263 it->current_x = new_x;
15264 it->continuation_lines_width += new_x;
15265 ++it->hpos;
15266 if (i == nglyphs - 1)
15267 {
15268 set_iterator_to_next (it, 1);
15269 #ifdef HAVE_WINDOW_SYSTEM
15270 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15271 {
15272 if (!get_next_display_element (it))
15273 {
15274 row->exact_window_width_line_p = 1;
15275 it->continuation_lines_width = 0;
15276 row->continued_p = 0;
15277 row->ends_at_zv_p = 1;
15278 }
15279 else if (ITERATOR_AT_END_OF_LINE_P (it))
15280 {
15281 row->continued_p = 0;
15282 row->exact_window_width_line_p = 1;
15283 }
15284 }
15285 #endif /* HAVE_WINDOW_SYSTEM */
15286 }
15287 }
15288 else if (CHAR_GLYPH_PADDING_P (*glyph)
15289 && !FRAME_WINDOW_P (it->f))
15290 {
15291 /* A padding glyph that doesn't fit on this line.
15292 This means the whole character doesn't fit
15293 on the line. */
15294 row->used[TEXT_AREA] = n_glyphs_before;
15295
15296 /* Fill the rest of the row with continuation
15297 glyphs like in 20.x. */
15298 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
15299 < row->glyphs[1 + TEXT_AREA])
15300 produce_special_glyphs (it, IT_CONTINUATION);
15301
15302 row->continued_p = 1;
15303 it->current_x = x_before;
15304 it->continuation_lines_width += x_before;
15305
15306 /* Restore the height to what it was before the
15307 element not fitting on the line. */
15308 it->max_ascent = ascent;
15309 it->max_descent = descent;
15310 it->max_phys_ascent = phys_ascent;
15311 it->max_phys_descent = phys_descent;
15312 }
15313 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
15314 {
15315 /* A TAB that extends past the right edge of the
15316 window. This produces a single glyph on
15317 window system frames. We leave the glyph in
15318 this row and let it fill the row, but don't
15319 consume the TAB. */
15320 it->continuation_lines_width += it->last_visible_x;
15321 row->ends_in_middle_of_char_p = 1;
15322 row->continued_p = 1;
15323 glyph->pixel_width = it->last_visible_x - x;
15324 it->starts_in_middle_of_char_p = 1;
15325 }
15326 else
15327 {
15328 /* Something other than a TAB that draws past
15329 the right edge of the window. Restore
15330 positions to values before the element. */
15331 row->used[TEXT_AREA] = n_glyphs_before + i;
15332
15333 /* Display continuation glyphs. */
15334 if (!FRAME_WINDOW_P (it->f))
15335 produce_special_glyphs (it, IT_CONTINUATION);
15336 row->continued_p = 1;
15337
15338 it->continuation_lines_width += x;
15339
15340 if (nglyphs > 1 && i > 0)
15341 {
15342 row->ends_in_middle_of_char_p = 1;
15343 it->starts_in_middle_of_char_p = 1;
15344 }
15345
15346 /* Restore the height to what it was before the
15347 element not fitting on the line. */
15348 it->max_ascent = ascent;
15349 it->max_descent = descent;
15350 it->max_phys_ascent = phys_ascent;
15351 it->max_phys_descent = phys_descent;
15352 }
15353
15354 break;
15355 }
15356 else if (new_x > it->first_visible_x)
15357 {
15358 /* Increment number of glyphs actually displayed. */
15359 ++it->hpos;
15360
15361 if (x < it->first_visible_x)
15362 /* Glyph is partially visible, i.e. row starts at
15363 negative X position. */
15364 row->x = x - it->first_visible_x;
15365 }
15366 else
15367 {
15368 /* Glyph is completely off the left margin of the
15369 window. This should not happen because of the
15370 move_it_in_display_line at the start of this
15371 function, unless the text display area of the
15372 window is empty. */
15373 xassert (it->first_visible_x <= it->last_visible_x);
15374 }
15375 }
15376
15377 row->ascent = max (row->ascent, it->max_ascent);
15378 row->height = max (row->height, it->max_ascent + it->max_descent);
15379 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15380 row->phys_height = max (row->phys_height,
15381 it->max_phys_ascent + it->max_phys_descent);
15382 row->extra_line_spacing = max (row->extra_line_spacing,
15383 it->max_extra_line_spacing);
15384
15385 /* End of this display line if row is continued. */
15386 if (row->continued_p || row->ends_at_zv_p)
15387 break;
15388 }
15389
15390 at_end_of_line:
15391 /* Is this a line end? If yes, we're also done, after making
15392 sure that a non-default face is extended up to the right
15393 margin of the window. */
15394 if (ITERATOR_AT_END_OF_LINE_P (it))
15395 {
15396 int used_before = row->used[TEXT_AREA];
15397
15398 row->ends_in_newline_from_string_p = STRINGP (it->object);
15399
15400 #ifdef HAVE_WINDOW_SYSTEM
15401 /* Add a space at the end of the line that is used to
15402 display the cursor there. */
15403 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15404 append_space_for_newline (it, 0);
15405 #endif /* HAVE_WINDOW_SYSTEM */
15406
15407 /* Extend the face to the end of the line. */
15408 extend_face_to_end_of_line (it);
15409
15410 /* Make sure we have the position. */
15411 if (used_before == 0)
15412 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15413
15414 /* Consume the line end. This skips over invisible lines. */
15415 set_iterator_to_next (it, 1);
15416 it->continuation_lines_width = 0;
15417 break;
15418 }
15419
15420 /* Proceed with next display element. Note that this skips
15421 over lines invisible because of selective display. */
15422 set_iterator_to_next (it, 1);
15423
15424 /* If we truncate lines, we are done when the last displayed
15425 glyphs reach past the right margin of the window. */
15426 if (it->truncate_lines_p
15427 && (FRAME_WINDOW_P (it->f)
15428 ? (it->current_x >= it->last_visible_x)
15429 : (it->current_x > it->last_visible_x)))
15430 {
15431 /* Maybe add truncation glyphs. */
15432 if (!FRAME_WINDOW_P (it->f))
15433 {
15434 int i, n;
15435
15436 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15437 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15438 break;
15439
15440 for (n = row->used[TEXT_AREA]; i < n; ++i)
15441 {
15442 row->used[TEXT_AREA] = i;
15443 produce_special_glyphs (it, IT_TRUNCATION);
15444 }
15445 }
15446 #ifdef HAVE_WINDOW_SYSTEM
15447 else
15448 {
15449 /* Don't truncate if we can overflow newline into fringe. */
15450 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15451 {
15452 if (!get_next_display_element (it))
15453 {
15454 it->continuation_lines_width = 0;
15455 row->ends_at_zv_p = 1;
15456 row->exact_window_width_line_p = 1;
15457 break;
15458 }
15459 if (ITERATOR_AT_END_OF_LINE_P (it))
15460 {
15461 row->exact_window_width_line_p = 1;
15462 goto at_end_of_line;
15463 }
15464 }
15465 }
15466 #endif /* HAVE_WINDOW_SYSTEM */
15467
15468 row->truncated_on_right_p = 1;
15469 it->continuation_lines_width = 0;
15470 reseat_at_next_visible_line_start (it, 0);
15471 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15472 it->hpos = hpos_before;
15473 it->current_x = x_before;
15474 break;
15475 }
15476 }
15477
15478 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15479 at the left window margin. */
15480 if (it->first_visible_x
15481 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15482 {
15483 if (!FRAME_WINDOW_P (it->f))
15484 insert_left_trunc_glyphs (it);
15485 row->truncated_on_left_p = 1;
15486 }
15487
15488 /* If the start of this line is the overlay arrow-position, then
15489 mark this glyph row as the one containing the overlay arrow.
15490 This is clearly a mess with variable size fonts. It would be
15491 better to let it be displayed like cursors under X. */
15492 if ((row->displays_text_p || !overlay_arrow_seen)
15493 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
15494 !NILP (overlay_arrow_string)))
15495 {
15496 /* Overlay arrow in window redisplay is a fringe bitmap. */
15497 if (STRINGP (overlay_arrow_string))
15498 {
15499 struct glyph_row *arrow_row
15500 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15501 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15502 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15503 struct glyph *p = row->glyphs[TEXT_AREA];
15504 struct glyph *p2, *end;
15505
15506 /* Copy the arrow glyphs. */
15507 while (glyph < arrow_end)
15508 *p++ = *glyph++;
15509
15510 /* Throw away padding glyphs. */
15511 p2 = p;
15512 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15513 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15514 ++p2;
15515 if (p2 > p)
15516 {
15517 while (p2 < end)
15518 *p++ = *p2++;
15519 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15520 }
15521 }
15522 else
15523 {
15524 xassert (INTEGERP (overlay_arrow_string));
15525 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
15526 }
15527 overlay_arrow_seen = 1;
15528 }
15529
15530 /* Compute pixel dimensions of this line. */
15531 compute_line_metrics (it);
15532
15533 /* Remember the position at which this line ends. */
15534 row->end = it->current;
15535
15536 /* Record whether this row ends inside an ellipsis. */
15537 row->ends_in_ellipsis_p
15538 = (it->method == GET_FROM_DISPLAY_VECTOR
15539 && it->ellipsis_p);
15540
15541 /* Save fringe bitmaps in this row. */
15542 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15543 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15544 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15545 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15546
15547 it->left_user_fringe_bitmap = 0;
15548 it->left_user_fringe_face_id = 0;
15549 it->right_user_fringe_bitmap = 0;
15550 it->right_user_fringe_face_id = 0;
15551
15552 /* Maybe set the cursor. */
15553 if (it->w->cursor.vpos < 0
15554 && PT >= MATRIX_ROW_START_CHARPOS (row)
15555 && PT <= MATRIX_ROW_END_CHARPOS (row)
15556 && cursor_row_p (it->w, row))
15557 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15558
15559 /* Highlight trailing whitespace. */
15560 if (!NILP (Vshow_trailing_whitespace))
15561 highlight_trailing_whitespace (it->f, it->glyph_row);
15562
15563 /* Prepare for the next line. This line starts horizontally at (X
15564 HPOS) = (0 0). Vertical positions are incremented. As a
15565 convenience for the caller, IT->glyph_row is set to the next
15566 row to be used. */
15567 it->current_x = it->hpos = 0;
15568 it->current_y += row->height;
15569 ++it->vpos;
15570 ++it->glyph_row;
15571 it->start = it->current;
15572 return row->displays_text_p;
15573 }
15574
15575
15576 \f
15577 /***********************************************************************
15578 Menu Bar
15579 ***********************************************************************/
15580
15581 /* Redisplay the menu bar in the frame for window W.
15582
15583 The menu bar of X frames that don't have X toolkit support is
15584 displayed in a special window W->frame->menu_bar_window.
15585
15586 The menu bar of terminal frames is treated specially as far as
15587 glyph matrices are concerned. Menu bar lines are not part of
15588 windows, so the update is done directly on the frame matrix rows
15589 for the menu bar. */
15590
15591 static void
15592 display_menu_bar (w)
15593 struct window *w;
15594 {
15595 struct frame *f = XFRAME (WINDOW_FRAME (w));
15596 struct it it;
15597 Lisp_Object items;
15598 int i;
15599
15600 /* Don't do all this for graphical frames. */
15601 #ifdef HAVE_NTGUI
15602 if (!NILP (Vwindow_system))
15603 return;
15604 #endif
15605 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15606 if (FRAME_X_P (f))
15607 return;
15608 #endif
15609 #ifdef MAC_OS
15610 if (FRAME_MAC_P (f))
15611 return;
15612 #endif
15613
15614 #ifdef USE_X_TOOLKIT
15615 xassert (!FRAME_WINDOW_P (f));
15616 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15617 it.first_visible_x = 0;
15618 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15619 #else /* not USE_X_TOOLKIT */
15620 if (FRAME_WINDOW_P (f))
15621 {
15622 /* Menu bar lines are displayed in the desired matrix of the
15623 dummy window menu_bar_window. */
15624 struct window *menu_w;
15625 xassert (WINDOWP (f->menu_bar_window));
15626 menu_w = XWINDOW (f->menu_bar_window);
15627 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15628 MENU_FACE_ID);
15629 it.first_visible_x = 0;
15630 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15631 }
15632 else
15633 {
15634 /* This is a TTY frame, i.e. character hpos/vpos are used as
15635 pixel x/y. */
15636 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15637 MENU_FACE_ID);
15638 it.first_visible_x = 0;
15639 it.last_visible_x = FRAME_COLS (f);
15640 }
15641 #endif /* not USE_X_TOOLKIT */
15642
15643 if (! mode_line_inverse_video)
15644 /* Force the menu-bar to be displayed in the default face. */
15645 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15646
15647 /* Clear all rows of the menu bar. */
15648 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15649 {
15650 struct glyph_row *row = it.glyph_row + i;
15651 clear_glyph_row (row);
15652 row->enabled_p = 1;
15653 row->full_width_p = 1;
15654 }
15655
15656 /* Display all items of the menu bar. */
15657 items = FRAME_MENU_BAR_ITEMS (it.f);
15658 for (i = 0; i < XVECTOR (items)->size; i += 4)
15659 {
15660 Lisp_Object string;
15661
15662 /* Stop at nil string. */
15663 string = AREF (items, i + 1);
15664 if (NILP (string))
15665 break;
15666
15667 /* Remember where item was displayed. */
15668 AREF (items, i + 3) = make_number (it.hpos);
15669
15670 /* Display the item, pad with one space. */
15671 if (it.current_x < it.last_visible_x)
15672 display_string (NULL, string, Qnil, 0, 0, &it,
15673 SCHARS (string) + 1, 0, 0, -1);
15674 }
15675
15676 /* Fill out the line with spaces. */
15677 if (it.current_x < it.last_visible_x)
15678 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15679
15680 /* Compute the total height of the lines. */
15681 compute_line_metrics (&it);
15682 }
15683
15684
15685 \f
15686 /***********************************************************************
15687 Mode Line
15688 ***********************************************************************/
15689
15690 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15691 FORCE is non-zero, redisplay mode lines unconditionally.
15692 Otherwise, redisplay only mode lines that are garbaged. Value is
15693 the number of windows whose mode lines were redisplayed. */
15694
15695 static int
15696 redisplay_mode_lines (window, force)
15697 Lisp_Object window;
15698 int force;
15699 {
15700 int nwindows = 0;
15701
15702 while (!NILP (window))
15703 {
15704 struct window *w = XWINDOW (window);
15705
15706 if (WINDOWP (w->hchild))
15707 nwindows += redisplay_mode_lines (w->hchild, force);
15708 else if (WINDOWP (w->vchild))
15709 nwindows += redisplay_mode_lines (w->vchild, force);
15710 else if (force
15711 || FRAME_GARBAGED_P (XFRAME (w->frame))
15712 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15713 {
15714 struct text_pos lpoint;
15715 struct buffer *old = current_buffer;
15716
15717 /* Set the window's buffer for the mode line display. */
15718 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15719 set_buffer_internal_1 (XBUFFER (w->buffer));
15720
15721 /* Point refers normally to the selected window. For any
15722 other window, set up appropriate value. */
15723 if (!EQ (window, selected_window))
15724 {
15725 struct text_pos pt;
15726
15727 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15728 if (CHARPOS (pt) < BEGV)
15729 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15730 else if (CHARPOS (pt) > (ZV - 1))
15731 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15732 else
15733 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15734 }
15735
15736 /* Display mode lines. */
15737 clear_glyph_matrix (w->desired_matrix);
15738 if (display_mode_lines (w))
15739 {
15740 ++nwindows;
15741 w->must_be_updated_p = 1;
15742 }
15743
15744 /* Restore old settings. */
15745 set_buffer_internal_1 (old);
15746 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15747 }
15748
15749 window = w->next;
15750 }
15751
15752 return nwindows;
15753 }
15754
15755
15756 /* Display the mode and/or top line of window W. Value is the number
15757 of mode lines displayed. */
15758
15759 static int
15760 display_mode_lines (w)
15761 struct window *w;
15762 {
15763 Lisp_Object old_selected_window, old_selected_frame;
15764 int n = 0;
15765
15766 old_selected_frame = selected_frame;
15767 selected_frame = w->frame;
15768 old_selected_window = selected_window;
15769 XSETWINDOW (selected_window, w);
15770
15771 /* These will be set while the mode line specs are processed. */
15772 line_number_displayed = 0;
15773 w->column_number_displayed = Qnil;
15774
15775 if (WINDOW_WANTS_MODELINE_P (w))
15776 {
15777 struct window *sel_w = XWINDOW (old_selected_window);
15778
15779 /* Select mode line face based on the real selected window. */
15780 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15781 current_buffer->mode_line_format);
15782 ++n;
15783 }
15784
15785 if (WINDOW_WANTS_HEADER_LINE_P (w))
15786 {
15787 display_mode_line (w, HEADER_LINE_FACE_ID,
15788 current_buffer->header_line_format);
15789 ++n;
15790 }
15791
15792 selected_frame = old_selected_frame;
15793 selected_window = old_selected_window;
15794 return n;
15795 }
15796
15797
15798 /* Display mode or top line of window W. FACE_ID specifies which line
15799 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15800 FORMAT is the mode line format to display. Value is the pixel
15801 height of the mode line displayed. */
15802
15803 static int
15804 display_mode_line (w, face_id, format)
15805 struct window *w;
15806 enum face_id face_id;
15807 Lisp_Object format;
15808 {
15809 struct it it;
15810 struct face *face;
15811 int count = SPECPDL_INDEX ();
15812
15813 init_iterator (&it, w, -1, -1, NULL, face_id);
15814 prepare_desired_row (it.glyph_row);
15815
15816 it.glyph_row->mode_line_p = 1;
15817
15818 if (! mode_line_inverse_video)
15819 /* Force the mode-line to be displayed in the default face. */
15820 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15821
15822 record_unwind_protect (unwind_format_mode_line,
15823 format_mode_line_unwind_data (NULL));
15824
15825 mode_line_target = MODE_LINE_DISPLAY;
15826
15827 /* Temporarily make frame's keyboard the current kboard so that
15828 kboard-local variables in the mode_line_format will get the right
15829 values. */
15830 push_frame_kboard (it.f);
15831 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15832 pop_frame_kboard ();
15833
15834 unbind_to (count, Qnil);
15835
15836 /* Fill up with spaces. */
15837 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15838
15839 compute_line_metrics (&it);
15840 it.glyph_row->full_width_p = 1;
15841 it.glyph_row->continued_p = 0;
15842 it.glyph_row->truncated_on_left_p = 0;
15843 it.glyph_row->truncated_on_right_p = 0;
15844
15845 /* Make a 3D mode-line have a shadow at its right end. */
15846 face = FACE_FROM_ID (it.f, face_id);
15847 extend_face_to_end_of_line (&it);
15848 if (face->box != FACE_NO_BOX)
15849 {
15850 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15851 + it.glyph_row->used[TEXT_AREA] - 1);
15852 last->right_box_line_p = 1;
15853 }
15854
15855 return it.glyph_row->height;
15856 }
15857
15858 /* Contribute ELT to the mode line for window IT->w. How it
15859 translates into text depends on its data type.
15860
15861 IT describes the display environment in which we display, as usual.
15862
15863 DEPTH is the depth in recursion. It is used to prevent
15864 infinite recursion here.
15865
15866 FIELD_WIDTH is the number of characters the display of ELT should
15867 occupy in the mode line, and PRECISION is the maximum number of
15868 characters to display from ELT's representation. See
15869 display_string for details.
15870
15871 Returns the hpos of the end of the text generated by ELT.
15872
15873 PROPS is a property list to add to any string we encounter.
15874
15875 If RISKY is nonzero, remove (disregard) any properties in any string
15876 we encounter, and ignore :eval and :propertize.
15877
15878 The global variable `mode_line_target' determines whether the
15879 output is passed to `store_mode_line_noprop',
15880 `store_mode_line_string', or `display_string'. */
15881
15882 static int
15883 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15884 struct it *it;
15885 int depth;
15886 int field_width, precision;
15887 Lisp_Object elt, props;
15888 int risky;
15889 {
15890 int n = 0, field, prec;
15891 int literal = 0;
15892
15893 tail_recurse:
15894 if (depth > 100)
15895 elt = build_string ("*too-deep*");
15896
15897 depth++;
15898
15899 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15900 {
15901 case Lisp_String:
15902 {
15903 /* A string: output it and check for %-constructs within it. */
15904 unsigned char c;
15905 const unsigned char *this, *lisp_string;
15906
15907 if (!NILP (props) || risky)
15908 {
15909 Lisp_Object oprops, aelt;
15910 oprops = Ftext_properties_at (make_number (0), elt);
15911
15912 /* If the starting string's properties are not what
15913 we want, translate the string. Also, if the string
15914 is risky, do that anyway. */
15915
15916 if (NILP (Fequal (props, oprops)) || risky)
15917 {
15918 /* If the starting string has properties,
15919 merge the specified ones onto the existing ones. */
15920 if (! NILP (oprops) && !risky)
15921 {
15922 Lisp_Object tem;
15923
15924 oprops = Fcopy_sequence (oprops);
15925 tem = props;
15926 while (CONSP (tem))
15927 {
15928 oprops = Fplist_put (oprops, XCAR (tem),
15929 XCAR (XCDR (tem)));
15930 tem = XCDR (XCDR (tem));
15931 }
15932 props = oprops;
15933 }
15934
15935 aelt = Fassoc (elt, mode_line_proptrans_alist);
15936 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15937 {
15938 mode_line_proptrans_alist
15939 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15940 elt = XCAR (aelt);
15941 }
15942 else
15943 {
15944 Lisp_Object tem;
15945
15946 elt = Fcopy_sequence (elt);
15947 Fset_text_properties (make_number (0), Flength (elt),
15948 props, elt);
15949 /* Add this item to mode_line_proptrans_alist. */
15950 mode_line_proptrans_alist
15951 = Fcons (Fcons (elt, props),
15952 mode_line_proptrans_alist);
15953 /* Truncate mode_line_proptrans_alist
15954 to at most 50 elements. */
15955 tem = Fnthcdr (make_number (50),
15956 mode_line_proptrans_alist);
15957 if (! NILP (tem))
15958 XSETCDR (tem, Qnil);
15959 }
15960 }
15961 }
15962
15963 this = SDATA (elt);
15964 lisp_string = this;
15965
15966 if (literal)
15967 {
15968 prec = precision - n;
15969 switch (mode_line_target)
15970 {
15971 case MODE_LINE_NOPROP:
15972 case MODE_LINE_TITLE:
15973 n += store_mode_line_noprop (SDATA (elt), -1, prec);
15974 break;
15975 case MODE_LINE_STRING:
15976 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15977 break;
15978 case MODE_LINE_DISPLAY:
15979 n += display_string (NULL, elt, Qnil, 0, 0, it,
15980 0, prec, 0, STRING_MULTIBYTE (elt));
15981 break;
15982 }
15983
15984 break;
15985 }
15986
15987 while ((precision <= 0 || n < precision)
15988 && *this
15989 && (mode_line_target != MODE_LINE_DISPLAY
15990 || it->current_x < it->last_visible_x))
15991 {
15992 const unsigned char *last = this;
15993
15994 /* Advance to end of string or next format specifier. */
15995 while ((c = *this++) != '\0' && c != '%')
15996 ;
15997
15998 if (this - 1 != last)
15999 {
16000 int nchars, nbytes;
16001
16002 /* Output to end of string or up to '%'. Field width
16003 is length of string. Don't output more than
16004 PRECISION allows us. */
16005 --this;
16006
16007 prec = c_string_width (last, this - last, precision - n,
16008 &nchars, &nbytes);
16009
16010 switch (mode_line_target)
16011 {
16012 case MODE_LINE_NOPROP:
16013 case MODE_LINE_TITLE:
16014 n += store_mode_line_noprop (last, 0, prec);
16015 break;
16016 case MODE_LINE_STRING:
16017 {
16018 int bytepos = last - lisp_string;
16019 int charpos = string_byte_to_char (elt, bytepos);
16020 int endpos = (precision <= 0
16021 ? string_byte_to_char (elt,
16022 this - lisp_string)
16023 : charpos + nchars);
16024
16025 n += store_mode_line_string (NULL,
16026 Fsubstring (elt, make_number (charpos),
16027 make_number (endpos)),
16028 0, 0, 0, Qnil);
16029 }
16030 break;
16031 case MODE_LINE_DISPLAY:
16032 {
16033 int bytepos = last - lisp_string;
16034 int charpos = string_byte_to_char (elt, bytepos);
16035 n += display_string (NULL, elt, Qnil, 0, charpos,
16036 it, 0, prec, 0,
16037 STRING_MULTIBYTE (elt));
16038 }
16039 break;
16040 }
16041 }
16042 else /* c == '%' */
16043 {
16044 const unsigned char *percent_position = this;
16045
16046 /* Get the specified minimum width. Zero means
16047 don't pad. */
16048 field = 0;
16049 while ((c = *this++) >= '0' && c <= '9')
16050 field = field * 10 + c - '0';
16051
16052 /* Don't pad beyond the total padding allowed. */
16053 if (field_width - n > 0 && field > field_width - n)
16054 field = field_width - n;
16055
16056 /* Note that either PRECISION <= 0 or N < PRECISION. */
16057 prec = precision - n;
16058
16059 if (c == 'M')
16060 n += display_mode_element (it, depth, field, prec,
16061 Vglobal_mode_string, props,
16062 risky);
16063 else if (c != 0)
16064 {
16065 int multibyte;
16066 int bytepos, charpos;
16067 unsigned char *spec;
16068
16069 bytepos = percent_position - lisp_string;
16070 charpos = (STRING_MULTIBYTE (elt)
16071 ? string_byte_to_char (elt, bytepos)
16072 : bytepos);
16073
16074 spec
16075 = decode_mode_spec (it->w, c, field, prec, &multibyte);
16076
16077 switch (mode_line_target)
16078 {
16079 case MODE_LINE_NOPROP:
16080 case MODE_LINE_TITLE:
16081 n += store_mode_line_noprop (spec, field, prec);
16082 break;
16083 case MODE_LINE_STRING:
16084 {
16085 int len = strlen (spec);
16086 Lisp_Object tem = make_string (spec, len);
16087 props = Ftext_properties_at (make_number (charpos), elt);
16088 /* Should only keep face property in props */
16089 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
16090 }
16091 break;
16092 case MODE_LINE_DISPLAY:
16093 {
16094 int nglyphs_before, nwritten;
16095
16096 nglyphs_before = it->glyph_row->used[TEXT_AREA];
16097 nwritten = display_string (spec, Qnil, elt,
16098 charpos, 0, it,
16099 field, prec, 0,
16100 multibyte);
16101
16102 /* Assign to the glyphs written above the
16103 string where the `%x' came from, position
16104 of the `%'. */
16105 if (nwritten > 0)
16106 {
16107 struct glyph *glyph
16108 = (it->glyph_row->glyphs[TEXT_AREA]
16109 + nglyphs_before);
16110 int i;
16111
16112 for (i = 0; i < nwritten; ++i)
16113 {
16114 glyph[i].object = elt;
16115 glyph[i].charpos = charpos;
16116 }
16117
16118 n += nwritten;
16119 }
16120 }
16121 break;
16122 }
16123 }
16124 else /* c == 0 */
16125 break;
16126 }
16127 }
16128 }
16129 break;
16130
16131 case Lisp_Symbol:
16132 /* A symbol: process the value of the symbol recursively
16133 as if it appeared here directly. Avoid error if symbol void.
16134 Special case: if value of symbol is a string, output the string
16135 literally. */
16136 {
16137 register Lisp_Object tem;
16138
16139 /* If the variable is not marked as risky to set
16140 then its contents are risky to use. */
16141 if (NILP (Fget (elt, Qrisky_local_variable)))
16142 risky = 1;
16143
16144 tem = Fboundp (elt);
16145 if (!NILP (tem))
16146 {
16147 tem = Fsymbol_value (elt);
16148 /* If value is a string, output that string literally:
16149 don't check for % within it. */
16150 if (STRINGP (tem))
16151 literal = 1;
16152
16153 if (!EQ (tem, elt))
16154 {
16155 /* Give up right away for nil or t. */
16156 elt = tem;
16157 goto tail_recurse;
16158 }
16159 }
16160 }
16161 break;
16162
16163 case Lisp_Cons:
16164 {
16165 register Lisp_Object car, tem;
16166
16167 /* A cons cell: five distinct cases.
16168 If first element is :eval or :propertize, do something special.
16169 If first element is a string or a cons, process all the elements
16170 and effectively concatenate them.
16171 If first element is a negative number, truncate displaying cdr to
16172 at most that many characters. If positive, pad (with spaces)
16173 to at least that many characters.
16174 If first element is a symbol, process the cadr or caddr recursively
16175 according to whether the symbol's value is non-nil or nil. */
16176 car = XCAR (elt);
16177 if (EQ (car, QCeval))
16178 {
16179 /* An element of the form (:eval FORM) means evaluate FORM
16180 and use the result as mode line elements. */
16181
16182 if (risky)
16183 break;
16184
16185 if (CONSP (XCDR (elt)))
16186 {
16187 Lisp_Object spec;
16188 spec = safe_eval (XCAR (XCDR (elt)));
16189 n += display_mode_element (it, depth, field_width - n,
16190 precision - n, spec, props,
16191 risky);
16192 }
16193 }
16194 else if (EQ (car, QCpropertize))
16195 {
16196 /* An element of the form (:propertize ELT PROPS...)
16197 means display ELT but applying properties PROPS. */
16198
16199 if (risky)
16200 break;
16201
16202 if (CONSP (XCDR (elt)))
16203 n += display_mode_element (it, depth, field_width - n,
16204 precision - n, XCAR (XCDR (elt)),
16205 XCDR (XCDR (elt)), risky);
16206 }
16207 else if (SYMBOLP (car))
16208 {
16209 tem = Fboundp (car);
16210 elt = XCDR (elt);
16211 if (!CONSP (elt))
16212 goto invalid;
16213 /* elt is now the cdr, and we know it is a cons cell.
16214 Use its car if CAR has a non-nil value. */
16215 if (!NILP (tem))
16216 {
16217 tem = Fsymbol_value (car);
16218 if (!NILP (tem))
16219 {
16220 elt = XCAR (elt);
16221 goto tail_recurse;
16222 }
16223 }
16224 /* Symbol's value is nil (or symbol is unbound)
16225 Get the cddr of the original list
16226 and if possible find the caddr and use that. */
16227 elt = XCDR (elt);
16228 if (NILP (elt))
16229 break;
16230 else if (!CONSP (elt))
16231 goto invalid;
16232 elt = XCAR (elt);
16233 goto tail_recurse;
16234 }
16235 else if (INTEGERP (car))
16236 {
16237 register int lim = XINT (car);
16238 elt = XCDR (elt);
16239 if (lim < 0)
16240 {
16241 /* Negative int means reduce maximum width. */
16242 if (precision <= 0)
16243 precision = -lim;
16244 else
16245 precision = min (precision, -lim);
16246 }
16247 else if (lim > 0)
16248 {
16249 /* Padding specified. Don't let it be more than
16250 current maximum. */
16251 if (precision > 0)
16252 lim = min (precision, lim);
16253
16254 /* If that's more padding than already wanted, queue it.
16255 But don't reduce padding already specified even if
16256 that is beyond the current truncation point. */
16257 field_width = max (lim, field_width);
16258 }
16259 goto tail_recurse;
16260 }
16261 else if (STRINGP (car) || CONSP (car))
16262 {
16263 register int limit = 50;
16264 /* Limit is to protect against circular lists. */
16265 while (CONSP (elt)
16266 && --limit > 0
16267 && (precision <= 0 || n < precision))
16268 {
16269 n += display_mode_element (it, depth,
16270 /* Do padding only after the last
16271 element in the list. */
16272 (! CONSP (XCDR (elt))
16273 ? field_width - n
16274 : 0),
16275 precision - n, XCAR (elt),
16276 props, risky);
16277 elt = XCDR (elt);
16278 }
16279 }
16280 }
16281 break;
16282
16283 default:
16284 invalid:
16285 elt = build_string ("*invalid*");
16286 goto tail_recurse;
16287 }
16288
16289 /* Pad to FIELD_WIDTH. */
16290 if (field_width > 0 && n < field_width)
16291 {
16292 switch (mode_line_target)
16293 {
16294 case MODE_LINE_NOPROP:
16295 case MODE_LINE_TITLE:
16296 n += store_mode_line_noprop ("", field_width - n, 0);
16297 break;
16298 case MODE_LINE_STRING:
16299 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
16300 break;
16301 case MODE_LINE_DISPLAY:
16302 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
16303 0, 0, 0);
16304 break;
16305 }
16306 }
16307
16308 return n;
16309 }
16310
16311 /* Store a mode-line string element in mode_line_string_list.
16312
16313 If STRING is non-null, display that C string. Otherwise, the Lisp
16314 string LISP_STRING is displayed.
16315
16316 FIELD_WIDTH is the minimum number of output glyphs to produce.
16317 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16318 with spaces. FIELD_WIDTH <= 0 means don't pad.
16319
16320 PRECISION is the maximum number of characters to output from
16321 STRING. PRECISION <= 0 means don't truncate the string.
16322
16323 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
16324 properties to the string.
16325
16326 PROPS are the properties to add to the string.
16327 The mode_line_string_face face property is always added to the string.
16328 */
16329
16330 static int
16331 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
16332 char *string;
16333 Lisp_Object lisp_string;
16334 int copy_string;
16335 int field_width;
16336 int precision;
16337 Lisp_Object props;
16338 {
16339 int len;
16340 int n = 0;
16341
16342 if (string != NULL)
16343 {
16344 len = strlen (string);
16345 if (precision > 0 && len > precision)
16346 len = precision;
16347 lisp_string = make_string (string, len);
16348 if (NILP (props))
16349 props = mode_line_string_face_prop;
16350 else if (!NILP (mode_line_string_face))
16351 {
16352 Lisp_Object face = Fplist_get (props, Qface);
16353 props = Fcopy_sequence (props);
16354 if (NILP (face))
16355 face = mode_line_string_face;
16356 else
16357 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16358 props = Fplist_put (props, Qface, face);
16359 }
16360 Fadd_text_properties (make_number (0), make_number (len),
16361 props, lisp_string);
16362 }
16363 else
16364 {
16365 len = XFASTINT (Flength (lisp_string));
16366 if (precision > 0 && len > precision)
16367 {
16368 len = precision;
16369 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
16370 precision = -1;
16371 }
16372 if (!NILP (mode_line_string_face))
16373 {
16374 Lisp_Object face;
16375 if (NILP (props))
16376 props = Ftext_properties_at (make_number (0), lisp_string);
16377 face = Fplist_get (props, Qface);
16378 if (NILP (face))
16379 face = mode_line_string_face;
16380 else
16381 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16382 props = Fcons (Qface, Fcons (face, Qnil));
16383 if (copy_string)
16384 lisp_string = Fcopy_sequence (lisp_string);
16385 }
16386 if (!NILP (props))
16387 Fadd_text_properties (make_number (0), make_number (len),
16388 props, lisp_string);
16389 }
16390
16391 if (len > 0)
16392 {
16393 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16394 n += len;
16395 }
16396
16397 if (field_width > len)
16398 {
16399 field_width -= len;
16400 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
16401 if (!NILP (props))
16402 Fadd_text_properties (make_number (0), make_number (field_width),
16403 props, lisp_string);
16404 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16405 n += field_width;
16406 }
16407
16408 return n;
16409 }
16410
16411
16412 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
16413 1, 4, 0,
16414 doc: /* Format a string out of a mode line format specification.
16415 First arg FORMAT specifies the mode line format (see `mode-line-format'
16416 for details) to use.
16417
16418 Optional second arg FACE specifies the face property to put
16419 on all characters for which no face is specified.
16420 t means whatever face the window's mode line currently uses
16421 \(either `mode-line' or `mode-line-inactive', depending).
16422 nil means the default is no face property.
16423 If FACE is an integer, the value string has no text properties.
16424
16425 Optional third and fourth args WINDOW and BUFFER specify the window
16426 and buffer to use as the context for the formatting (defaults
16427 are the selected window and the window's buffer). */)
16428 (format, face, window, buffer)
16429 Lisp_Object format, face, window, buffer;
16430 {
16431 struct it it;
16432 int len;
16433 struct window *w;
16434 struct buffer *old_buffer = NULL;
16435 int face_id = -1;
16436 int no_props = INTEGERP (face);
16437 int count = SPECPDL_INDEX ();
16438 Lisp_Object str;
16439 int string_start = 0;
16440
16441 if (NILP (window))
16442 window = selected_window;
16443 CHECK_WINDOW (window);
16444 w = XWINDOW (window);
16445
16446 if (NILP (buffer))
16447 buffer = w->buffer;
16448 CHECK_BUFFER (buffer);
16449
16450 if (NILP (format))
16451 return build_string ("");
16452
16453 if (no_props)
16454 face = Qnil;
16455
16456 if (!NILP (face))
16457 {
16458 if (EQ (face, Qt))
16459 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
16460 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
16461 }
16462
16463 if (face_id < 0)
16464 face_id = DEFAULT_FACE_ID;
16465
16466 if (XBUFFER (buffer) != current_buffer)
16467 old_buffer = current_buffer;
16468
16469 record_unwind_protect (unwind_format_mode_line,
16470 format_mode_line_unwind_data (old_buffer));
16471
16472 if (old_buffer)
16473 set_buffer_internal_1 (XBUFFER (buffer));
16474
16475 init_iterator (&it, w, -1, -1, NULL, face_id);
16476
16477 if (no_props)
16478 {
16479 mode_line_target = MODE_LINE_NOPROP;
16480 mode_line_string_face_prop = Qnil;
16481 mode_line_string_list = Qnil;
16482 string_start = MODE_LINE_NOPROP_LEN (0);
16483 }
16484 else
16485 {
16486 mode_line_target = MODE_LINE_STRING;
16487 mode_line_string_list = Qnil;
16488 mode_line_string_face = face;
16489 mode_line_string_face_prop
16490 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
16491 }
16492
16493 push_frame_kboard (it.f);
16494 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16495 pop_frame_kboard ();
16496
16497 if (no_props)
16498 {
16499 len = MODE_LINE_NOPROP_LEN (string_start);
16500 str = make_string (mode_line_noprop_buf + string_start, len);
16501 }
16502 else
16503 {
16504 mode_line_string_list = Fnreverse (mode_line_string_list);
16505 str = Fmapconcat (intern ("identity"), mode_line_string_list,
16506 make_string ("", 0));
16507 }
16508
16509 unbind_to (count, Qnil);
16510 return str;
16511 }
16512
16513 /* Write a null-terminated, right justified decimal representation of
16514 the positive integer D to BUF using a minimal field width WIDTH. */
16515
16516 static void
16517 pint2str (buf, width, d)
16518 register char *buf;
16519 register int width;
16520 register int d;
16521 {
16522 register char *p = buf;
16523
16524 if (d <= 0)
16525 *p++ = '0';
16526 else
16527 {
16528 while (d > 0)
16529 {
16530 *p++ = d % 10 + '0';
16531 d /= 10;
16532 }
16533 }
16534
16535 for (width -= (int) (p - buf); width > 0; --width)
16536 *p++ = ' ';
16537 *p-- = '\0';
16538 while (p > buf)
16539 {
16540 d = *buf;
16541 *buf++ = *p;
16542 *p-- = d;
16543 }
16544 }
16545
16546 /* Write a null-terminated, right justified decimal and "human
16547 readable" representation of the nonnegative integer D to BUF using
16548 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16549
16550 static const char power_letter[] =
16551 {
16552 0, /* not used */
16553 'k', /* kilo */
16554 'M', /* mega */
16555 'G', /* giga */
16556 'T', /* tera */
16557 'P', /* peta */
16558 'E', /* exa */
16559 'Z', /* zetta */
16560 'Y' /* yotta */
16561 };
16562
16563 static void
16564 pint2hrstr (buf, width, d)
16565 char *buf;
16566 int width;
16567 int d;
16568 {
16569 /* We aim to represent the nonnegative integer D as
16570 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16571 int quotient = d;
16572 int remainder = 0;
16573 /* -1 means: do not use TENTHS. */
16574 int tenths = -1;
16575 int exponent = 0;
16576
16577 /* Length of QUOTIENT.TENTHS as a string. */
16578 int length;
16579
16580 char * psuffix;
16581 char * p;
16582
16583 if (1000 <= quotient)
16584 {
16585 /* Scale to the appropriate EXPONENT. */
16586 do
16587 {
16588 remainder = quotient % 1000;
16589 quotient /= 1000;
16590 exponent++;
16591 }
16592 while (1000 <= quotient);
16593
16594 /* Round to nearest and decide whether to use TENTHS or not. */
16595 if (quotient <= 9)
16596 {
16597 tenths = remainder / 100;
16598 if (50 <= remainder % 100)
16599 {
16600 if (tenths < 9)
16601 tenths++;
16602 else
16603 {
16604 quotient++;
16605 if (quotient == 10)
16606 tenths = -1;
16607 else
16608 tenths = 0;
16609 }
16610 }
16611 }
16612 else
16613 if (500 <= remainder)
16614 {
16615 if (quotient < 999)
16616 quotient++;
16617 else
16618 {
16619 quotient = 1;
16620 exponent++;
16621 tenths = 0;
16622 }
16623 }
16624 }
16625
16626 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16627 if (tenths == -1 && quotient <= 99)
16628 if (quotient <= 9)
16629 length = 1;
16630 else
16631 length = 2;
16632 else
16633 length = 3;
16634 p = psuffix = buf + max (width, length);
16635
16636 /* Print EXPONENT. */
16637 if (exponent)
16638 *psuffix++ = power_letter[exponent];
16639 *psuffix = '\0';
16640
16641 /* Print TENTHS. */
16642 if (tenths >= 0)
16643 {
16644 *--p = '0' + tenths;
16645 *--p = '.';
16646 }
16647
16648 /* Print QUOTIENT. */
16649 do
16650 {
16651 int digit = quotient % 10;
16652 *--p = '0' + digit;
16653 }
16654 while ((quotient /= 10) != 0);
16655
16656 /* Print leading spaces. */
16657 while (buf < p)
16658 *--p = ' ';
16659 }
16660
16661 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16662 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16663 type of CODING_SYSTEM. Return updated pointer into BUF. */
16664
16665 static unsigned char invalid_eol_type[] = "(*invalid*)";
16666
16667 static char *
16668 decode_mode_spec_coding (coding_system, buf, eol_flag)
16669 Lisp_Object coding_system;
16670 register char *buf;
16671 int eol_flag;
16672 {
16673 Lisp_Object val;
16674 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16675 const unsigned char *eol_str;
16676 int eol_str_len;
16677 /* The EOL conversion we are using. */
16678 Lisp_Object eoltype;
16679
16680 val = Fget (coding_system, Qcoding_system);
16681 eoltype = Qnil;
16682
16683 if (!VECTORP (val)) /* Not yet decided. */
16684 {
16685 if (multibyte)
16686 *buf++ = '-';
16687 if (eol_flag)
16688 eoltype = eol_mnemonic_undecided;
16689 /* Don't mention EOL conversion if it isn't decided. */
16690 }
16691 else
16692 {
16693 Lisp_Object eolvalue;
16694
16695 eolvalue = Fget (coding_system, Qeol_type);
16696
16697 if (multibyte)
16698 *buf++ = XFASTINT (AREF (val, 1));
16699
16700 if (eol_flag)
16701 {
16702 /* The EOL conversion that is normal on this system. */
16703
16704 if (NILP (eolvalue)) /* Not yet decided. */
16705 eoltype = eol_mnemonic_undecided;
16706 else if (VECTORP (eolvalue)) /* Not yet decided. */
16707 eoltype = eol_mnemonic_undecided;
16708 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16709 eoltype = (XFASTINT (eolvalue) == 0
16710 ? eol_mnemonic_unix
16711 : (XFASTINT (eolvalue) == 1
16712 ? eol_mnemonic_dos : eol_mnemonic_mac));
16713 }
16714 }
16715
16716 if (eol_flag)
16717 {
16718 /* Mention the EOL conversion if it is not the usual one. */
16719 if (STRINGP (eoltype))
16720 {
16721 eol_str = SDATA (eoltype);
16722 eol_str_len = SBYTES (eoltype);
16723 }
16724 else if (INTEGERP (eoltype)
16725 && CHAR_VALID_P (XINT (eoltype), 0))
16726 {
16727 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16728 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16729 eol_str = tmp;
16730 }
16731 else
16732 {
16733 eol_str = invalid_eol_type;
16734 eol_str_len = sizeof (invalid_eol_type) - 1;
16735 }
16736 bcopy (eol_str, buf, eol_str_len);
16737 buf += eol_str_len;
16738 }
16739
16740 return buf;
16741 }
16742
16743 /* Return a string for the output of a mode line %-spec for window W,
16744 generated by character C. PRECISION >= 0 means don't return a
16745 string longer than that value. FIELD_WIDTH > 0 means pad the
16746 string returned with spaces to that value. Return 1 in *MULTIBYTE
16747 if the result is multibyte text.
16748
16749 Note we operate on the current buffer for most purposes,
16750 the exception being w->base_line_pos. */
16751
16752 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16753
16754 static char *
16755 decode_mode_spec (w, c, field_width, precision, multibyte)
16756 struct window *w;
16757 register int c;
16758 int field_width, precision;
16759 int *multibyte;
16760 {
16761 Lisp_Object obj;
16762 struct frame *f = XFRAME (WINDOW_FRAME (w));
16763 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16764 struct buffer *b = current_buffer;
16765
16766 obj = Qnil;
16767 *multibyte = 0;
16768
16769 switch (c)
16770 {
16771 case '*':
16772 if (!NILP (b->read_only))
16773 return "%";
16774 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16775 return "*";
16776 return "-";
16777
16778 case '+':
16779 /* This differs from %* only for a modified read-only buffer. */
16780 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16781 return "*";
16782 if (!NILP (b->read_only))
16783 return "%";
16784 return "-";
16785
16786 case '&':
16787 /* This differs from %* in ignoring read-only-ness. */
16788 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16789 return "*";
16790 return "-";
16791
16792 case '%':
16793 return "%";
16794
16795 case '[':
16796 {
16797 int i;
16798 char *p;
16799
16800 if (command_loop_level > 5)
16801 return "[[[... ";
16802 p = decode_mode_spec_buf;
16803 for (i = 0; i < command_loop_level; i++)
16804 *p++ = '[';
16805 *p = 0;
16806 return decode_mode_spec_buf;
16807 }
16808
16809 case ']':
16810 {
16811 int i;
16812 char *p;
16813
16814 if (command_loop_level > 5)
16815 return " ...]]]";
16816 p = decode_mode_spec_buf;
16817 for (i = 0; i < command_loop_level; i++)
16818 *p++ = ']';
16819 *p = 0;
16820 return decode_mode_spec_buf;
16821 }
16822
16823 case '-':
16824 {
16825 register int i;
16826
16827 /* Let lots_of_dashes be a string of infinite length. */
16828 if (mode_line_target == MODE_LINE_NOPROP ||
16829 mode_line_target == MODE_LINE_STRING)
16830 return "--";
16831 if (field_width <= 0
16832 || field_width > sizeof (lots_of_dashes))
16833 {
16834 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16835 decode_mode_spec_buf[i] = '-';
16836 decode_mode_spec_buf[i] = '\0';
16837 return decode_mode_spec_buf;
16838 }
16839 else
16840 return lots_of_dashes;
16841 }
16842
16843 case 'b':
16844 obj = b->name;
16845 break;
16846
16847 case 'c':
16848 {
16849 int col = (int) current_column (); /* iftc */
16850 w->column_number_displayed = make_number (col);
16851 pint2str (decode_mode_spec_buf, field_width, col);
16852 return decode_mode_spec_buf;
16853 }
16854
16855 case 'F':
16856 /* %F displays the frame name. */
16857 if (!NILP (f->title))
16858 return (char *) SDATA (f->title);
16859 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16860 return (char *) SDATA (f->name);
16861 return "Emacs";
16862
16863 case 'f':
16864 obj = b->filename;
16865 break;
16866
16867 case 'i':
16868 {
16869 int size = ZV - BEGV;
16870 pint2str (decode_mode_spec_buf, field_width, size);
16871 return decode_mode_spec_buf;
16872 }
16873
16874 case 'I':
16875 {
16876 int size = ZV - BEGV;
16877 pint2hrstr (decode_mode_spec_buf, field_width, size);
16878 return decode_mode_spec_buf;
16879 }
16880
16881 case 'l':
16882 {
16883 int startpos = XMARKER (w->start)->charpos;
16884 int startpos_byte = marker_byte_position (w->start);
16885 int line, linepos, linepos_byte, topline;
16886 int nlines, junk;
16887 int height = WINDOW_TOTAL_LINES (w);
16888
16889 /* If we decided that this buffer isn't suitable for line numbers,
16890 don't forget that too fast. */
16891 if (EQ (w->base_line_pos, w->buffer))
16892 goto no_value;
16893 /* But do forget it, if the window shows a different buffer now. */
16894 else if (BUFFERP (w->base_line_pos))
16895 w->base_line_pos = Qnil;
16896
16897 /* If the buffer is very big, don't waste time. */
16898 if (INTEGERP (Vline_number_display_limit)
16899 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16900 {
16901 w->base_line_pos = Qnil;
16902 w->base_line_number = Qnil;
16903 goto no_value;
16904 }
16905
16906 if (!NILP (w->base_line_number)
16907 && !NILP (w->base_line_pos)
16908 && XFASTINT (w->base_line_pos) <= startpos)
16909 {
16910 line = XFASTINT (w->base_line_number);
16911 linepos = XFASTINT (w->base_line_pos);
16912 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16913 }
16914 else
16915 {
16916 line = 1;
16917 linepos = BUF_BEGV (b);
16918 linepos_byte = BUF_BEGV_BYTE (b);
16919 }
16920
16921 /* Count lines from base line to window start position. */
16922 nlines = display_count_lines (linepos, linepos_byte,
16923 startpos_byte,
16924 startpos, &junk);
16925
16926 topline = nlines + line;
16927
16928 /* Determine a new base line, if the old one is too close
16929 or too far away, or if we did not have one.
16930 "Too close" means it's plausible a scroll-down would
16931 go back past it. */
16932 if (startpos == BUF_BEGV (b))
16933 {
16934 w->base_line_number = make_number (topline);
16935 w->base_line_pos = make_number (BUF_BEGV (b));
16936 }
16937 else if (nlines < height + 25 || nlines > height * 3 + 50
16938 || linepos == BUF_BEGV (b))
16939 {
16940 int limit = BUF_BEGV (b);
16941 int limit_byte = BUF_BEGV_BYTE (b);
16942 int position;
16943 int distance = (height * 2 + 30) * line_number_display_limit_width;
16944
16945 if (startpos - distance > limit)
16946 {
16947 limit = startpos - distance;
16948 limit_byte = CHAR_TO_BYTE (limit);
16949 }
16950
16951 nlines = display_count_lines (startpos, startpos_byte,
16952 limit_byte,
16953 - (height * 2 + 30),
16954 &position);
16955 /* If we couldn't find the lines we wanted within
16956 line_number_display_limit_width chars per line,
16957 give up on line numbers for this window. */
16958 if (position == limit_byte && limit == startpos - distance)
16959 {
16960 w->base_line_pos = w->buffer;
16961 w->base_line_number = Qnil;
16962 goto no_value;
16963 }
16964
16965 w->base_line_number = make_number (topline - nlines);
16966 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16967 }
16968
16969 /* Now count lines from the start pos to point. */
16970 nlines = display_count_lines (startpos, startpos_byte,
16971 PT_BYTE, PT, &junk);
16972
16973 /* Record that we did display the line number. */
16974 line_number_displayed = 1;
16975
16976 /* Make the string to show. */
16977 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16978 return decode_mode_spec_buf;
16979 no_value:
16980 {
16981 char* p = decode_mode_spec_buf;
16982 int pad = field_width - 2;
16983 while (pad-- > 0)
16984 *p++ = ' ';
16985 *p++ = '?';
16986 *p++ = '?';
16987 *p = '\0';
16988 return decode_mode_spec_buf;
16989 }
16990 }
16991 break;
16992
16993 case 'm':
16994 obj = b->mode_name;
16995 break;
16996
16997 case 'n':
16998 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16999 return " Narrow";
17000 break;
17001
17002 case 'p':
17003 {
17004 int pos = marker_position (w->start);
17005 int total = BUF_ZV (b) - BUF_BEGV (b);
17006
17007 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
17008 {
17009 if (pos <= BUF_BEGV (b))
17010 return "All";
17011 else
17012 return "Bottom";
17013 }
17014 else if (pos <= BUF_BEGV (b))
17015 return "Top";
17016 else
17017 {
17018 if (total > 1000000)
17019 /* Do it differently for a large value, to avoid overflow. */
17020 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17021 else
17022 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
17023 /* We can't normally display a 3-digit number,
17024 so get us a 2-digit number that is close. */
17025 if (total == 100)
17026 total = 99;
17027 sprintf (decode_mode_spec_buf, "%2d%%", total);
17028 return decode_mode_spec_buf;
17029 }
17030 }
17031
17032 /* Display percentage of size above the bottom of the screen. */
17033 case 'P':
17034 {
17035 int toppos = marker_position (w->start);
17036 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
17037 int total = BUF_ZV (b) - BUF_BEGV (b);
17038
17039 if (botpos >= BUF_ZV (b))
17040 {
17041 if (toppos <= BUF_BEGV (b))
17042 return "All";
17043 else
17044 return "Bottom";
17045 }
17046 else
17047 {
17048 if (total > 1000000)
17049 /* Do it differently for a large value, to avoid overflow. */
17050 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
17051 else
17052 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
17053 /* We can't normally display a 3-digit number,
17054 so get us a 2-digit number that is close. */
17055 if (total == 100)
17056 total = 99;
17057 if (toppos <= BUF_BEGV (b))
17058 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
17059 else
17060 sprintf (decode_mode_spec_buf, "%2d%%", total);
17061 return decode_mode_spec_buf;
17062 }
17063 }
17064
17065 case 's':
17066 /* status of process */
17067 obj = Fget_buffer_process (Fcurrent_buffer ());
17068 if (NILP (obj))
17069 return "no process";
17070 #ifdef subprocesses
17071 obj = Fsymbol_name (Fprocess_status (obj));
17072 #endif
17073 break;
17074
17075 case 't': /* indicate TEXT or BINARY */
17076 #ifdef MODE_LINE_BINARY_TEXT
17077 return MODE_LINE_BINARY_TEXT (b);
17078 #else
17079 return "T";
17080 #endif
17081
17082 case 'z':
17083 /* coding-system (not including end-of-line format) */
17084 case 'Z':
17085 /* coding-system (including end-of-line type) */
17086 {
17087 int eol_flag = (c == 'Z');
17088 char *p = decode_mode_spec_buf;
17089
17090 if (! FRAME_WINDOW_P (f))
17091 {
17092 /* No need to mention EOL here--the terminal never needs
17093 to do EOL conversion. */
17094 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
17095 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
17096 }
17097 p = decode_mode_spec_coding (b->buffer_file_coding_system,
17098 p, eol_flag);
17099
17100 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
17101 #ifdef subprocesses
17102 obj = Fget_buffer_process (Fcurrent_buffer ());
17103 if (PROCESSP (obj))
17104 {
17105 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
17106 p, eol_flag);
17107 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
17108 p, eol_flag);
17109 }
17110 #endif /* subprocesses */
17111 #endif /* 0 */
17112 *p = 0;
17113 return decode_mode_spec_buf;
17114 }
17115 }
17116
17117 if (STRINGP (obj))
17118 {
17119 *multibyte = STRING_MULTIBYTE (obj);
17120 return (char *) SDATA (obj);
17121 }
17122 else
17123 return "";
17124 }
17125
17126
17127 /* Count up to COUNT lines starting from START / START_BYTE.
17128 But don't go beyond LIMIT_BYTE.
17129 Return the number of lines thus found (always nonnegative).
17130
17131 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
17132
17133 static int
17134 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
17135 int start, start_byte, limit_byte, count;
17136 int *byte_pos_ptr;
17137 {
17138 register unsigned char *cursor;
17139 unsigned char *base;
17140
17141 register int ceiling;
17142 register unsigned char *ceiling_addr;
17143 int orig_count = count;
17144
17145 /* If we are not in selective display mode,
17146 check only for newlines. */
17147 int selective_display = (!NILP (current_buffer->selective_display)
17148 && !INTEGERP (current_buffer->selective_display));
17149
17150 if (count > 0)
17151 {
17152 while (start_byte < limit_byte)
17153 {
17154 ceiling = BUFFER_CEILING_OF (start_byte);
17155 ceiling = min (limit_byte - 1, ceiling);
17156 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
17157 base = (cursor = BYTE_POS_ADDR (start_byte));
17158 while (1)
17159 {
17160 if (selective_display)
17161 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
17162 ;
17163 else
17164 while (*cursor != '\n' && ++cursor != ceiling_addr)
17165 ;
17166
17167 if (cursor != ceiling_addr)
17168 {
17169 if (--count == 0)
17170 {
17171 start_byte += cursor - base + 1;
17172 *byte_pos_ptr = start_byte;
17173 return orig_count;
17174 }
17175 else
17176 if (++cursor == ceiling_addr)
17177 break;
17178 }
17179 else
17180 break;
17181 }
17182 start_byte += cursor - base;
17183 }
17184 }
17185 else
17186 {
17187 while (start_byte > limit_byte)
17188 {
17189 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
17190 ceiling = max (limit_byte, ceiling);
17191 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
17192 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
17193 while (1)
17194 {
17195 if (selective_display)
17196 while (--cursor != ceiling_addr
17197 && *cursor != '\n' && *cursor != 015)
17198 ;
17199 else
17200 while (--cursor != ceiling_addr && *cursor != '\n')
17201 ;
17202
17203 if (cursor != ceiling_addr)
17204 {
17205 if (++count == 0)
17206 {
17207 start_byte += cursor - base + 1;
17208 *byte_pos_ptr = start_byte;
17209 /* When scanning backwards, we should
17210 not count the newline posterior to which we stop. */
17211 return - orig_count - 1;
17212 }
17213 }
17214 else
17215 break;
17216 }
17217 /* Here we add 1 to compensate for the last decrement
17218 of CURSOR, which took it past the valid range. */
17219 start_byte += cursor - base + 1;
17220 }
17221 }
17222
17223 *byte_pos_ptr = limit_byte;
17224
17225 if (count < 0)
17226 return - orig_count + count;
17227 return orig_count - count;
17228
17229 }
17230
17231
17232 \f
17233 /***********************************************************************
17234 Displaying strings
17235 ***********************************************************************/
17236
17237 /* Display a NUL-terminated string, starting with index START.
17238
17239 If STRING is non-null, display that C string. Otherwise, the Lisp
17240 string LISP_STRING is displayed.
17241
17242 If FACE_STRING is not nil, FACE_STRING_POS is a position in
17243 FACE_STRING. Display STRING or LISP_STRING with the face at
17244 FACE_STRING_POS in FACE_STRING:
17245
17246 Display the string in the environment given by IT, but use the
17247 standard display table, temporarily.
17248
17249 FIELD_WIDTH is the minimum number of output glyphs to produce.
17250 If STRING has fewer characters than FIELD_WIDTH, pad to the right
17251 with spaces. If STRING has more characters, more than FIELD_WIDTH
17252 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
17253
17254 PRECISION is the maximum number of characters to output from
17255 STRING. PRECISION < 0 means don't truncate the string.
17256
17257 This is roughly equivalent to printf format specifiers:
17258
17259 FIELD_WIDTH PRECISION PRINTF
17260 ----------------------------------------
17261 -1 -1 %s
17262 -1 10 %.10s
17263 10 -1 %10s
17264 20 10 %20.10s
17265
17266 MULTIBYTE zero means do not display multibyte chars, > 0 means do
17267 display them, and < 0 means obey the current buffer's value of
17268 enable_multibyte_characters.
17269
17270 Value is the number of glyphs produced. */
17271
17272 static int
17273 display_string (string, lisp_string, face_string, face_string_pos,
17274 start, it, field_width, precision, max_x, multibyte)
17275 unsigned char *string;
17276 Lisp_Object lisp_string;
17277 Lisp_Object face_string;
17278 int face_string_pos;
17279 int start;
17280 struct it *it;
17281 int field_width, precision, max_x;
17282 int multibyte;
17283 {
17284 int hpos_at_start = it->hpos;
17285 int saved_face_id = it->face_id;
17286 struct glyph_row *row = it->glyph_row;
17287
17288 /* Initialize the iterator IT for iteration over STRING beginning
17289 with index START. */
17290 reseat_to_string (it, string, lisp_string, start,
17291 precision, field_width, multibyte);
17292
17293 /* If displaying STRING, set up the face of the iterator
17294 from LISP_STRING, if that's given. */
17295 if (STRINGP (face_string))
17296 {
17297 int endptr;
17298 struct face *face;
17299
17300 it->face_id
17301 = face_at_string_position (it->w, face_string, face_string_pos,
17302 0, it->region_beg_charpos,
17303 it->region_end_charpos,
17304 &endptr, it->base_face_id, 0);
17305 face = FACE_FROM_ID (it->f, it->face_id);
17306 it->face_box_p = face->box != FACE_NO_BOX;
17307 }
17308
17309 /* Set max_x to the maximum allowed X position. Don't let it go
17310 beyond the right edge of the window. */
17311 if (max_x <= 0)
17312 max_x = it->last_visible_x;
17313 else
17314 max_x = min (max_x, it->last_visible_x);
17315
17316 /* Skip over display elements that are not visible. because IT->w is
17317 hscrolled. */
17318 if (it->current_x < it->first_visible_x)
17319 move_it_in_display_line_to (it, 100000, it->first_visible_x,
17320 MOVE_TO_POS | MOVE_TO_X);
17321
17322 row->ascent = it->max_ascent;
17323 row->height = it->max_ascent + it->max_descent;
17324 row->phys_ascent = it->max_phys_ascent;
17325 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17326 row->extra_line_spacing = it->max_extra_line_spacing;
17327
17328 /* This condition is for the case that we are called with current_x
17329 past last_visible_x. */
17330 while (it->current_x < max_x)
17331 {
17332 int x_before, x, n_glyphs_before, i, nglyphs;
17333
17334 /* Get the next display element. */
17335 if (!get_next_display_element (it))
17336 break;
17337
17338 /* Produce glyphs. */
17339 x_before = it->current_x;
17340 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
17341 PRODUCE_GLYPHS (it);
17342
17343 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
17344 i = 0;
17345 x = x_before;
17346 while (i < nglyphs)
17347 {
17348 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17349
17350 if (!it->truncate_lines_p
17351 && x + glyph->pixel_width > max_x)
17352 {
17353 /* End of continued line or max_x reached. */
17354 if (CHAR_GLYPH_PADDING_P (*glyph))
17355 {
17356 /* A wide character is unbreakable. */
17357 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
17358 it->current_x = x_before;
17359 }
17360 else
17361 {
17362 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
17363 it->current_x = x;
17364 }
17365 break;
17366 }
17367 else if (x + glyph->pixel_width > it->first_visible_x)
17368 {
17369 /* Glyph is at least partially visible. */
17370 ++it->hpos;
17371 if (x < it->first_visible_x)
17372 it->glyph_row->x = x - it->first_visible_x;
17373 }
17374 else
17375 {
17376 /* Glyph is off the left margin of the display area.
17377 Should not happen. */
17378 abort ();
17379 }
17380
17381 row->ascent = max (row->ascent, it->max_ascent);
17382 row->height = max (row->height, it->max_ascent + it->max_descent);
17383 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17384 row->phys_height = max (row->phys_height,
17385 it->max_phys_ascent + it->max_phys_descent);
17386 row->extra_line_spacing = max (row->extra_line_spacing,
17387 it->max_extra_line_spacing);
17388 x += glyph->pixel_width;
17389 ++i;
17390 }
17391
17392 /* Stop if max_x reached. */
17393 if (i < nglyphs)
17394 break;
17395
17396 /* Stop at line ends. */
17397 if (ITERATOR_AT_END_OF_LINE_P (it))
17398 {
17399 it->continuation_lines_width = 0;
17400 break;
17401 }
17402
17403 set_iterator_to_next (it, 1);
17404
17405 /* Stop if truncating at the right edge. */
17406 if (it->truncate_lines_p
17407 && it->current_x >= it->last_visible_x)
17408 {
17409 /* Add truncation mark, but don't do it if the line is
17410 truncated at a padding space. */
17411 if (IT_CHARPOS (*it) < it->string_nchars)
17412 {
17413 if (!FRAME_WINDOW_P (it->f))
17414 {
17415 int i, n;
17416
17417 if (it->current_x > it->last_visible_x)
17418 {
17419 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17420 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17421 break;
17422 for (n = row->used[TEXT_AREA]; i < n; ++i)
17423 {
17424 row->used[TEXT_AREA] = i;
17425 produce_special_glyphs (it, IT_TRUNCATION);
17426 }
17427 }
17428 produce_special_glyphs (it, IT_TRUNCATION);
17429 }
17430 it->glyph_row->truncated_on_right_p = 1;
17431 }
17432 break;
17433 }
17434 }
17435
17436 /* Maybe insert a truncation at the left. */
17437 if (it->first_visible_x
17438 && IT_CHARPOS (*it) > 0)
17439 {
17440 if (!FRAME_WINDOW_P (it->f))
17441 insert_left_trunc_glyphs (it);
17442 it->glyph_row->truncated_on_left_p = 1;
17443 }
17444
17445 it->face_id = saved_face_id;
17446
17447 /* Value is number of columns displayed. */
17448 return it->hpos - hpos_at_start;
17449 }
17450
17451
17452 \f
17453 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17454 appears as an element of LIST or as the car of an element of LIST.
17455 If PROPVAL is a list, compare each element against LIST in that
17456 way, and return 1/2 if any element of PROPVAL is found in LIST.
17457 Otherwise return 0. This function cannot quit.
17458 The return value is 2 if the text is invisible but with an ellipsis
17459 and 1 if it's invisible and without an ellipsis. */
17460
17461 int
17462 invisible_p (propval, list)
17463 register Lisp_Object propval;
17464 Lisp_Object list;
17465 {
17466 register Lisp_Object tail, proptail;
17467
17468 for (tail = list; CONSP (tail); tail = XCDR (tail))
17469 {
17470 register Lisp_Object tem;
17471 tem = XCAR (tail);
17472 if (EQ (propval, tem))
17473 return 1;
17474 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17475 return NILP (XCDR (tem)) ? 1 : 2;
17476 }
17477
17478 if (CONSP (propval))
17479 {
17480 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17481 {
17482 Lisp_Object propelt;
17483 propelt = XCAR (proptail);
17484 for (tail = list; CONSP (tail); tail = XCDR (tail))
17485 {
17486 register Lisp_Object tem;
17487 tem = XCAR (tail);
17488 if (EQ (propelt, tem))
17489 return 1;
17490 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17491 return NILP (XCDR (tem)) ? 1 : 2;
17492 }
17493 }
17494 }
17495
17496 return 0;
17497 }
17498
17499 /* Calculate a width or height in pixels from a specification using
17500 the following elements:
17501
17502 SPEC ::=
17503 NUM - a (fractional) multiple of the default font width/height
17504 (NUM) - specifies exactly NUM pixels
17505 UNIT - a fixed number of pixels, see below.
17506 ELEMENT - size of a display element in pixels, see below.
17507 (NUM . SPEC) - equals NUM * SPEC
17508 (+ SPEC SPEC ...) - add pixel values
17509 (- SPEC SPEC ...) - subtract pixel values
17510 (- SPEC) - negate pixel value
17511
17512 NUM ::=
17513 INT or FLOAT - a number constant
17514 SYMBOL - use symbol's (buffer local) variable binding.
17515
17516 UNIT ::=
17517 in - pixels per inch *)
17518 mm - pixels per 1/1000 meter *)
17519 cm - pixels per 1/100 meter *)
17520 width - width of current font in pixels.
17521 height - height of current font in pixels.
17522
17523 *) using the ratio(s) defined in display-pixels-per-inch.
17524
17525 ELEMENT ::=
17526
17527 left-fringe - left fringe width in pixels
17528 right-fringe - right fringe width in pixels
17529
17530 left-margin - left margin width in pixels
17531 right-margin - right margin width in pixels
17532
17533 scroll-bar - scroll-bar area width in pixels
17534
17535 Examples:
17536
17537 Pixels corresponding to 5 inches:
17538 (5 . in)
17539
17540 Total width of non-text areas on left side of window (if scroll-bar is on left):
17541 '(space :width (+ left-fringe left-margin scroll-bar))
17542
17543 Align to first text column (in header line):
17544 '(space :align-to 0)
17545
17546 Align to middle of text area minus half the width of variable `my-image'
17547 containing a loaded image:
17548 '(space :align-to (0.5 . (- text my-image)))
17549
17550 Width of left margin minus width of 1 character in the default font:
17551 '(space :width (- left-margin 1))
17552
17553 Width of left margin minus width of 2 characters in the current font:
17554 '(space :width (- left-margin (2 . width)))
17555
17556 Center 1 character over left-margin (in header line):
17557 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17558
17559 Different ways to express width of left fringe plus left margin minus one pixel:
17560 '(space :width (- (+ left-fringe left-margin) (1)))
17561 '(space :width (+ left-fringe left-margin (- (1))))
17562 '(space :width (+ left-fringe left-margin (-1)))
17563
17564 */
17565
17566 #define NUMVAL(X) \
17567 ((INTEGERP (X) || FLOATP (X)) \
17568 ? XFLOATINT (X) \
17569 : - 1)
17570
17571 int
17572 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17573 double *res;
17574 struct it *it;
17575 Lisp_Object prop;
17576 void *font;
17577 int width_p, *align_to;
17578 {
17579 double pixels;
17580
17581 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17582 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17583
17584 if (NILP (prop))
17585 return OK_PIXELS (0);
17586
17587 if (SYMBOLP (prop))
17588 {
17589 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17590 {
17591 char *unit = SDATA (SYMBOL_NAME (prop));
17592
17593 if (unit[0] == 'i' && unit[1] == 'n')
17594 pixels = 1.0;
17595 else if (unit[0] == 'm' && unit[1] == 'm')
17596 pixels = 25.4;
17597 else if (unit[0] == 'c' && unit[1] == 'm')
17598 pixels = 2.54;
17599 else
17600 pixels = 0;
17601 if (pixels > 0)
17602 {
17603 double ppi;
17604 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17605 || (CONSP (Vdisplay_pixels_per_inch)
17606 && (ppi = (width_p
17607 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17608 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17609 ppi > 0)))
17610 return OK_PIXELS (ppi / pixels);
17611
17612 return 0;
17613 }
17614 }
17615
17616 #ifdef HAVE_WINDOW_SYSTEM
17617 if (EQ (prop, Qheight))
17618 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17619 if (EQ (prop, Qwidth))
17620 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17621 #else
17622 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17623 return OK_PIXELS (1);
17624 #endif
17625
17626 if (EQ (prop, Qtext))
17627 return OK_PIXELS (width_p
17628 ? window_box_width (it->w, TEXT_AREA)
17629 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17630
17631 if (align_to && *align_to < 0)
17632 {
17633 *res = 0;
17634 if (EQ (prop, Qleft))
17635 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17636 if (EQ (prop, Qright))
17637 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17638 if (EQ (prop, Qcenter))
17639 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17640 + window_box_width (it->w, TEXT_AREA) / 2);
17641 if (EQ (prop, Qleft_fringe))
17642 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17643 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17644 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17645 if (EQ (prop, Qright_fringe))
17646 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17647 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17648 : window_box_right_offset (it->w, TEXT_AREA));
17649 if (EQ (prop, Qleft_margin))
17650 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17651 if (EQ (prop, Qright_margin))
17652 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17653 if (EQ (prop, Qscroll_bar))
17654 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17655 ? 0
17656 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17657 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17658 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17659 : 0)));
17660 }
17661 else
17662 {
17663 if (EQ (prop, Qleft_fringe))
17664 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17665 if (EQ (prop, Qright_fringe))
17666 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17667 if (EQ (prop, Qleft_margin))
17668 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17669 if (EQ (prop, Qright_margin))
17670 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17671 if (EQ (prop, Qscroll_bar))
17672 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17673 }
17674
17675 prop = Fbuffer_local_value (prop, it->w->buffer);
17676 }
17677
17678 if (INTEGERP (prop) || FLOATP (prop))
17679 {
17680 int base_unit = (width_p
17681 ? FRAME_COLUMN_WIDTH (it->f)
17682 : FRAME_LINE_HEIGHT (it->f));
17683 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17684 }
17685
17686 if (CONSP (prop))
17687 {
17688 Lisp_Object car = XCAR (prop);
17689 Lisp_Object cdr = XCDR (prop);
17690
17691 if (SYMBOLP (car))
17692 {
17693 #ifdef HAVE_WINDOW_SYSTEM
17694 if (valid_image_p (prop))
17695 {
17696 int id = lookup_image (it->f, prop);
17697 struct image *img = IMAGE_FROM_ID (it->f, id);
17698
17699 return OK_PIXELS (width_p ? img->width : img->height);
17700 }
17701 #endif
17702 if (EQ (car, Qplus) || EQ (car, Qminus))
17703 {
17704 int first = 1;
17705 double px;
17706
17707 pixels = 0;
17708 while (CONSP (cdr))
17709 {
17710 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17711 font, width_p, align_to))
17712 return 0;
17713 if (first)
17714 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17715 else
17716 pixels += px;
17717 cdr = XCDR (cdr);
17718 }
17719 if (EQ (car, Qminus))
17720 pixels = -pixels;
17721 return OK_PIXELS (pixels);
17722 }
17723
17724 car = Fbuffer_local_value (car, it->w->buffer);
17725 }
17726
17727 if (INTEGERP (car) || FLOATP (car))
17728 {
17729 double fact;
17730 pixels = XFLOATINT (car);
17731 if (NILP (cdr))
17732 return OK_PIXELS (pixels);
17733 if (calc_pixel_width_or_height (&fact, it, cdr,
17734 font, width_p, align_to))
17735 return OK_PIXELS (pixels * fact);
17736 return 0;
17737 }
17738
17739 return 0;
17740 }
17741
17742 return 0;
17743 }
17744
17745 \f
17746 /***********************************************************************
17747 Glyph Display
17748 ***********************************************************************/
17749
17750 #ifdef HAVE_WINDOW_SYSTEM
17751
17752 #if GLYPH_DEBUG
17753
17754 void
17755 dump_glyph_string (s)
17756 struct glyph_string *s;
17757 {
17758 fprintf (stderr, "glyph string\n");
17759 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17760 s->x, s->y, s->width, s->height);
17761 fprintf (stderr, " ybase = %d\n", s->ybase);
17762 fprintf (stderr, " hl = %d\n", s->hl);
17763 fprintf (stderr, " left overhang = %d, right = %d\n",
17764 s->left_overhang, s->right_overhang);
17765 fprintf (stderr, " nchars = %d\n", s->nchars);
17766 fprintf (stderr, " extends to end of line = %d\n",
17767 s->extends_to_end_of_line_p);
17768 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17769 fprintf (stderr, " bg width = %d\n", s->background_width);
17770 }
17771
17772 #endif /* GLYPH_DEBUG */
17773
17774 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17775 of XChar2b structures for S; it can't be allocated in
17776 init_glyph_string because it must be allocated via `alloca'. W
17777 is the window on which S is drawn. ROW and AREA are the glyph row
17778 and area within the row from which S is constructed. START is the
17779 index of the first glyph structure covered by S. HL is a
17780 face-override for drawing S. */
17781
17782 #ifdef HAVE_NTGUI
17783 #define OPTIONAL_HDC(hdc) hdc,
17784 #define DECLARE_HDC(hdc) HDC hdc;
17785 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17786 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17787 #endif
17788
17789 #ifndef OPTIONAL_HDC
17790 #define OPTIONAL_HDC(hdc)
17791 #define DECLARE_HDC(hdc)
17792 #define ALLOCATE_HDC(hdc, f)
17793 #define RELEASE_HDC(hdc, f)
17794 #endif
17795
17796 static void
17797 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17798 struct glyph_string *s;
17799 DECLARE_HDC (hdc)
17800 XChar2b *char2b;
17801 struct window *w;
17802 struct glyph_row *row;
17803 enum glyph_row_area area;
17804 int start;
17805 enum draw_glyphs_face hl;
17806 {
17807 bzero (s, sizeof *s);
17808 s->w = w;
17809 s->f = XFRAME (w->frame);
17810 #ifdef HAVE_NTGUI
17811 s->hdc = hdc;
17812 #endif
17813 s->display = FRAME_X_DISPLAY (s->f);
17814 s->window = FRAME_X_WINDOW (s->f);
17815 s->char2b = char2b;
17816 s->hl = hl;
17817 s->row = row;
17818 s->area = area;
17819 s->first_glyph = row->glyphs[area] + start;
17820 s->height = row->height;
17821 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17822
17823 /* Display the internal border below the tool-bar window. */
17824 if (WINDOWP (s->f->tool_bar_window)
17825 && s->w == XWINDOW (s->f->tool_bar_window))
17826 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17827
17828 s->ybase = s->y + row->ascent;
17829 }
17830
17831
17832 /* Append the list of glyph strings with head H and tail T to the list
17833 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17834
17835 static INLINE void
17836 append_glyph_string_lists (head, tail, h, t)
17837 struct glyph_string **head, **tail;
17838 struct glyph_string *h, *t;
17839 {
17840 if (h)
17841 {
17842 if (*head)
17843 (*tail)->next = h;
17844 else
17845 *head = h;
17846 h->prev = *tail;
17847 *tail = t;
17848 }
17849 }
17850
17851
17852 /* Prepend the list of glyph strings with head H and tail T to the
17853 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17854 result. */
17855
17856 static INLINE void
17857 prepend_glyph_string_lists (head, tail, h, t)
17858 struct glyph_string **head, **tail;
17859 struct glyph_string *h, *t;
17860 {
17861 if (h)
17862 {
17863 if (*head)
17864 (*head)->prev = t;
17865 else
17866 *tail = t;
17867 t->next = *head;
17868 *head = h;
17869 }
17870 }
17871
17872
17873 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17874 Set *HEAD and *TAIL to the resulting list. */
17875
17876 static INLINE void
17877 append_glyph_string (head, tail, s)
17878 struct glyph_string **head, **tail;
17879 struct glyph_string *s;
17880 {
17881 s->next = s->prev = NULL;
17882 append_glyph_string_lists (head, tail, s, s);
17883 }
17884
17885
17886 /* Get face and two-byte form of character glyph GLYPH on frame F.
17887 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17888 a pointer to a realized face that is ready for display. */
17889
17890 static INLINE struct face *
17891 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17892 struct frame *f;
17893 struct glyph *glyph;
17894 XChar2b *char2b;
17895 int *two_byte_p;
17896 {
17897 struct face *face;
17898
17899 xassert (glyph->type == CHAR_GLYPH);
17900 face = FACE_FROM_ID (f, glyph->face_id);
17901
17902 if (two_byte_p)
17903 *two_byte_p = 0;
17904
17905 if (!glyph->multibyte_p)
17906 {
17907 /* Unibyte case. We don't have to encode, but we have to make
17908 sure to use a face suitable for unibyte. */
17909 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17910 }
17911 else if (glyph->u.ch < 128
17912 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17913 {
17914 /* Case of ASCII in a face known to fit ASCII. */
17915 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17916 }
17917 else
17918 {
17919 int c1, c2, charset;
17920
17921 /* Split characters into bytes. If c2 is -1 afterwards, C is
17922 really a one-byte character so that byte1 is zero. */
17923 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17924 if (c2 > 0)
17925 STORE_XCHAR2B (char2b, c1, c2);
17926 else
17927 STORE_XCHAR2B (char2b, 0, c1);
17928
17929 /* Maybe encode the character in *CHAR2B. */
17930 if (charset != CHARSET_ASCII)
17931 {
17932 struct font_info *font_info
17933 = FONT_INFO_FROM_ID (f, face->font_info_id);
17934 if (font_info)
17935 glyph->font_type
17936 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17937 }
17938 }
17939
17940 /* Make sure X resources of the face are allocated. */
17941 xassert (face != NULL);
17942 PREPARE_FACE_FOR_DISPLAY (f, face);
17943 return face;
17944 }
17945
17946
17947 /* Fill glyph string S with composition components specified by S->cmp.
17948
17949 FACES is an array of faces for all components of this composition.
17950 S->gidx is the index of the first component for S.
17951 OVERLAPS_P non-zero means S should draw the foreground only, and
17952 use its physical height for clipping.
17953
17954 Value is the index of a component not in S. */
17955
17956 static int
17957 fill_composite_glyph_string (s, faces, overlaps_p)
17958 struct glyph_string *s;
17959 struct face **faces;
17960 int overlaps_p;
17961 {
17962 int i;
17963
17964 xassert (s);
17965
17966 s->for_overlaps_p = overlaps_p;
17967
17968 s->face = faces[s->gidx];
17969 s->font = s->face->font;
17970 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17971
17972 /* For all glyphs of this composition, starting at the offset
17973 S->gidx, until we reach the end of the definition or encounter a
17974 glyph that requires the different face, add it to S. */
17975 ++s->nchars;
17976 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17977 ++s->nchars;
17978
17979 /* All glyph strings for the same composition has the same width,
17980 i.e. the width set for the first component of the composition. */
17981
17982 s->width = s->first_glyph->pixel_width;
17983
17984 /* If the specified font could not be loaded, use the frame's
17985 default font, but record the fact that we couldn't load it in
17986 the glyph string so that we can draw rectangles for the
17987 characters of the glyph string. */
17988 if (s->font == NULL)
17989 {
17990 s->font_not_found_p = 1;
17991 s->font = FRAME_FONT (s->f);
17992 }
17993
17994 /* Adjust base line for subscript/superscript text. */
17995 s->ybase += s->first_glyph->voffset;
17996
17997 xassert (s->face && s->face->gc);
17998
17999 /* This glyph string must always be drawn with 16-bit functions. */
18000 s->two_byte_p = 1;
18001
18002 return s->gidx + s->nchars;
18003 }
18004
18005
18006 /* Fill glyph string S from a sequence of character glyphs.
18007
18008 FACE_ID is the face id of the string. START is the index of the
18009 first glyph to consider, END is the index of the last + 1.
18010 OVERLAPS_P non-zero means S should draw the foreground only, and
18011 use its physical height for clipping.
18012
18013 Value is the index of the first glyph not in S. */
18014
18015 static int
18016 fill_glyph_string (s, face_id, start, end, overlaps_p)
18017 struct glyph_string *s;
18018 int face_id;
18019 int start, end, overlaps_p;
18020 {
18021 struct glyph *glyph, *last;
18022 int voffset;
18023 int glyph_not_available_p;
18024
18025 xassert (s->f == XFRAME (s->w->frame));
18026 xassert (s->nchars == 0);
18027 xassert (start >= 0 && end > start);
18028
18029 s->for_overlaps_p = overlaps_p,
18030 glyph = s->row->glyphs[s->area] + start;
18031 last = s->row->glyphs[s->area] + end;
18032 voffset = glyph->voffset;
18033
18034 glyph_not_available_p = glyph->glyph_not_available_p;
18035
18036 while (glyph < last
18037 && glyph->type == CHAR_GLYPH
18038 && glyph->voffset == voffset
18039 /* Same face id implies same font, nowadays. */
18040 && glyph->face_id == face_id
18041 && glyph->glyph_not_available_p == glyph_not_available_p)
18042 {
18043 int two_byte_p;
18044
18045 s->face = get_glyph_face_and_encoding (s->f, glyph,
18046 s->char2b + s->nchars,
18047 &two_byte_p);
18048 s->two_byte_p = two_byte_p;
18049 ++s->nchars;
18050 xassert (s->nchars <= end - start);
18051 s->width += glyph->pixel_width;
18052 ++glyph;
18053 }
18054
18055 s->font = s->face->font;
18056 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18057
18058 /* If the specified font could not be loaded, use the frame's font,
18059 but record the fact that we couldn't load it in
18060 S->font_not_found_p so that we can draw rectangles for the
18061 characters of the glyph string. */
18062 if (s->font == NULL || glyph_not_available_p)
18063 {
18064 s->font_not_found_p = 1;
18065 s->font = FRAME_FONT (s->f);
18066 }
18067
18068 /* Adjust base line for subscript/superscript text. */
18069 s->ybase += voffset;
18070
18071 xassert (s->face && s->face->gc);
18072 return glyph - s->row->glyphs[s->area];
18073 }
18074
18075
18076 /* Fill glyph string S from image glyph S->first_glyph. */
18077
18078 static void
18079 fill_image_glyph_string (s)
18080 struct glyph_string *s;
18081 {
18082 xassert (s->first_glyph->type == IMAGE_GLYPH);
18083 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
18084 xassert (s->img);
18085 s->slice = s->first_glyph->slice;
18086 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
18087 s->font = s->face->font;
18088 s->width = s->first_glyph->pixel_width;
18089
18090 /* Adjust base line for subscript/superscript text. */
18091 s->ybase += s->first_glyph->voffset;
18092 }
18093
18094
18095 /* Fill glyph string S from a sequence of stretch glyphs.
18096
18097 ROW is the glyph row in which the glyphs are found, AREA is the
18098 area within the row. START is the index of the first glyph to
18099 consider, END is the index of the last + 1.
18100
18101 Value is the index of the first glyph not in S. */
18102
18103 static int
18104 fill_stretch_glyph_string (s, row, area, start, end)
18105 struct glyph_string *s;
18106 struct glyph_row *row;
18107 enum glyph_row_area area;
18108 int start, end;
18109 {
18110 struct glyph *glyph, *last;
18111 int voffset, face_id;
18112
18113 xassert (s->first_glyph->type == STRETCH_GLYPH);
18114
18115 glyph = s->row->glyphs[s->area] + start;
18116 last = s->row->glyphs[s->area] + end;
18117 face_id = glyph->face_id;
18118 s->face = FACE_FROM_ID (s->f, face_id);
18119 s->font = s->face->font;
18120 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
18121 s->width = glyph->pixel_width;
18122 voffset = glyph->voffset;
18123
18124 for (++glyph;
18125 (glyph < last
18126 && glyph->type == STRETCH_GLYPH
18127 && glyph->voffset == voffset
18128 && glyph->face_id == face_id);
18129 ++glyph)
18130 s->width += glyph->pixel_width;
18131
18132 /* Adjust base line for subscript/superscript text. */
18133 s->ybase += voffset;
18134
18135 /* The case that face->gc == 0 is handled when drawing the glyph
18136 string by calling PREPARE_FACE_FOR_DISPLAY. */
18137 xassert (s->face);
18138 return glyph - s->row->glyphs[s->area];
18139 }
18140
18141
18142 /* EXPORT for RIF:
18143 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
18144 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
18145 assumed to be zero. */
18146
18147 void
18148 x_get_glyph_overhangs (glyph, f, left, right)
18149 struct glyph *glyph;
18150 struct frame *f;
18151 int *left, *right;
18152 {
18153 *left = *right = 0;
18154
18155 if (glyph->type == CHAR_GLYPH)
18156 {
18157 XFontStruct *font;
18158 struct face *face;
18159 struct font_info *font_info;
18160 XChar2b char2b;
18161 XCharStruct *pcm;
18162
18163 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
18164 font = face->font;
18165 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
18166 if (font /* ++KFS: Should this be font_info ? */
18167 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
18168 {
18169 if (pcm->rbearing > pcm->width)
18170 *right = pcm->rbearing - pcm->width;
18171 if (pcm->lbearing < 0)
18172 *left = -pcm->lbearing;
18173 }
18174 }
18175 }
18176
18177
18178 /* Return the index of the first glyph preceding glyph string S that
18179 is overwritten by S because of S's left overhang. Value is -1
18180 if no glyphs are overwritten. */
18181
18182 static int
18183 left_overwritten (s)
18184 struct glyph_string *s;
18185 {
18186 int k;
18187
18188 if (s->left_overhang)
18189 {
18190 int x = 0, i;
18191 struct glyph *glyphs = s->row->glyphs[s->area];
18192 int first = s->first_glyph - glyphs;
18193
18194 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
18195 x -= glyphs[i].pixel_width;
18196
18197 k = i + 1;
18198 }
18199 else
18200 k = -1;
18201
18202 return k;
18203 }
18204
18205
18206 /* Return the index of the first glyph preceding glyph string S that
18207 is overwriting S because of its right overhang. Value is -1 if no
18208 glyph in front of S overwrites S. */
18209
18210 static int
18211 left_overwriting (s)
18212 struct glyph_string *s;
18213 {
18214 int i, k, x;
18215 struct glyph *glyphs = s->row->glyphs[s->area];
18216 int first = s->first_glyph - glyphs;
18217
18218 k = -1;
18219 x = 0;
18220 for (i = first - 1; i >= 0; --i)
18221 {
18222 int left, right;
18223 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18224 if (x + right > 0)
18225 k = i;
18226 x -= glyphs[i].pixel_width;
18227 }
18228
18229 return k;
18230 }
18231
18232
18233 /* Return the index of the last glyph following glyph string S that is
18234 not overwritten by S because of S's right overhang. Value is -1 if
18235 no such glyph is found. */
18236
18237 static int
18238 right_overwritten (s)
18239 struct glyph_string *s;
18240 {
18241 int k = -1;
18242
18243 if (s->right_overhang)
18244 {
18245 int x = 0, i;
18246 struct glyph *glyphs = s->row->glyphs[s->area];
18247 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18248 int end = s->row->used[s->area];
18249
18250 for (i = first; i < end && s->right_overhang > x; ++i)
18251 x += glyphs[i].pixel_width;
18252
18253 k = i;
18254 }
18255
18256 return k;
18257 }
18258
18259
18260 /* Return the index of the last glyph following glyph string S that
18261 overwrites S because of its left overhang. Value is negative
18262 if no such glyph is found. */
18263
18264 static int
18265 right_overwriting (s)
18266 struct glyph_string *s;
18267 {
18268 int i, k, x;
18269 int end = s->row->used[s->area];
18270 struct glyph *glyphs = s->row->glyphs[s->area];
18271 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18272
18273 k = -1;
18274 x = 0;
18275 for (i = first; i < end; ++i)
18276 {
18277 int left, right;
18278 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18279 if (x - left < 0)
18280 k = i;
18281 x += glyphs[i].pixel_width;
18282 }
18283
18284 return k;
18285 }
18286
18287
18288 /* Get face and two-byte form of character C in face FACE_ID on frame
18289 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18290 means we want to display multibyte text. DISPLAY_P non-zero means
18291 make sure that X resources for the face returned are allocated.
18292 Value is a pointer to a realized face that is ready for display if
18293 DISPLAY_P is non-zero. */
18294
18295 static INLINE struct face *
18296 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
18297 struct frame *f;
18298 int c, face_id;
18299 XChar2b *char2b;
18300 int multibyte_p, display_p;
18301 {
18302 struct face *face = FACE_FROM_ID (f, face_id);
18303
18304 if (!multibyte_p)
18305 {
18306 /* Unibyte case. We don't have to encode, but we have to make
18307 sure to use a face suitable for unibyte. */
18308 STORE_XCHAR2B (char2b, 0, c);
18309 face_id = FACE_FOR_CHAR (f, face, c);
18310 face = FACE_FROM_ID (f, face_id);
18311 }
18312 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
18313 {
18314 /* Case of ASCII in a face known to fit ASCII. */
18315 STORE_XCHAR2B (char2b, 0, c);
18316 }
18317 else
18318 {
18319 int c1, c2, charset;
18320
18321 /* Split characters into bytes. If c2 is -1 afterwards, C is
18322 really a one-byte character so that byte1 is zero. */
18323 SPLIT_CHAR (c, charset, c1, c2);
18324 if (c2 > 0)
18325 STORE_XCHAR2B (char2b, c1, c2);
18326 else
18327 STORE_XCHAR2B (char2b, 0, c1);
18328
18329 /* Maybe encode the character in *CHAR2B. */
18330 if (face->font != NULL)
18331 {
18332 struct font_info *font_info
18333 = FONT_INFO_FROM_ID (f, face->font_info_id);
18334 if (font_info)
18335 rif->encode_char (c, char2b, font_info, 0);
18336 }
18337 }
18338
18339 /* Make sure X resources of the face are allocated. */
18340 #ifdef HAVE_X_WINDOWS
18341 if (display_p)
18342 #endif
18343 {
18344 xassert (face != NULL);
18345 PREPARE_FACE_FOR_DISPLAY (f, face);
18346 }
18347
18348 return face;
18349 }
18350
18351
18352 /* Set background width of glyph string S. START is the index of the
18353 first glyph following S. LAST_X is the right-most x-position + 1
18354 in the drawing area. */
18355
18356 static INLINE void
18357 set_glyph_string_background_width (s, start, last_x)
18358 struct glyph_string *s;
18359 int start;
18360 int last_x;
18361 {
18362 /* If the face of this glyph string has to be drawn to the end of
18363 the drawing area, set S->extends_to_end_of_line_p. */
18364 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
18365
18366 if (start == s->row->used[s->area]
18367 && s->area == TEXT_AREA
18368 && ((s->hl == DRAW_NORMAL_TEXT
18369 && (s->row->fill_line_p
18370 || s->face->background != default_face->background
18371 || s->face->stipple != default_face->stipple
18372 || s->row->mouse_face_p))
18373 || s->hl == DRAW_MOUSE_FACE
18374 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
18375 && s->row->fill_line_p)))
18376 s->extends_to_end_of_line_p = 1;
18377
18378 /* If S extends its face to the end of the line, set its
18379 background_width to the distance to the right edge of the drawing
18380 area. */
18381 if (s->extends_to_end_of_line_p)
18382 s->background_width = last_x - s->x + 1;
18383 else
18384 s->background_width = s->width;
18385 }
18386
18387
18388 /* Compute overhangs and x-positions for glyph string S and its
18389 predecessors, or successors. X is the starting x-position for S.
18390 BACKWARD_P non-zero means process predecessors. */
18391
18392 static void
18393 compute_overhangs_and_x (s, x, backward_p)
18394 struct glyph_string *s;
18395 int x;
18396 int backward_p;
18397 {
18398 if (backward_p)
18399 {
18400 while (s)
18401 {
18402 if (rif->compute_glyph_string_overhangs)
18403 rif->compute_glyph_string_overhangs (s);
18404 x -= s->width;
18405 s->x = x;
18406 s = s->prev;
18407 }
18408 }
18409 else
18410 {
18411 while (s)
18412 {
18413 if (rif->compute_glyph_string_overhangs)
18414 rif->compute_glyph_string_overhangs (s);
18415 s->x = x;
18416 x += s->width;
18417 s = s->next;
18418 }
18419 }
18420 }
18421
18422
18423
18424 /* The following macros are only called from draw_glyphs below.
18425 They reference the following parameters of that function directly:
18426 `w', `row', `area', and `overlap_p'
18427 as well as the following local variables:
18428 `s', `f', and `hdc' (in W32) */
18429
18430 #ifdef HAVE_NTGUI
18431 /* On W32, silently add local `hdc' variable to argument list of
18432 init_glyph_string. */
18433 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18434 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
18435 #else
18436 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18437 init_glyph_string (s, char2b, w, row, area, start, hl)
18438 #endif
18439
18440 /* Add a glyph string for a stretch glyph to the list of strings
18441 between HEAD and TAIL. START is the index of the stretch glyph in
18442 row area AREA of glyph row ROW. END is the index of the last glyph
18443 in that glyph row area. X is the current output position assigned
18444 to the new glyph string constructed. HL overrides that face of the
18445 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18446 is the right-most x-position of the drawing area. */
18447
18448 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
18449 and below -- keep them on one line. */
18450 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18451 do \
18452 { \
18453 s = (struct glyph_string *) alloca (sizeof *s); \
18454 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18455 START = fill_stretch_glyph_string (s, row, area, START, END); \
18456 append_glyph_string (&HEAD, &TAIL, s); \
18457 s->x = (X); \
18458 } \
18459 while (0)
18460
18461
18462 /* Add a glyph string for an image glyph to the list of strings
18463 between HEAD and TAIL. START is the index of the image glyph in
18464 row area AREA of glyph row ROW. END is the index of the last glyph
18465 in that glyph row area. X is the current output position assigned
18466 to the new glyph string constructed. HL overrides that face of the
18467 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18468 is the right-most x-position of the drawing area. */
18469
18470 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18471 do \
18472 { \
18473 s = (struct glyph_string *) alloca (sizeof *s); \
18474 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18475 fill_image_glyph_string (s); \
18476 append_glyph_string (&HEAD, &TAIL, s); \
18477 ++START; \
18478 s->x = (X); \
18479 } \
18480 while (0)
18481
18482
18483 /* Add a glyph string for a sequence of character glyphs to the list
18484 of strings between HEAD and TAIL. START is the index of the first
18485 glyph in row area AREA of glyph row ROW that is part of the new
18486 glyph string. END is the index of the last glyph in that glyph row
18487 area. X is the current output position assigned to the new glyph
18488 string constructed. HL overrides that face of the glyph; e.g. it
18489 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18490 right-most x-position of the drawing area. */
18491
18492 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18493 do \
18494 { \
18495 int c, face_id; \
18496 XChar2b *char2b; \
18497 \
18498 c = (row)->glyphs[area][START].u.ch; \
18499 face_id = (row)->glyphs[area][START].face_id; \
18500 \
18501 s = (struct glyph_string *) alloca (sizeof *s); \
18502 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18503 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18504 append_glyph_string (&HEAD, &TAIL, s); \
18505 s->x = (X); \
18506 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18507 } \
18508 while (0)
18509
18510
18511 /* Add a glyph string for a composite sequence to the list of strings
18512 between HEAD and TAIL. START is the index of the first glyph in
18513 row area AREA of glyph row ROW that is part of the new glyph
18514 string. END is the index of the last glyph in that glyph row area.
18515 X is the current output position assigned to the new glyph string
18516 constructed. HL overrides that face of the glyph; e.g. it is
18517 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18518 x-position of the drawing area. */
18519
18520 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18521 do { \
18522 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18523 int face_id = (row)->glyphs[area][START].face_id; \
18524 struct face *base_face = FACE_FROM_ID (f, face_id); \
18525 struct composition *cmp = composition_table[cmp_id]; \
18526 int glyph_len = cmp->glyph_len; \
18527 XChar2b *char2b; \
18528 struct face **faces; \
18529 struct glyph_string *first_s = NULL; \
18530 int n; \
18531 \
18532 base_face = base_face->ascii_face; \
18533 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18534 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18535 /* At first, fill in `char2b' and `faces'. */ \
18536 for (n = 0; n < glyph_len; n++) \
18537 { \
18538 int c = COMPOSITION_GLYPH (cmp, n); \
18539 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18540 faces[n] = FACE_FROM_ID (f, this_face_id); \
18541 get_char_face_and_encoding (f, c, this_face_id, \
18542 char2b + n, 1, 1); \
18543 } \
18544 \
18545 /* Make glyph_strings for each glyph sequence that is drawable by \
18546 the same face, and append them to HEAD/TAIL. */ \
18547 for (n = 0; n < cmp->glyph_len;) \
18548 { \
18549 s = (struct glyph_string *) alloca (sizeof *s); \
18550 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18551 append_glyph_string (&(HEAD), &(TAIL), s); \
18552 s->cmp = cmp; \
18553 s->gidx = n; \
18554 s->x = (X); \
18555 \
18556 if (n == 0) \
18557 first_s = s; \
18558 \
18559 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18560 } \
18561 \
18562 ++START; \
18563 s = first_s; \
18564 } while (0)
18565
18566
18567 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18568 of AREA of glyph row ROW on window W between indices START and END.
18569 HL overrides the face for drawing glyph strings, e.g. it is
18570 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18571 x-positions of the drawing area.
18572
18573 This is an ugly monster macro construct because we must use alloca
18574 to allocate glyph strings (because draw_glyphs can be called
18575 asynchronously). */
18576
18577 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18578 do \
18579 { \
18580 HEAD = TAIL = NULL; \
18581 while (START < END) \
18582 { \
18583 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18584 switch (first_glyph->type) \
18585 { \
18586 case CHAR_GLYPH: \
18587 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18588 HL, X, LAST_X); \
18589 break; \
18590 \
18591 case COMPOSITE_GLYPH: \
18592 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18593 HL, X, LAST_X); \
18594 break; \
18595 \
18596 case STRETCH_GLYPH: \
18597 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18598 HL, X, LAST_X); \
18599 break; \
18600 \
18601 case IMAGE_GLYPH: \
18602 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18603 HL, X, LAST_X); \
18604 break; \
18605 \
18606 default: \
18607 abort (); \
18608 } \
18609 \
18610 set_glyph_string_background_width (s, START, LAST_X); \
18611 (X) += s->width; \
18612 } \
18613 } \
18614 while (0)
18615
18616
18617 /* Draw glyphs between START and END in AREA of ROW on window W,
18618 starting at x-position X. X is relative to AREA in W. HL is a
18619 face-override with the following meaning:
18620
18621 DRAW_NORMAL_TEXT draw normally
18622 DRAW_CURSOR draw in cursor face
18623 DRAW_MOUSE_FACE draw in mouse face.
18624 DRAW_INVERSE_VIDEO draw in mode line face
18625 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18626 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18627
18628 If OVERLAPS_P is non-zero, draw only the foreground of characters
18629 and clip to the physical height of ROW.
18630
18631 Value is the x-position reached, relative to AREA of W. */
18632
18633 static int
18634 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18635 struct window *w;
18636 int x;
18637 struct glyph_row *row;
18638 enum glyph_row_area area;
18639 int start, end;
18640 enum draw_glyphs_face hl;
18641 int overlaps_p;
18642 {
18643 struct glyph_string *head, *tail;
18644 struct glyph_string *s;
18645 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
18646 int last_x, area_width;
18647 int x_reached;
18648 int i, j;
18649 struct frame *f = XFRAME (WINDOW_FRAME (w));
18650 DECLARE_HDC (hdc);
18651
18652 ALLOCATE_HDC (hdc, f);
18653
18654 /* Let's rather be paranoid than getting a SEGV. */
18655 end = min (end, row->used[area]);
18656 start = max (0, start);
18657 start = min (end, start);
18658
18659 /* Translate X to frame coordinates. Set last_x to the right
18660 end of the drawing area. */
18661 if (row->full_width_p)
18662 {
18663 /* X is relative to the left edge of W, without scroll bars
18664 or fringes. */
18665 x += WINDOW_LEFT_EDGE_X (w);
18666 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18667 }
18668 else
18669 {
18670 int area_left = window_box_left (w, area);
18671 x += area_left;
18672 area_width = window_box_width (w, area);
18673 last_x = area_left + area_width;
18674 }
18675
18676 /* Build a doubly-linked list of glyph_string structures between
18677 head and tail from what we have to draw. Note that the macro
18678 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18679 the reason we use a separate variable `i'. */
18680 i = start;
18681 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18682 if (tail)
18683 x_reached = tail->x + tail->background_width;
18684 else
18685 x_reached = x;
18686
18687 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18688 the row, redraw some glyphs in front or following the glyph
18689 strings built above. */
18690 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18691 {
18692 int dummy_x = 0;
18693 struct glyph_string *h, *t;
18694
18695 /* Compute overhangs for all glyph strings. */
18696 if (rif->compute_glyph_string_overhangs)
18697 for (s = head; s; s = s->next)
18698 rif->compute_glyph_string_overhangs (s);
18699
18700 /* Prepend glyph strings for glyphs in front of the first glyph
18701 string that are overwritten because of the first glyph
18702 string's left overhang. The background of all strings
18703 prepended must be drawn because the first glyph string
18704 draws over it. */
18705 i = left_overwritten (head);
18706 if (i >= 0)
18707 {
18708 j = i;
18709 BUILD_GLYPH_STRINGS (j, start, h, t,
18710 DRAW_NORMAL_TEXT, dummy_x, last_x);
18711 start = i;
18712 compute_overhangs_and_x (t, head->x, 1);
18713 prepend_glyph_string_lists (&head, &tail, h, t);
18714 clip_head = head;
18715 }
18716
18717 /* Prepend glyph strings for glyphs in front of the first glyph
18718 string that overwrite that glyph string because of their
18719 right overhang. For these strings, only the foreground must
18720 be drawn, because it draws over the glyph string at `head'.
18721 The background must not be drawn because this would overwrite
18722 right overhangs of preceding glyphs for which no glyph
18723 strings exist. */
18724 i = left_overwriting (head);
18725 if (i >= 0)
18726 {
18727 clip_head = head;
18728 BUILD_GLYPH_STRINGS (i, start, h, t,
18729 DRAW_NORMAL_TEXT, dummy_x, last_x);
18730 for (s = h; s; s = s->next)
18731 s->background_filled_p = 1;
18732 compute_overhangs_and_x (t, head->x, 1);
18733 prepend_glyph_string_lists (&head, &tail, h, t);
18734 }
18735
18736 /* Append glyphs strings for glyphs following the last glyph
18737 string tail that are overwritten by tail. The background of
18738 these strings has to be drawn because tail's foreground draws
18739 over it. */
18740 i = right_overwritten (tail);
18741 if (i >= 0)
18742 {
18743 BUILD_GLYPH_STRINGS (end, i, h, t,
18744 DRAW_NORMAL_TEXT, x, last_x);
18745 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18746 append_glyph_string_lists (&head, &tail, h, t);
18747 clip_tail = tail;
18748 }
18749
18750 /* Append glyph strings for glyphs following the last glyph
18751 string tail that overwrite tail. The foreground of such
18752 glyphs has to be drawn because it writes into the background
18753 of tail. The background must not be drawn because it could
18754 paint over the foreground of following glyphs. */
18755 i = right_overwriting (tail);
18756 if (i >= 0)
18757 {
18758 clip_tail = tail;
18759 BUILD_GLYPH_STRINGS (end, i, h, t,
18760 DRAW_NORMAL_TEXT, x, last_x);
18761 for (s = h; s; s = s->next)
18762 s->background_filled_p = 1;
18763 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18764 append_glyph_string_lists (&head, &tail, h, t);
18765 }
18766 if (clip_head || clip_tail)
18767 for (s = head; s; s = s->next)
18768 {
18769 s->clip_head = clip_head;
18770 s->clip_tail = clip_tail;
18771 }
18772 }
18773
18774 /* Draw all strings. */
18775 for (s = head; s; s = s->next)
18776 rif->draw_glyph_string (s);
18777
18778 if (area == TEXT_AREA
18779 && !row->full_width_p
18780 /* When drawing overlapping rows, only the glyph strings'
18781 foreground is drawn, which doesn't erase a cursor
18782 completely. */
18783 && !overlaps_p)
18784 {
18785 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
18786 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
18787 : (tail ? tail->x + tail->background_width : x));
18788
18789 int text_left = window_box_left (w, TEXT_AREA);
18790 x0 -= text_left;
18791 x1 -= text_left;
18792
18793 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18794 row->y, MATRIX_ROW_BOTTOM_Y (row));
18795 }
18796
18797 /* Value is the x-position up to which drawn, relative to AREA of W.
18798 This doesn't include parts drawn because of overhangs. */
18799 if (row->full_width_p)
18800 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18801 else
18802 x_reached -= window_box_left (w, area);
18803
18804 RELEASE_HDC (hdc, f);
18805
18806 return x_reached;
18807 }
18808
18809 /* Expand row matrix if too narrow. Don't expand if area
18810 is not present. */
18811
18812 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18813 { \
18814 if (!fonts_changed_p \
18815 && (it->glyph_row->glyphs[area] \
18816 < it->glyph_row->glyphs[area + 1])) \
18817 { \
18818 it->w->ncols_scale_factor++; \
18819 fonts_changed_p = 1; \
18820 } \
18821 }
18822
18823 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18824 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18825
18826 static INLINE void
18827 append_glyph (it)
18828 struct it *it;
18829 {
18830 struct glyph *glyph;
18831 enum glyph_row_area area = it->area;
18832
18833 xassert (it->glyph_row);
18834 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18835
18836 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18837 if (glyph < it->glyph_row->glyphs[area + 1])
18838 {
18839 glyph->charpos = CHARPOS (it->position);
18840 glyph->object = it->object;
18841 glyph->pixel_width = it->pixel_width;
18842 glyph->ascent = it->ascent;
18843 glyph->descent = it->descent;
18844 glyph->voffset = it->voffset;
18845 glyph->type = CHAR_GLYPH;
18846 glyph->multibyte_p = it->multibyte_p;
18847 glyph->left_box_line_p = it->start_of_box_run_p;
18848 glyph->right_box_line_p = it->end_of_box_run_p;
18849 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18850 || it->phys_descent > it->descent);
18851 glyph->padding_p = 0;
18852 glyph->glyph_not_available_p = it->glyph_not_available_p;
18853 glyph->face_id = it->face_id;
18854 glyph->u.ch = it->char_to_display;
18855 glyph->slice = null_glyph_slice;
18856 glyph->font_type = FONT_TYPE_UNKNOWN;
18857 ++it->glyph_row->used[area];
18858 }
18859 else
18860 IT_EXPAND_MATRIX_WIDTH (it, area);
18861 }
18862
18863 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18864 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18865
18866 static INLINE void
18867 append_composite_glyph (it)
18868 struct it *it;
18869 {
18870 struct glyph *glyph;
18871 enum glyph_row_area area = it->area;
18872
18873 xassert (it->glyph_row);
18874
18875 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18876 if (glyph < it->glyph_row->glyphs[area + 1])
18877 {
18878 glyph->charpos = CHARPOS (it->position);
18879 glyph->object = it->object;
18880 glyph->pixel_width = it->pixel_width;
18881 glyph->ascent = it->ascent;
18882 glyph->descent = it->descent;
18883 glyph->voffset = it->voffset;
18884 glyph->type = COMPOSITE_GLYPH;
18885 glyph->multibyte_p = it->multibyte_p;
18886 glyph->left_box_line_p = it->start_of_box_run_p;
18887 glyph->right_box_line_p = it->end_of_box_run_p;
18888 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18889 || it->phys_descent > it->descent);
18890 glyph->padding_p = 0;
18891 glyph->glyph_not_available_p = 0;
18892 glyph->face_id = it->face_id;
18893 glyph->u.cmp_id = it->cmp_id;
18894 glyph->slice = null_glyph_slice;
18895 glyph->font_type = FONT_TYPE_UNKNOWN;
18896 ++it->glyph_row->used[area];
18897 }
18898 else
18899 IT_EXPAND_MATRIX_WIDTH (it, area);
18900 }
18901
18902
18903 /* Change IT->ascent and IT->height according to the setting of
18904 IT->voffset. */
18905
18906 static INLINE void
18907 take_vertical_position_into_account (it)
18908 struct it *it;
18909 {
18910 if (it->voffset)
18911 {
18912 if (it->voffset < 0)
18913 /* Increase the ascent so that we can display the text higher
18914 in the line. */
18915 it->ascent -= it->voffset;
18916 else
18917 /* Increase the descent so that we can display the text lower
18918 in the line. */
18919 it->descent += it->voffset;
18920 }
18921 }
18922
18923
18924 /* Produce glyphs/get display metrics for the image IT is loaded with.
18925 See the description of struct display_iterator in dispextern.h for
18926 an overview of struct display_iterator. */
18927
18928 static void
18929 produce_image_glyph (it)
18930 struct it *it;
18931 {
18932 struct image *img;
18933 struct face *face;
18934 int glyph_ascent;
18935 struct glyph_slice slice;
18936
18937 xassert (it->what == IT_IMAGE);
18938
18939 face = FACE_FROM_ID (it->f, it->face_id);
18940 xassert (face);
18941 /* Make sure X resources of the face is loaded. */
18942 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18943
18944 if (it->image_id < 0)
18945 {
18946 /* Fringe bitmap. */
18947 it->ascent = it->phys_ascent = 0;
18948 it->descent = it->phys_descent = 0;
18949 it->pixel_width = 0;
18950 it->nglyphs = 0;
18951 return;
18952 }
18953
18954 img = IMAGE_FROM_ID (it->f, it->image_id);
18955 xassert (img);
18956 /* Make sure X resources of the image is loaded. */
18957 prepare_image_for_display (it->f, img);
18958
18959 slice.x = slice.y = 0;
18960 slice.width = img->width;
18961 slice.height = img->height;
18962
18963 if (INTEGERP (it->slice.x))
18964 slice.x = XINT (it->slice.x);
18965 else if (FLOATP (it->slice.x))
18966 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18967
18968 if (INTEGERP (it->slice.y))
18969 slice.y = XINT (it->slice.y);
18970 else if (FLOATP (it->slice.y))
18971 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18972
18973 if (INTEGERP (it->slice.width))
18974 slice.width = XINT (it->slice.width);
18975 else if (FLOATP (it->slice.width))
18976 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18977
18978 if (INTEGERP (it->slice.height))
18979 slice.height = XINT (it->slice.height);
18980 else if (FLOATP (it->slice.height))
18981 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18982
18983 if (slice.x >= img->width)
18984 slice.x = img->width;
18985 if (slice.y >= img->height)
18986 slice.y = img->height;
18987 if (slice.x + slice.width >= img->width)
18988 slice.width = img->width - slice.x;
18989 if (slice.y + slice.height > img->height)
18990 slice.height = img->height - slice.y;
18991
18992 if (slice.width == 0 || slice.height == 0)
18993 return;
18994
18995 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18996
18997 it->descent = slice.height - glyph_ascent;
18998 if (slice.y == 0)
18999 it->descent += img->vmargin;
19000 if (slice.y + slice.height == img->height)
19001 it->descent += img->vmargin;
19002 it->phys_descent = it->descent;
19003
19004 it->pixel_width = slice.width;
19005 if (slice.x == 0)
19006 it->pixel_width += img->hmargin;
19007 if (slice.x + slice.width == img->width)
19008 it->pixel_width += img->hmargin;
19009
19010 /* It's quite possible for images to have an ascent greater than
19011 their height, so don't get confused in that case. */
19012 if (it->descent < 0)
19013 it->descent = 0;
19014
19015 #if 0 /* this breaks image tiling */
19016 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
19017 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
19018 if (face_ascent > it->ascent)
19019 it->ascent = it->phys_ascent = face_ascent;
19020 #endif
19021
19022 it->nglyphs = 1;
19023
19024 if (face->box != FACE_NO_BOX)
19025 {
19026 if (face->box_line_width > 0)
19027 {
19028 if (slice.y == 0)
19029 it->ascent += face->box_line_width;
19030 if (slice.y + slice.height == img->height)
19031 it->descent += face->box_line_width;
19032 }
19033
19034 if (it->start_of_box_run_p && slice.x == 0)
19035 it->pixel_width += abs (face->box_line_width);
19036 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
19037 it->pixel_width += abs (face->box_line_width);
19038 }
19039
19040 take_vertical_position_into_account (it);
19041
19042 if (it->glyph_row)
19043 {
19044 struct glyph *glyph;
19045 enum glyph_row_area area = it->area;
19046
19047 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19048 if (glyph < it->glyph_row->glyphs[area + 1])
19049 {
19050 glyph->charpos = CHARPOS (it->position);
19051 glyph->object = it->object;
19052 glyph->pixel_width = it->pixel_width;
19053 glyph->ascent = glyph_ascent;
19054 glyph->descent = it->descent;
19055 glyph->voffset = it->voffset;
19056 glyph->type = IMAGE_GLYPH;
19057 glyph->multibyte_p = it->multibyte_p;
19058 glyph->left_box_line_p = it->start_of_box_run_p;
19059 glyph->right_box_line_p = it->end_of_box_run_p;
19060 glyph->overlaps_vertically_p = 0;
19061 glyph->padding_p = 0;
19062 glyph->glyph_not_available_p = 0;
19063 glyph->face_id = it->face_id;
19064 glyph->u.img_id = img->id;
19065 glyph->slice = slice;
19066 glyph->font_type = FONT_TYPE_UNKNOWN;
19067 ++it->glyph_row->used[area];
19068 }
19069 else
19070 IT_EXPAND_MATRIX_WIDTH (it, area);
19071 }
19072 }
19073
19074
19075 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
19076 of the glyph, WIDTH and HEIGHT are the width and height of the
19077 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
19078
19079 static void
19080 append_stretch_glyph (it, object, width, height, ascent)
19081 struct it *it;
19082 Lisp_Object object;
19083 int width, height;
19084 int ascent;
19085 {
19086 struct glyph *glyph;
19087 enum glyph_row_area area = it->area;
19088
19089 xassert (ascent >= 0 && ascent <= height);
19090
19091 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
19092 if (glyph < it->glyph_row->glyphs[area + 1])
19093 {
19094 glyph->charpos = CHARPOS (it->position);
19095 glyph->object = object;
19096 glyph->pixel_width = width;
19097 glyph->ascent = ascent;
19098 glyph->descent = height - ascent;
19099 glyph->voffset = it->voffset;
19100 glyph->type = STRETCH_GLYPH;
19101 glyph->multibyte_p = it->multibyte_p;
19102 glyph->left_box_line_p = it->start_of_box_run_p;
19103 glyph->right_box_line_p = it->end_of_box_run_p;
19104 glyph->overlaps_vertically_p = 0;
19105 glyph->padding_p = 0;
19106 glyph->glyph_not_available_p = 0;
19107 glyph->face_id = it->face_id;
19108 glyph->u.stretch.ascent = ascent;
19109 glyph->u.stretch.height = height;
19110 glyph->slice = null_glyph_slice;
19111 glyph->font_type = FONT_TYPE_UNKNOWN;
19112 ++it->glyph_row->used[area];
19113 }
19114 else
19115 IT_EXPAND_MATRIX_WIDTH (it, area);
19116 }
19117
19118
19119 /* Produce a stretch glyph for iterator IT. IT->object is the value
19120 of the glyph property displayed. The value must be a list
19121 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
19122 being recognized:
19123
19124 1. `:width WIDTH' specifies that the space should be WIDTH *
19125 canonical char width wide. WIDTH may be an integer or floating
19126 point number.
19127
19128 2. `:relative-width FACTOR' specifies that the width of the stretch
19129 should be computed from the width of the first character having the
19130 `glyph' property, and should be FACTOR times that width.
19131
19132 3. `:align-to HPOS' specifies that the space should be wide enough
19133 to reach HPOS, a value in canonical character units.
19134
19135 Exactly one of the above pairs must be present.
19136
19137 4. `:height HEIGHT' specifies that the height of the stretch produced
19138 should be HEIGHT, measured in canonical character units.
19139
19140 5. `:relative-height FACTOR' specifies that the height of the
19141 stretch should be FACTOR times the height of the characters having
19142 the glyph property.
19143
19144 Either none or exactly one of 4 or 5 must be present.
19145
19146 6. `:ascent ASCENT' specifies that ASCENT percent of the height
19147 of the stretch should be used for the ascent of the stretch.
19148 ASCENT must be in the range 0 <= ASCENT <= 100. */
19149
19150 static void
19151 produce_stretch_glyph (it)
19152 struct it *it;
19153 {
19154 /* (space :width WIDTH :height HEIGHT ...) */
19155 Lisp_Object prop, plist;
19156 int width = 0, height = 0, align_to = -1;
19157 int zero_width_ok_p = 0, zero_height_ok_p = 0;
19158 int ascent = 0;
19159 double tem;
19160 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19161 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
19162
19163 PREPARE_FACE_FOR_DISPLAY (it->f, face);
19164
19165 /* List should start with `space'. */
19166 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
19167 plist = XCDR (it->object);
19168
19169 /* Compute the width of the stretch. */
19170 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
19171 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
19172 {
19173 /* Absolute width `:width WIDTH' specified and valid. */
19174 zero_width_ok_p = 1;
19175 width = (int)tem;
19176 }
19177 else if (prop = Fplist_get (plist, QCrelative_width),
19178 NUMVAL (prop) > 0)
19179 {
19180 /* Relative width `:relative-width FACTOR' specified and valid.
19181 Compute the width of the characters having the `glyph'
19182 property. */
19183 struct it it2;
19184 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
19185
19186 it2 = *it;
19187 if (it->multibyte_p)
19188 {
19189 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
19190 - IT_BYTEPOS (*it));
19191 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
19192 }
19193 else
19194 it2.c = *p, it2.len = 1;
19195
19196 it2.glyph_row = NULL;
19197 it2.what = IT_CHARACTER;
19198 x_produce_glyphs (&it2);
19199 width = NUMVAL (prop) * it2.pixel_width;
19200 }
19201 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
19202 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
19203 {
19204 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
19205 align_to = (align_to < 0
19206 ? 0
19207 : align_to - window_box_left_offset (it->w, TEXT_AREA));
19208 else if (align_to < 0)
19209 align_to = window_box_left_offset (it->w, TEXT_AREA);
19210 width = max (0, (int)tem + align_to - it->current_x);
19211 zero_width_ok_p = 1;
19212 }
19213 else
19214 /* Nothing specified -> width defaults to canonical char width. */
19215 width = FRAME_COLUMN_WIDTH (it->f);
19216
19217 if (width <= 0 && (width < 0 || !zero_width_ok_p))
19218 width = 1;
19219
19220 /* Compute height. */
19221 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
19222 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
19223 {
19224 height = (int)tem;
19225 zero_height_ok_p = 1;
19226 }
19227 else if (prop = Fplist_get (plist, QCrelative_height),
19228 NUMVAL (prop) > 0)
19229 height = FONT_HEIGHT (font) * NUMVAL (prop);
19230 else
19231 height = FONT_HEIGHT (font);
19232
19233 if (height <= 0 && (height < 0 || !zero_height_ok_p))
19234 height = 1;
19235
19236 /* Compute percentage of height used for ascent. If
19237 `:ascent ASCENT' is present and valid, use that. Otherwise,
19238 derive the ascent from the font in use. */
19239 if (prop = Fplist_get (plist, QCascent),
19240 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
19241 ascent = height * NUMVAL (prop) / 100.0;
19242 else if (!NILP (prop)
19243 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
19244 ascent = min (max (0, (int)tem), height);
19245 else
19246 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
19247
19248 if (width > 0 && height > 0 && it->glyph_row)
19249 {
19250 Lisp_Object object = it->stack[it->sp - 1].string;
19251 if (!STRINGP (object))
19252 object = it->w->buffer;
19253 append_stretch_glyph (it, object, width, height, ascent);
19254 }
19255
19256 it->pixel_width = width;
19257 it->ascent = it->phys_ascent = ascent;
19258 it->descent = it->phys_descent = height - it->ascent;
19259 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
19260
19261 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
19262 {
19263 if (face->box_line_width > 0)
19264 {
19265 it->ascent += face->box_line_width;
19266 it->descent += face->box_line_width;
19267 }
19268
19269 if (it->start_of_box_run_p)
19270 it->pixel_width += abs (face->box_line_width);
19271 if (it->end_of_box_run_p)
19272 it->pixel_width += abs (face->box_line_width);
19273 }
19274
19275 take_vertical_position_into_account (it);
19276 }
19277
19278 /* Get line-height and line-spacing property at point.
19279 If line-height has format (HEIGHT TOTAL), return TOTAL
19280 in TOTAL_HEIGHT. */
19281
19282 static Lisp_Object
19283 get_line_height_property (it, prop)
19284 struct it *it;
19285 Lisp_Object prop;
19286 {
19287 Lisp_Object position;
19288
19289 if (STRINGP (it->object))
19290 position = make_number (IT_STRING_CHARPOS (*it));
19291 else if (BUFFERP (it->object))
19292 position = make_number (IT_CHARPOS (*it));
19293 else
19294 return Qnil;
19295
19296 return Fget_char_property (position, prop, it->object);
19297 }
19298
19299 /* Calculate line-height and line-spacing properties.
19300 An integer value specifies explicit pixel value.
19301 A float value specifies relative value to current face height.
19302 A cons (float . face-name) specifies relative value to
19303 height of specified face font.
19304
19305 Returns height in pixels, or nil. */
19306
19307
19308 static Lisp_Object
19309 calc_line_height_property (it, val, font, boff, override)
19310 struct it *it;
19311 Lisp_Object val;
19312 XFontStruct *font;
19313 int boff, override;
19314 {
19315 Lisp_Object face_name = Qnil;
19316 int ascent, descent, height;
19317
19318 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
19319 return val;
19320
19321 if (CONSP (val))
19322 {
19323 face_name = XCAR (val);
19324 val = XCDR (val);
19325 if (!NUMBERP (val))
19326 val = make_number (1);
19327 if (NILP (face_name))
19328 {
19329 height = it->ascent + it->descent;
19330 goto scale;
19331 }
19332 }
19333
19334 if (NILP (face_name))
19335 {
19336 font = FRAME_FONT (it->f);
19337 boff = FRAME_BASELINE_OFFSET (it->f);
19338 }
19339 else if (EQ (face_name, Qt))
19340 {
19341 override = 0;
19342 }
19343 else
19344 {
19345 int face_id;
19346 struct face *face;
19347 struct font_info *font_info;
19348
19349 face_id = lookup_named_face (it->f, face_name, ' ', 0);
19350 if (face_id < 0)
19351 return make_number (-1);
19352
19353 face = FACE_FROM_ID (it->f, face_id);
19354 font = face->font;
19355 if (font == NULL)
19356 return make_number (-1);
19357
19358 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19359 boff = font_info->baseline_offset;
19360 if (font_info->vertical_centering)
19361 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19362 }
19363
19364 ascent = FONT_BASE (font) + boff;
19365 descent = FONT_DESCENT (font) - boff;
19366
19367 if (override)
19368 {
19369 it->override_ascent = ascent;
19370 it->override_descent = descent;
19371 it->override_boff = boff;
19372 }
19373
19374 height = ascent + descent;
19375
19376 scale:
19377 if (FLOATP (val))
19378 height = (int)(XFLOAT_DATA (val) * height);
19379 else if (INTEGERP (val))
19380 height *= XINT (val);
19381
19382 return make_number (height);
19383 }
19384
19385
19386 /* RIF:
19387 Produce glyphs/get display metrics for the display element IT is
19388 loaded with. See the description of struct display_iterator in
19389 dispextern.h for an overview of struct display_iterator. */
19390
19391 void
19392 x_produce_glyphs (it)
19393 struct it *it;
19394 {
19395 int extra_line_spacing = it->extra_line_spacing;
19396
19397 it->glyph_not_available_p = 0;
19398
19399 if (it->what == IT_CHARACTER)
19400 {
19401 XChar2b char2b;
19402 XFontStruct *font;
19403 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19404 XCharStruct *pcm;
19405 int font_not_found_p;
19406 struct font_info *font_info;
19407 int boff; /* baseline offset */
19408 /* We may change it->multibyte_p upon unibyte<->multibyte
19409 conversion. So, save the current value now and restore it
19410 later.
19411
19412 Note: It seems that we don't have to record multibyte_p in
19413 struct glyph because the character code itself tells if or
19414 not the character is multibyte. Thus, in the future, we must
19415 consider eliminating the field `multibyte_p' in the struct
19416 glyph. */
19417 int saved_multibyte_p = it->multibyte_p;
19418
19419 /* Maybe translate single-byte characters to multibyte, or the
19420 other way. */
19421 it->char_to_display = it->c;
19422 if (!ASCII_BYTE_P (it->c))
19423 {
19424 if (unibyte_display_via_language_environment
19425 && SINGLE_BYTE_CHAR_P (it->c)
19426 && (it->c >= 0240
19427 || !NILP (Vnonascii_translation_table)))
19428 {
19429 it->char_to_display = unibyte_char_to_multibyte (it->c);
19430 it->multibyte_p = 1;
19431 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19432 face = FACE_FROM_ID (it->f, it->face_id);
19433 }
19434 else if (!SINGLE_BYTE_CHAR_P (it->c)
19435 && !it->multibyte_p)
19436 {
19437 it->multibyte_p = 1;
19438 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19439 face = FACE_FROM_ID (it->f, it->face_id);
19440 }
19441 }
19442
19443 /* Get font to use. Encode IT->char_to_display. */
19444 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19445 &char2b, it->multibyte_p, 0);
19446 font = face->font;
19447
19448 /* When no suitable font found, use the default font. */
19449 font_not_found_p = font == NULL;
19450 if (font_not_found_p)
19451 {
19452 font = FRAME_FONT (it->f);
19453 boff = FRAME_BASELINE_OFFSET (it->f);
19454 font_info = NULL;
19455 }
19456 else
19457 {
19458 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19459 boff = font_info->baseline_offset;
19460 if (font_info->vertical_centering)
19461 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19462 }
19463
19464 if (it->char_to_display >= ' '
19465 && (!it->multibyte_p || it->char_to_display < 128))
19466 {
19467 /* Either unibyte or ASCII. */
19468 int stretched_p;
19469
19470 it->nglyphs = 1;
19471
19472 pcm = rif->per_char_metric (font, &char2b,
19473 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
19474
19475 if (it->override_ascent >= 0)
19476 {
19477 it->ascent = it->override_ascent;
19478 it->descent = it->override_descent;
19479 boff = it->override_boff;
19480 }
19481 else
19482 {
19483 it->ascent = FONT_BASE (font) + boff;
19484 it->descent = FONT_DESCENT (font) - boff;
19485 }
19486
19487 if (pcm)
19488 {
19489 it->phys_ascent = pcm->ascent + boff;
19490 it->phys_descent = pcm->descent - boff;
19491 it->pixel_width = pcm->width;
19492 }
19493 else
19494 {
19495 it->glyph_not_available_p = 1;
19496 it->phys_ascent = it->ascent;
19497 it->phys_descent = it->descent;
19498 it->pixel_width = FONT_WIDTH (font);
19499 }
19500
19501 if (it->constrain_row_ascent_descent_p)
19502 {
19503 if (it->descent > it->max_descent)
19504 {
19505 it->ascent += it->descent - it->max_descent;
19506 it->descent = it->max_descent;
19507 }
19508 if (it->ascent > it->max_ascent)
19509 {
19510 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19511 it->ascent = it->max_ascent;
19512 }
19513 it->phys_ascent = min (it->phys_ascent, it->ascent);
19514 it->phys_descent = min (it->phys_descent, it->descent);
19515 extra_line_spacing = 0;
19516 }
19517
19518 /* If this is a space inside a region of text with
19519 `space-width' property, change its width. */
19520 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19521 if (stretched_p)
19522 it->pixel_width *= XFLOATINT (it->space_width);
19523
19524 /* If face has a box, add the box thickness to the character
19525 height. If character has a box line to the left and/or
19526 right, add the box line width to the character's width. */
19527 if (face->box != FACE_NO_BOX)
19528 {
19529 int thick = face->box_line_width;
19530
19531 if (thick > 0)
19532 {
19533 it->ascent += thick;
19534 it->descent += thick;
19535 }
19536 else
19537 thick = -thick;
19538
19539 if (it->start_of_box_run_p)
19540 it->pixel_width += thick;
19541 if (it->end_of_box_run_p)
19542 it->pixel_width += thick;
19543 }
19544
19545 /* If face has an overline, add the height of the overline
19546 (1 pixel) and a 1 pixel margin to the character height. */
19547 if (face->overline_p)
19548 it->ascent += 2;
19549
19550 if (it->constrain_row_ascent_descent_p)
19551 {
19552 if (it->ascent > it->max_ascent)
19553 it->ascent = it->max_ascent;
19554 if (it->descent > it->max_descent)
19555 it->descent = it->max_descent;
19556 }
19557
19558 take_vertical_position_into_account (it);
19559
19560 /* If we have to actually produce glyphs, do it. */
19561 if (it->glyph_row)
19562 {
19563 if (stretched_p)
19564 {
19565 /* Translate a space with a `space-width' property
19566 into a stretch glyph. */
19567 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19568 / FONT_HEIGHT (font));
19569 append_stretch_glyph (it, it->object, it->pixel_width,
19570 it->ascent + it->descent, ascent);
19571 }
19572 else
19573 append_glyph (it);
19574
19575 /* If characters with lbearing or rbearing are displayed
19576 in this line, record that fact in a flag of the
19577 glyph row. This is used to optimize X output code. */
19578 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19579 it->glyph_row->contains_overlapping_glyphs_p = 1;
19580 }
19581 }
19582 else if (it->char_to_display == '\n')
19583 {
19584 /* A newline has no width but we need the height of the line.
19585 But if previous part of the line set a height, don't
19586 increase that height */
19587
19588 Lisp_Object height;
19589 Lisp_Object total_height = Qnil;
19590
19591 it->override_ascent = -1;
19592 it->pixel_width = 0;
19593 it->nglyphs = 0;
19594
19595 height = get_line_height_property(it, Qline_height);
19596 /* Split (line-height total-height) list */
19597 if (CONSP (height)
19598 && CONSP (XCDR (height))
19599 && NILP (XCDR (XCDR (height))))
19600 {
19601 total_height = XCAR (XCDR (height));
19602 height = XCAR (height);
19603 }
19604 height = calc_line_height_property(it, height, font, boff, 1);
19605
19606 if (it->override_ascent >= 0)
19607 {
19608 it->ascent = it->override_ascent;
19609 it->descent = it->override_descent;
19610 boff = it->override_boff;
19611 }
19612 else
19613 {
19614 it->ascent = FONT_BASE (font) + boff;
19615 it->descent = FONT_DESCENT (font) - boff;
19616 }
19617
19618 if (EQ (height, Qt))
19619 {
19620 if (it->descent > it->max_descent)
19621 {
19622 it->ascent += it->descent - it->max_descent;
19623 it->descent = it->max_descent;
19624 }
19625 if (it->ascent > it->max_ascent)
19626 {
19627 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19628 it->ascent = it->max_ascent;
19629 }
19630 it->phys_ascent = min (it->phys_ascent, it->ascent);
19631 it->phys_descent = min (it->phys_descent, it->descent);
19632 it->constrain_row_ascent_descent_p = 1;
19633 extra_line_spacing = 0;
19634 }
19635 else
19636 {
19637 Lisp_Object spacing;
19638
19639 it->phys_ascent = it->ascent;
19640 it->phys_descent = it->descent;
19641
19642 if ((it->max_ascent > 0 || it->max_descent > 0)
19643 && face->box != FACE_NO_BOX
19644 && face->box_line_width > 0)
19645 {
19646 it->ascent += face->box_line_width;
19647 it->descent += face->box_line_width;
19648 }
19649 if (!NILP (height)
19650 && XINT (height) > it->ascent + it->descent)
19651 it->ascent = XINT (height) - it->descent;
19652
19653 if (!NILP (total_height))
19654 spacing = calc_line_height_property(it, total_height, font, boff, 0);
19655 else
19656 {
19657 spacing = get_line_height_property(it, Qline_spacing);
19658 spacing = calc_line_height_property(it, spacing, font, boff, 0);
19659 }
19660 if (INTEGERP (spacing))
19661 {
19662 extra_line_spacing = XINT (spacing);
19663 if (!NILP (total_height))
19664 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19665 }
19666 }
19667 }
19668 else if (it->char_to_display == '\t')
19669 {
19670 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
19671 int x = it->current_x + it->continuation_lines_width;
19672 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19673
19674 /* If the distance from the current position to the next tab
19675 stop is less than a space character width, use the
19676 tab stop after that. */
19677 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
19678 next_tab_x += tab_width;
19679
19680 it->pixel_width = next_tab_x - x;
19681 it->nglyphs = 1;
19682 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19683 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19684
19685 if (it->glyph_row)
19686 {
19687 append_stretch_glyph (it, it->object, it->pixel_width,
19688 it->ascent + it->descent, it->ascent);
19689 }
19690 }
19691 else
19692 {
19693 /* A multi-byte character. Assume that the display width of the
19694 character is the width of the character multiplied by the
19695 width of the font. */
19696
19697 /* If we found a font, this font should give us the right
19698 metrics. If we didn't find a font, use the frame's
19699 default font and calculate the width of the character
19700 from the charset width; this is what old redisplay code
19701 did. */
19702
19703 pcm = rif->per_char_metric (font, &char2b,
19704 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19705
19706 if (font_not_found_p || !pcm)
19707 {
19708 int charset = CHAR_CHARSET (it->char_to_display);
19709
19710 it->glyph_not_available_p = 1;
19711 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19712 * CHARSET_WIDTH (charset));
19713 it->phys_ascent = FONT_BASE (font) + boff;
19714 it->phys_descent = FONT_DESCENT (font) - boff;
19715 }
19716 else
19717 {
19718 it->pixel_width = pcm->width;
19719 it->phys_ascent = pcm->ascent + boff;
19720 it->phys_descent = pcm->descent - boff;
19721 if (it->glyph_row
19722 && (pcm->lbearing < 0
19723 || pcm->rbearing > pcm->width))
19724 it->glyph_row->contains_overlapping_glyphs_p = 1;
19725 }
19726 it->nglyphs = 1;
19727 it->ascent = FONT_BASE (font) + boff;
19728 it->descent = FONT_DESCENT (font) - boff;
19729 if (face->box != FACE_NO_BOX)
19730 {
19731 int thick = face->box_line_width;
19732
19733 if (thick > 0)
19734 {
19735 it->ascent += thick;
19736 it->descent += thick;
19737 }
19738 else
19739 thick = - thick;
19740
19741 if (it->start_of_box_run_p)
19742 it->pixel_width += thick;
19743 if (it->end_of_box_run_p)
19744 it->pixel_width += thick;
19745 }
19746
19747 /* If face has an overline, add the height of the overline
19748 (1 pixel) and a 1 pixel margin to the character height. */
19749 if (face->overline_p)
19750 it->ascent += 2;
19751
19752 take_vertical_position_into_account (it);
19753
19754 if (it->glyph_row)
19755 append_glyph (it);
19756 }
19757 it->multibyte_p = saved_multibyte_p;
19758 }
19759 else if (it->what == IT_COMPOSITION)
19760 {
19761 /* Note: A composition is represented as one glyph in the
19762 glyph matrix. There are no padding glyphs. */
19763 XChar2b char2b;
19764 XFontStruct *font;
19765 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19766 XCharStruct *pcm;
19767 int font_not_found_p;
19768 struct font_info *font_info;
19769 int boff; /* baseline offset */
19770 struct composition *cmp = composition_table[it->cmp_id];
19771
19772 /* Maybe translate single-byte characters to multibyte. */
19773 it->char_to_display = it->c;
19774 if (unibyte_display_via_language_environment
19775 && SINGLE_BYTE_CHAR_P (it->c)
19776 && (it->c >= 0240
19777 || (it->c >= 0200
19778 && !NILP (Vnonascii_translation_table))))
19779 {
19780 it->char_to_display = unibyte_char_to_multibyte (it->c);
19781 }
19782
19783 /* Get face and font to use. Encode IT->char_to_display. */
19784 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19785 face = FACE_FROM_ID (it->f, it->face_id);
19786 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19787 &char2b, it->multibyte_p, 0);
19788 font = face->font;
19789
19790 /* When no suitable font found, use the default font. */
19791 font_not_found_p = font == NULL;
19792 if (font_not_found_p)
19793 {
19794 font = FRAME_FONT (it->f);
19795 boff = FRAME_BASELINE_OFFSET (it->f);
19796 font_info = NULL;
19797 }
19798 else
19799 {
19800 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19801 boff = font_info->baseline_offset;
19802 if (font_info->vertical_centering)
19803 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19804 }
19805
19806 /* There are no padding glyphs, so there is only one glyph to
19807 produce for the composition. Important is that pixel_width,
19808 ascent and descent are the values of what is drawn by
19809 draw_glyphs (i.e. the values of the overall glyphs composed). */
19810 it->nglyphs = 1;
19811
19812 /* If we have not yet calculated pixel size data of glyphs of
19813 the composition for the current face font, calculate them
19814 now. Theoretically, we have to check all fonts for the
19815 glyphs, but that requires much time and memory space. So,
19816 here we check only the font of the first glyph. This leads
19817 to incorrect display very rarely, and C-l (recenter) can
19818 correct the display anyway. */
19819 if (cmp->font != (void *) font)
19820 {
19821 /* Ascent and descent of the font of the first character of
19822 this composition (adjusted by baseline offset). Ascent
19823 and descent of overall glyphs should not be less than
19824 them respectively. */
19825 int font_ascent = FONT_BASE (font) + boff;
19826 int font_descent = FONT_DESCENT (font) - boff;
19827 /* Bounding box of the overall glyphs. */
19828 int leftmost, rightmost, lowest, highest;
19829 int i, width, ascent, descent;
19830
19831 cmp->font = (void *) font;
19832
19833 /* Initialize the bounding box. */
19834 if (font_info
19835 && (pcm = rif->per_char_metric (font, &char2b,
19836 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19837 {
19838 width = pcm->width;
19839 ascent = pcm->ascent;
19840 descent = pcm->descent;
19841 }
19842 else
19843 {
19844 width = FONT_WIDTH (font);
19845 ascent = FONT_BASE (font);
19846 descent = FONT_DESCENT (font);
19847 }
19848
19849 rightmost = width;
19850 lowest = - descent + boff;
19851 highest = ascent + boff;
19852 leftmost = 0;
19853
19854 if (font_info
19855 && font_info->default_ascent
19856 && CHAR_TABLE_P (Vuse_default_ascent)
19857 && !NILP (Faref (Vuse_default_ascent,
19858 make_number (it->char_to_display))))
19859 highest = font_info->default_ascent + boff;
19860
19861 /* Draw the first glyph at the normal position. It may be
19862 shifted to right later if some other glyphs are drawn at
19863 the left. */
19864 cmp->offsets[0] = 0;
19865 cmp->offsets[1] = boff;
19866
19867 /* Set cmp->offsets for the remaining glyphs. */
19868 for (i = 1; i < cmp->glyph_len; i++)
19869 {
19870 int left, right, btm, top;
19871 int ch = COMPOSITION_GLYPH (cmp, i);
19872 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19873
19874 face = FACE_FROM_ID (it->f, face_id);
19875 get_char_face_and_encoding (it->f, ch, face->id,
19876 &char2b, it->multibyte_p, 0);
19877 font = face->font;
19878 if (font == NULL)
19879 {
19880 font = FRAME_FONT (it->f);
19881 boff = FRAME_BASELINE_OFFSET (it->f);
19882 font_info = NULL;
19883 }
19884 else
19885 {
19886 font_info
19887 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19888 boff = font_info->baseline_offset;
19889 if (font_info->vertical_centering)
19890 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19891 }
19892
19893 if (font_info
19894 && (pcm = rif->per_char_metric (font, &char2b,
19895 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19896 {
19897 width = pcm->width;
19898 ascent = pcm->ascent;
19899 descent = pcm->descent;
19900 }
19901 else
19902 {
19903 width = FONT_WIDTH (font);
19904 ascent = 1;
19905 descent = 0;
19906 }
19907
19908 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19909 {
19910 /* Relative composition with or without
19911 alternate chars. */
19912 left = (leftmost + rightmost - width) / 2;
19913 btm = - descent + boff;
19914 if (font_info && font_info->relative_compose
19915 && (! CHAR_TABLE_P (Vignore_relative_composition)
19916 || NILP (Faref (Vignore_relative_composition,
19917 make_number (ch)))))
19918 {
19919
19920 if (- descent >= font_info->relative_compose)
19921 /* One extra pixel between two glyphs. */
19922 btm = highest + 1;
19923 else if (ascent <= 0)
19924 /* One extra pixel between two glyphs. */
19925 btm = lowest - 1 - ascent - descent;
19926 }
19927 }
19928 else
19929 {
19930 /* A composition rule is specified by an integer
19931 value that encodes global and new reference
19932 points (GREF and NREF). GREF and NREF are
19933 specified by numbers as below:
19934
19935 0---1---2 -- ascent
19936 | |
19937 | |
19938 | |
19939 9--10--11 -- center
19940 | |
19941 ---3---4---5--- baseline
19942 | |
19943 6---7---8 -- descent
19944 */
19945 int rule = COMPOSITION_RULE (cmp, i);
19946 int gref, nref, grefx, grefy, nrefx, nrefy;
19947
19948 COMPOSITION_DECODE_RULE (rule, gref, nref);
19949 grefx = gref % 3, nrefx = nref % 3;
19950 grefy = gref / 3, nrefy = nref / 3;
19951
19952 left = (leftmost
19953 + grefx * (rightmost - leftmost) / 2
19954 - nrefx * width / 2);
19955 btm = ((grefy == 0 ? highest
19956 : grefy == 1 ? 0
19957 : grefy == 2 ? lowest
19958 : (highest + lowest) / 2)
19959 - (nrefy == 0 ? ascent + descent
19960 : nrefy == 1 ? descent - boff
19961 : nrefy == 2 ? 0
19962 : (ascent + descent) / 2));
19963 }
19964
19965 cmp->offsets[i * 2] = left;
19966 cmp->offsets[i * 2 + 1] = btm + descent;
19967
19968 /* Update the bounding box of the overall glyphs. */
19969 right = left + width;
19970 top = btm + descent + ascent;
19971 if (left < leftmost)
19972 leftmost = left;
19973 if (right > rightmost)
19974 rightmost = right;
19975 if (top > highest)
19976 highest = top;
19977 if (btm < lowest)
19978 lowest = btm;
19979 }
19980
19981 /* If there are glyphs whose x-offsets are negative,
19982 shift all glyphs to the right and make all x-offsets
19983 non-negative. */
19984 if (leftmost < 0)
19985 {
19986 for (i = 0; i < cmp->glyph_len; i++)
19987 cmp->offsets[i * 2] -= leftmost;
19988 rightmost -= leftmost;
19989 }
19990
19991 cmp->pixel_width = rightmost;
19992 cmp->ascent = highest;
19993 cmp->descent = - lowest;
19994 if (cmp->ascent < font_ascent)
19995 cmp->ascent = font_ascent;
19996 if (cmp->descent < font_descent)
19997 cmp->descent = font_descent;
19998 }
19999
20000 it->pixel_width = cmp->pixel_width;
20001 it->ascent = it->phys_ascent = cmp->ascent;
20002 it->descent = it->phys_descent = cmp->descent;
20003
20004 if (face->box != FACE_NO_BOX)
20005 {
20006 int thick = face->box_line_width;
20007
20008 if (thick > 0)
20009 {
20010 it->ascent += thick;
20011 it->descent += thick;
20012 }
20013 else
20014 thick = - thick;
20015
20016 if (it->start_of_box_run_p)
20017 it->pixel_width += thick;
20018 if (it->end_of_box_run_p)
20019 it->pixel_width += thick;
20020 }
20021
20022 /* If face has an overline, add the height of the overline
20023 (1 pixel) and a 1 pixel margin to the character height. */
20024 if (face->overline_p)
20025 it->ascent += 2;
20026
20027 take_vertical_position_into_account (it);
20028
20029 if (it->glyph_row)
20030 append_composite_glyph (it);
20031 }
20032 else if (it->what == IT_IMAGE)
20033 produce_image_glyph (it);
20034 else if (it->what == IT_STRETCH)
20035 produce_stretch_glyph (it);
20036
20037 /* Accumulate dimensions. Note: can't assume that it->descent > 0
20038 because this isn't true for images with `:ascent 100'. */
20039 xassert (it->ascent >= 0 && it->descent >= 0);
20040 if (it->area == TEXT_AREA)
20041 it->current_x += it->pixel_width;
20042
20043 if (extra_line_spacing > 0)
20044 {
20045 it->descent += extra_line_spacing;
20046 if (extra_line_spacing > it->max_extra_line_spacing)
20047 it->max_extra_line_spacing = extra_line_spacing;
20048 }
20049
20050 it->max_ascent = max (it->max_ascent, it->ascent);
20051 it->max_descent = max (it->max_descent, it->descent);
20052 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
20053 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
20054 }
20055
20056 /* EXPORT for RIF:
20057 Output LEN glyphs starting at START at the nominal cursor position.
20058 Advance the nominal cursor over the text. The global variable
20059 updated_window contains the window being updated, updated_row is
20060 the glyph row being updated, and updated_area is the area of that
20061 row being updated. */
20062
20063 void
20064 x_write_glyphs (start, len)
20065 struct glyph *start;
20066 int len;
20067 {
20068 int x, hpos;
20069
20070 xassert (updated_window && updated_row);
20071 BLOCK_INPUT;
20072
20073 /* Write glyphs. */
20074
20075 hpos = start - updated_row->glyphs[updated_area];
20076 x = draw_glyphs (updated_window, output_cursor.x,
20077 updated_row, updated_area,
20078 hpos, hpos + len,
20079 DRAW_NORMAL_TEXT, 0);
20080
20081 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
20082 if (updated_area == TEXT_AREA
20083 && updated_window->phys_cursor_on_p
20084 && updated_window->phys_cursor.vpos == output_cursor.vpos
20085 && updated_window->phys_cursor.hpos >= hpos
20086 && updated_window->phys_cursor.hpos < hpos + len)
20087 updated_window->phys_cursor_on_p = 0;
20088
20089 UNBLOCK_INPUT;
20090
20091 /* Advance the output cursor. */
20092 output_cursor.hpos += len;
20093 output_cursor.x = x;
20094 }
20095
20096
20097 /* EXPORT for RIF:
20098 Insert LEN glyphs from START at the nominal cursor position. */
20099
20100 void
20101 x_insert_glyphs (start, len)
20102 struct glyph *start;
20103 int len;
20104 {
20105 struct frame *f;
20106 struct window *w;
20107 int line_height, shift_by_width, shifted_region_width;
20108 struct glyph_row *row;
20109 struct glyph *glyph;
20110 int frame_x, frame_y, hpos;
20111
20112 xassert (updated_window && updated_row);
20113 BLOCK_INPUT;
20114 w = updated_window;
20115 f = XFRAME (WINDOW_FRAME (w));
20116
20117 /* Get the height of the line we are in. */
20118 row = updated_row;
20119 line_height = row->height;
20120
20121 /* Get the width of the glyphs to insert. */
20122 shift_by_width = 0;
20123 for (glyph = start; glyph < start + len; ++glyph)
20124 shift_by_width += glyph->pixel_width;
20125
20126 /* Get the width of the region to shift right. */
20127 shifted_region_width = (window_box_width (w, updated_area)
20128 - output_cursor.x
20129 - shift_by_width);
20130
20131 /* Shift right. */
20132 frame_x = window_box_left (w, updated_area) + output_cursor.x;
20133 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
20134
20135 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
20136 line_height, shift_by_width);
20137
20138 /* Write the glyphs. */
20139 hpos = start - row->glyphs[updated_area];
20140 draw_glyphs (w, output_cursor.x, row, updated_area,
20141 hpos, hpos + len,
20142 DRAW_NORMAL_TEXT, 0);
20143
20144 /* Advance the output cursor. */
20145 output_cursor.hpos += len;
20146 output_cursor.x += shift_by_width;
20147 UNBLOCK_INPUT;
20148 }
20149
20150
20151 /* EXPORT for RIF:
20152 Erase the current text line from the nominal cursor position
20153 (inclusive) to pixel column TO_X (exclusive). The idea is that
20154 everything from TO_X onward is already erased.
20155
20156 TO_X is a pixel position relative to updated_area of
20157 updated_window. TO_X == -1 means clear to the end of this area. */
20158
20159 void
20160 x_clear_end_of_line (to_x)
20161 int to_x;
20162 {
20163 struct frame *f;
20164 struct window *w = updated_window;
20165 int max_x, min_y, max_y;
20166 int from_x, from_y, to_y;
20167
20168 xassert (updated_window && updated_row);
20169 f = XFRAME (w->frame);
20170
20171 if (updated_row->full_width_p)
20172 max_x = WINDOW_TOTAL_WIDTH (w);
20173 else
20174 max_x = window_box_width (w, updated_area);
20175 max_y = window_text_bottom_y (w);
20176
20177 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
20178 of window. For TO_X > 0, truncate to end of drawing area. */
20179 if (to_x == 0)
20180 return;
20181 else if (to_x < 0)
20182 to_x = max_x;
20183 else
20184 to_x = min (to_x, max_x);
20185
20186 to_y = min (max_y, output_cursor.y + updated_row->height);
20187
20188 /* Notice if the cursor will be cleared by this operation. */
20189 if (!updated_row->full_width_p)
20190 notice_overwritten_cursor (w, updated_area,
20191 output_cursor.x, -1,
20192 updated_row->y,
20193 MATRIX_ROW_BOTTOM_Y (updated_row));
20194
20195 from_x = output_cursor.x;
20196
20197 /* Translate to frame coordinates. */
20198 if (updated_row->full_width_p)
20199 {
20200 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
20201 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
20202 }
20203 else
20204 {
20205 int area_left = window_box_left (w, updated_area);
20206 from_x += area_left;
20207 to_x += area_left;
20208 }
20209
20210 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
20211 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
20212 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
20213
20214 /* Prevent inadvertently clearing to end of the X window. */
20215 if (to_x > from_x && to_y > from_y)
20216 {
20217 BLOCK_INPUT;
20218 rif->clear_frame_area (f, from_x, from_y,
20219 to_x - from_x, to_y - from_y);
20220 UNBLOCK_INPUT;
20221 }
20222 }
20223
20224 #endif /* HAVE_WINDOW_SYSTEM */
20225
20226
20227 \f
20228 /***********************************************************************
20229 Cursor types
20230 ***********************************************************************/
20231
20232 /* Value is the internal representation of the specified cursor type
20233 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
20234 of the bar cursor. */
20235
20236 static enum text_cursor_kinds
20237 get_specified_cursor_type (arg, width)
20238 Lisp_Object arg;
20239 int *width;
20240 {
20241 enum text_cursor_kinds type;
20242
20243 if (NILP (arg))
20244 return NO_CURSOR;
20245
20246 if (EQ (arg, Qbox))
20247 return FILLED_BOX_CURSOR;
20248
20249 if (EQ (arg, Qhollow))
20250 return HOLLOW_BOX_CURSOR;
20251
20252 if (EQ (arg, Qbar))
20253 {
20254 *width = 2;
20255 return BAR_CURSOR;
20256 }
20257
20258 if (CONSP (arg)
20259 && EQ (XCAR (arg), Qbar)
20260 && INTEGERP (XCDR (arg))
20261 && XINT (XCDR (arg)) >= 0)
20262 {
20263 *width = XINT (XCDR (arg));
20264 return BAR_CURSOR;
20265 }
20266
20267 if (EQ (arg, Qhbar))
20268 {
20269 *width = 2;
20270 return HBAR_CURSOR;
20271 }
20272
20273 if (CONSP (arg)
20274 && EQ (XCAR (arg), Qhbar)
20275 && INTEGERP (XCDR (arg))
20276 && XINT (XCDR (arg)) >= 0)
20277 {
20278 *width = XINT (XCDR (arg));
20279 return HBAR_CURSOR;
20280 }
20281
20282 /* Treat anything unknown as "hollow box cursor".
20283 It was bad to signal an error; people have trouble fixing
20284 .Xdefaults with Emacs, when it has something bad in it. */
20285 type = HOLLOW_BOX_CURSOR;
20286
20287 return type;
20288 }
20289
20290 /* Set the default cursor types for specified frame. */
20291 void
20292 set_frame_cursor_types (f, arg)
20293 struct frame *f;
20294 Lisp_Object arg;
20295 {
20296 int width;
20297 Lisp_Object tem;
20298
20299 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
20300 FRAME_CURSOR_WIDTH (f) = width;
20301
20302 /* By default, set up the blink-off state depending on the on-state. */
20303
20304 tem = Fassoc (arg, Vblink_cursor_alist);
20305 if (!NILP (tem))
20306 {
20307 FRAME_BLINK_OFF_CURSOR (f)
20308 = get_specified_cursor_type (XCDR (tem), &width);
20309 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
20310 }
20311 else
20312 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
20313 }
20314
20315
20316 /* Return the cursor we want to be displayed in window W. Return
20317 width of bar/hbar cursor through WIDTH arg. Return with
20318 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
20319 (i.e. if the `system caret' should track this cursor).
20320
20321 In a mini-buffer window, we want the cursor only to appear if we
20322 are reading input from this window. For the selected window, we
20323 want the cursor type given by the frame parameter or buffer local
20324 setting of cursor-type. If explicitly marked off, draw no cursor.
20325 In all other cases, we want a hollow box cursor. */
20326
20327 static enum text_cursor_kinds
20328 get_window_cursor_type (w, glyph, width, active_cursor)
20329 struct window *w;
20330 struct glyph *glyph;
20331 int *width;
20332 int *active_cursor;
20333 {
20334 struct frame *f = XFRAME (w->frame);
20335 struct buffer *b = XBUFFER (w->buffer);
20336 int cursor_type = DEFAULT_CURSOR;
20337 Lisp_Object alt_cursor;
20338 int non_selected = 0;
20339
20340 *active_cursor = 1;
20341
20342 /* Echo area */
20343 if (cursor_in_echo_area
20344 && FRAME_HAS_MINIBUF_P (f)
20345 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
20346 {
20347 if (w == XWINDOW (echo_area_window))
20348 {
20349 *width = FRAME_CURSOR_WIDTH (f);
20350 return FRAME_DESIRED_CURSOR (f);
20351 }
20352
20353 *active_cursor = 0;
20354 non_selected = 1;
20355 }
20356
20357 /* Nonselected window or nonselected frame. */
20358 else if (w != XWINDOW (f->selected_window)
20359 #ifdef HAVE_WINDOW_SYSTEM
20360 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
20361 #endif
20362 )
20363 {
20364 *active_cursor = 0;
20365
20366 if (MINI_WINDOW_P (w) && minibuf_level == 0)
20367 return NO_CURSOR;
20368
20369 non_selected = 1;
20370 }
20371
20372 /* Never display a cursor in a window in which cursor-type is nil. */
20373 if (NILP (b->cursor_type))
20374 return NO_CURSOR;
20375
20376 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
20377 if (non_selected)
20378 {
20379 alt_cursor = XBUFFER (w->buffer)->cursor_in_non_selected_windows;
20380 return get_specified_cursor_type (alt_cursor, width);
20381 }
20382
20383 /* Get the normal cursor type for this window. */
20384 if (EQ (b->cursor_type, Qt))
20385 {
20386 cursor_type = FRAME_DESIRED_CURSOR (f);
20387 *width = FRAME_CURSOR_WIDTH (f);
20388 }
20389 else
20390 cursor_type = get_specified_cursor_type (b->cursor_type, width);
20391
20392 /* Use normal cursor if not blinked off. */
20393 if (!w->cursor_off_p)
20394 {
20395 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
20396 if (cursor_type == FILLED_BOX_CURSOR)
20397 cursor_type = HOLLOW_BOX_CURSOR;
20398 }
20399 return cursor_type;
20400 }
20401
20402 /* Cursor is blinked off, so determine how to "toggle" it. */
20403
20404 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
20405 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
20406 return get_specified_cursor_type (XCDR (alt_cursor), width);
20407
20408 /* Then see if frame has specified a specific blink off cursor type. */
20409 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
20410 {
20411 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
20412 return FRAME_BLINK_OFF_CURSOR (f);
20413 }
20414
20415 #if 0
20416 /* Some people liked having a permanently visible blinking cursor,
20417 while others had very strong opinions against it. So it was
20418 decided to remove it. KFS 2003-09-03 */
20419
20420 /* Finally perform built-in cursor blinking:
20421 filled box <-> hollow box
20422 wide [h]bar <-> narrow [h]bar
20423 narrow [h]bar <-> no cursor
20424 other type <-> no cursor */
20425
20426 if (cursor_type == FILLED_BOX_CURSOR)
20427 return HOLLOW_BOX_CURSOR;
20428
20429 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
20430 {
20431 *width = 1;
20432 return cursor_type;
20433 }
20434 #endif
20435
20436 return NO_CURSOR;
20437 }
20438
20439
20440 #ifdef HAVE_WINDOW_SYSTEM
20441
20442 /* Notice when the text cursor of window W has been completely
20443 overwritten by a drawing operation that outputs glyphs in AREA
20444 starting at X0 and ending at X1 in the line starting at Y0 and
20445 ending at Y1. X coordinates are area-relative. X1 < 0 means all
20446 the rest of the line after X0 has been written. Y coordinates
20447 are window-relative. */
20448
20449 static void
20450 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
20451 struct window *w;
20452 enum glyph_row_area area;
20453 int x0, y0, x1, y1;
20454 {
20455 int cx0, cx1, cy0, cy1;
20456 struct glyph_row *row;
20457
20458 if (!w->phys_cursor_on_p)
20459 return;
20460 if (area != TEXT_AREA)
20461 return;
20462
20463 if (w->phys_cursor.vpos < 0
20464 || w->phys_cursor.vpos >= w->current_matrix->nrows
20465 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
20466 !(row->enabled_p && row->displays_text_p)))
20467 return;
20468
20469 if (row->cursor_in_fringe_p)
20470 {
20471 row->cursor_in_fringe_p = 0;
20472 draw_fringe_bitmap (w, row, 0);
20473 w->phys_cursor_on_p = 0;
20474 return;
20475 }
20476
20477 cx0 = w->phys_cursor.x;
20478 cx1 = cx0 + w->phys_cursor_width;
20479 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20480 return;
20481
20482 /* The cursor image will be completely removed from the
20483 screen if the output area intersects the cursor area in
20484 y-direction. When we draw in [y0 y1[, and some part of
20485 the cursor is at y < y0, that part must have been drawn
20486 before. When scrolling, the cursor is erased before
20487 actually scrolling, so we don't come here. When not
20488 scrolling, the rows above the old cursor row must have
20489 changed, and in this case these rows must have written
20490 over the cursor image.
20491
20492 Likewise if part of the cursor is below y1, with the
20493 exception of the cursor being in the first blank row at
20494 the buffer and window end because update_text_area
20495 doesn't draw that row. (Except when it does, but
20496 that's handled in update_text_area.) */
20497
20498 cy0 = w->phys_cursor.y;
20499 cy1 = cy0 + w->phys_cursor_height;
20500 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20501 return;
20502
20503 w->phys_cursor_on_p = 0;
20504 }
20505
20506 #endif /* HAVE_WINDOW_SYSTEM */
20507
20508 \f
20509 /************************************************************************
20510 Mouse Face
20511 ************************************************************************/
20512
20513 #ifdef HAVE_WINDOW_SYSTEM
20514
20515 /* EXPORT for RIF:
20516 Fix the display of area AREA of overlapping row ROW in window W. */
20517
20518 void
20519 x_fix_overlapping_area (w, row, area)
20520 struct window *w;
20521 struct glyph_row *row;
20522 enum glyph_row_area area;
20523 {
20524 int i, x;
20525
20526 BLOCK_INPUT;
20527
20528 x = 0;
20529 for (i = 0; i < row->used[area];)
20530 {
20531 if (row->glyphs[area][i].overlaps_vertically_p)
20532 {
20533 int start = i, start_x = x;
20534
20535 do
20536 {
20537 x += row->glyphs[area][i].pixel_width;
20538 ++i;
20539 }
20540 while (i < row->used[area]
20541 && row->glyphs[area][i].overlaps_vertically_p);
20542
20543 draw_glyphs (w, start_x, row, area,
20544 start, i,
20545 DRAW_NORMAL_TEXT, 1);
20546 }
20547 else
20548 {
20549 x += row->glyphs[area][i].pixel_width;
20550 ++i;
20551 }
20552 }
20553
20554 UNBLOCK_INPUT;
20555 }
20556
20557
20558 /* EXPORT:
20559 Draw the cursor glyph of window W in glyph row ROW. See the
20560 comment of draw_glyphs for the meaning of HL. */
20561
20562 void
20563 draw_phys_cursor_glyph (w, row, hl)
20564 struct window *w;
20565 struct glyph_row *row;
20566 enum draw_glyphs_face hl;
20567 {
20568 /* If cursor hpos is out of bounds, don't draw garbage. This can
20569 happen in mini-buffer windows when switching between echo area
20570 glyphs and mini-buffer. */
20571 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20572 {
20573 int on_p = w->phys_cursor_on_p;
20574 int x1;
20575 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20576 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20577 hl, 0);
20578 w->phys_cursor_on_p = on_p;
20579
20580 if (hl == DRAW_CURSOR)
20581 w->phys_cursor_width = x1 - w->phys_cursor.x;
20582 /* When we erase the cursor, and ROW is overlapped by other
20583 rows, make sure that these overlapping parts of other rows
20584 are redrawn. */
20585 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20586 {
20587 if (row > w->current_matrix->rows
20588 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20589 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20590
20591 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20592 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20593 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20594 }
20595 }
20596 }
20597
20598
20599 /* EXPORT:
20600 Erase the image of a cursor of window W from the screen. */
20601
20602 void
20603 erase_phys_cursor (w)
20604 struct window *w;
20605 {
20606 struct frame *f = XFRAME (w->frame);
20607 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20608 int hpos = w->phys_cursor.hpos;
20609 int vpos = w->phys_cursor.vpos;
20610 int mouse_face_here_p = 0;
20611 struct glyph_matrix *active_glyphs = w->current_matrix;
20612 struct glyph_row *cursor_row;
20613 struct glyph *cursor_glyph;
20614 enum draw_glyphs_face hl;
20615
20616 /* No cursor displayed or row invalidated => nothing to do on the
20617 screen. */
20618 if (w->phys_cursor_type == NO_CURSOR)
20619 goto mark_cursor_off;
20620
20621 /* VPOS >= active_glyphs->nrows means that window has been resized.
20622 Don't bother to erase the cursor. */
20623 if (vpos >= active_glyphs->nrows)
20624 goto mark_cursor_off;
20625
20626 /* If row containing cursor is marked invalid, there is nothing we
20627 can do. */
20628 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20629 if (!cursor_row->enabled_p)
20630 goto mark_cursor_off;
20631
20632 /* If line spacing is > 0, old cursor may only be partially visible in
20633 window after split-window. So adjust visible height. */
20634 cursor_row->visible_height = min (cursor_row->visible_height,
20635 window_text_bottom_y (w) - cursor_row->y);
20636
20637 /* If row is completely invisible, don't attempt to delete a cursor which
20638 isn't there. This can happen if cursor is at top of a window, and
20639 we switch to a buffer with a header line in that window. */
20640 if (cursor_row->visible_height <= 0)
20641 goto mark_cursor_off;
20642
20643 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20644 if (cursor_row->cursor_in_fringe_p)
20645 {
20646 cursor_row->cursor_in_fringe_p = 0;
20647 draw_fringe_bitmap (w, cursor_row, 0);
20648 goto mark_cursor_off;
20649 }
20650
20651 /* This can happen when the new row is shorter than the old one.
20652 In this case, either draw_glyphs or clear_end_of_line
20653 should have cleared the cursor. Note that we wouldn't be
20654 able to erase the cursor in this case because we don't have a
20655 cursor glyph at hand. */
20656 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20657 goto mark_cursor_off;
20658
20659 /* If the cursor is in the mouse face area, redisplay that when
20660 we clear the cursor. */
20661 if (! NILP (dpyinfo->mouse_face_window)
20662 && w == XWINDOW (dpyinfo->mouse_face_window)
20663 && (vpos > dpyinfo->mouse_face_beg_row
20664 || (vpos == dpyinfo->mouse_face_beg_row
20665 && hpos >= dpyinfo->mouse_face_beg_col))
20666 && (vpos < dpyinfo->mouse_face_end_row
20667 || (vpos == dpyinfo->mouse_face_end_row
20668 && hpos < dpyinfo->mouse_face_end_col))
20669 /* Don't redraw the cursor's spot in mouse face if it is at the
20670 end of a line (on a newline). The cursor appears there, but
20671 mouse highlighting does not. */
20672 && cursor_row->used[TEXT_AREA] > hpos)
20673 mouse_face_here_p = 1;
20674
20675 /* Maybe clear the display under the cursor. */
20676 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20677 {
20678 int x, y;
20679 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20680 int width;
20681
20682 cursor_glyph = get_phys_cursor_glyph (w);
20683 if (cursor_glyph == NULL)
20684 goto mark_cursor_off;
20685
20686 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20687 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20688 width = min (cursor_glyph->pixel_width,
20689 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
20690
20691 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
20692 }
20693
20694 /* Erase the cursor by redrawing the character underneath it. */
20695 if (mouse_face_here_p)
20696 hl = DRAW_MOUSE_FACE;
20697 else
20698 hl = DRAW_NORMAL_TEXT;
20699 draw_phys_cursor_glyph (w, cursor_row, hl);
20700
20701 mark_cursor_off:
20702 w->phys_cursor_on_p = 0;
20703 w->phys_cursor_type = NO_CURSOR;
20704 }
20705
20706
20707 /* EXPORT:
20708 Display or clear cursor of window W. If ON is zero, clear the
20709 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20710 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20711
20712 void
20713 display_and_set_cursor (w, on, hpos, vpos, x, y)
20714 struct window *w;
20715 int on, hpos, vpos, x, y;
20716 {
20717 struct frame *f = XFRAME (w->frame);
20718 int new_cursor_type;
20719 int new_cursor_width;
20720 int active_cursor;
20721 struct glyph_row *glyph_row;
20722 struct glyph *glyph;
20723
20724 /* This is pointless on invisible frames, and dangerous on garbaged
20725 windows and frames; in the latter case, the frame or window may
20726 be in the midst of changing its size, and x and y may be off the
20727 window. */
20728 if (! FRAME_VISIBLE_P (f)
20729 || FRAME_GARBAGED_P (f)
20730 || vpos >= w->current_matrix->nrows
20731 || hpos >= w->current_matrix->matrix_w)
20732 return;
20733
20734 /* If cursor is off and we want it off, return quickly. */
20735 if (!on && !w->phys_cursor_on_p)
20736 return;
20737
20738 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20739 /* If cursor row is not enabled, we don't really know where to
20740 display the cursor. */
20741 if (!glyph_row->enabled_p)
20742 {
20743 w->phys_cursor_on_p = 0;
20744 return;
20745 }
20746
20747 glyph = NULL;
20748 if (!glyph_row->exact_window_width_line_p
20749 || hpos < glyph_row->used[TEXT_AREA])
20750 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20751
20752 xassert (interrupt_input_blocked);
20753
20754 /* Set new_cursor_type to the cursor we want to be displayed. */
20755 new_cursor_type = get_window_cursor_type (w, glyph,
20756 &new_cursor_width, &active_cursor);
20757
20758 /* If cursor is currently being shown and we don't want it to be or
20759 it is in the wrong place, or the cursor type is not what we want,
20760 erase it. */
20761 if (w->phys_cursor_on_p
20762 && (!on
20763 || w->phys_cursor.x != x
20764 || w->phys_cursor.y != y
20765 || new_cursor_type != w->phys_cursor_type
20766 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20767 && new_cursor_width != w->phys_cursor_width)))
20768 erase_phys_cursor (w);
20769
20770 /* Don't check phys_cursor_on_p here because that flag is only set
20771 to zero in some cases where we know that the cursor has been
20772 completely erased, to avoid the extra work of erasing the cursor
20773 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20774 still not be visible, or it has only been partly erased. */
20775 if (on)
20776 {
20777 w->phys_cursor_ascent = glyph_row->ascent;
20778 w->phys_cursor_height = glyph_row->height;
20779
20780 /* Set phys_cursor_.* before x_draw_.* is called because some
20781 of them may need the information. */
20782 w->phys_cursor.x = x;
20783 w->phys_cursor.y = glyph_row->y;
20784 w->phys_cursor.hpos = hpos;
20785 w->phys_cursor.vpos = vpos;
20786 }
20787
20788 rif->draw_window_cursor (w, glyph_row, x, y,
20789 new_cursor_type, new_cursor_width,
20790 on, active_cursor);
20791 }
20792
20793
20794 /* Switch the display of W's cursor on or off, according to the value
20795 of ON. */
20796
20797 static void
20798 update_window_cursor (w, on)
20799 struct window *w;
20800 int on;
20801 {
20802 /* Don't update cursor in windows whose frame is in the process
20803 of being deleted. */
20804 if (w->current_matrix)
20805 {
20806 BLOCK_INPUT;
20807 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20808 w->phys_cursor.x, w->phys_cursor.y);
20809 UNBLOCK_INPUT;
20810 }
20811 }
20812
20813
20814 /* Call update_window_cursor with parameter ON_P on all leaf windows
20815 in the window tree rooted at W. */
20816
20817 static void
20818 update_cursor_in_window_tree (w, on_p)
20819 struct window *w;
20820 int on_p;
20821 {
20822 while (w)
20823 {
20824 if (!NILP (w->hchild))
20825 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20826 else if (!NILP (w->vchild))
20827 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20828 else
20829 update_window_cursor (w, on_p);
20830
20831 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20832 }
20833 }
20834
20835
20836 /* EXPORT:
20837 Display the cursor on window W, or clear it, according to ON_P.
20838 Don't change the cursor's position. */
20839
20840 void
20841 x_update_cursor (f, on_p)
20842 struct frame *f;
20843 int on_p;
20844 {
20845 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20846 }
20847
20848
20849 /* EXPORT:
20850 Clear the cursor of window W to background color, and mark the
20851 cursor as not shown. This is used when the text where the cursor
20852 is is about to be rewritten. */
20853
20854 void
20855 x_clear_cursor (w)
20856 struct window *w;
20857 {
20858 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20859 update_window_cursor (w, 0);
20860 }
20861
20862
20863 /* EXPORT:
20864 Display the active region described by mouse_face_* according to DRAW. */
20865
20866 void
20867 show_mouse_face (dpyinfo, draw)
20868 Display_Info *dpyinfo;
20869 enum draw_glyphs_face draw;
20870 {
20871 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20872 struct frame *f = XFRAME (WINDOW_FRAME (w));
20873
20874 if (/* If window is in the process of being destroyed, don't bother
20875 to do anything. */
20876 w->current_matrix != NULL
20877 /* Don't update mouse highlight if hidden */
20878 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20879 /* Recognize when we are called to operate on rows that don't exist
20880 anymore. This can happen when a window is split. */
20881 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20882 {
20883 int phys_cursor_on_p = w->phys_cursor_on_p;
20884 struct glyph_row *row, *first, *last;
20885
20886 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20887 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20888
20889 for (row = first; row <= last && row->enabled_p; ++row)
20890 {
20891 int start_hpos, end_hpos, start_x;
20892
20893 /* For all but the first row, the highlight starts at column 0. */
20894 if (row == first)
20895 {
20896 start_hpos = dpyinfo->mouse_face_beg_col;
20897 start_x = dpyinfo->mouse_face_beg_x;
20898 }
20899 else
20900 {
20901 start_hpos = 0;
20902 start_x = 0;
20903 }
20904
20905 if (row == last)
20906 end_hpos = dpyinfo->mouse_face_end_col;
20907 else
20908 end_hpos = row->used[TEXT_AREA];
20909
20910 if (end_hpos > start_hpos)
20911 {
20912 draw_glyphs (w, start_x, row, TEXT_AREA,
20913 start_hpos, end_hpos,
20914 draw, 0);
20915
20916 row->mouse_face_p
20917 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20918 }
20919 }
20920
20921 /* When we've written over the cursor, arrange for it to
20922 be displayed again. */
20923 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20924 {
20925 BLOCK_INPUT;
20926 display_and_set_cursor (w, 1,
20927 w->phys_cursor.hpos, w->phys_cursor.vpos,
20928 w->phys_cursor.x, w->phys_cursor.y);
20929 UNBLOCK_INPUT;
20930 }
20931 }
20932
20933 /* Change the mouse cursor. */
20934 if (draw == DRAW_NORMAL_TEXT)
20935 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20936 else if (draw == DRAW_MOUSE_FACE)
20937 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20938 else
20939 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20940 }
20941
20942 /* EXPORT:
20943 Clear out the mouse-highlighted active region.
20944 Redraw it un-highlighted first. Value is non-zero if mouse
20945 face was actually drawn unhighlighted. */
20946
20947 int
20948 clear_mouse_face (dpyinfo)
20949 Display_Info *dpyinfo;
20950 {
20951 int cleared = 0;
20952
20953 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20954 {
20955 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20956 cleared = 1;
20957 }
20958
20959 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20960 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20961 dpyinfo->mouse_face_window = Qnil;
20962 dpyinfo->mouse_face_overlay = Qnil;
20963 return cleared;
20964 }
20965
20966
20967 /* EXPORT:
20968 Non-zero if physical cursor of window W is within mouse face. */
20969
20970 int
20971 cursor_in_mouse_face_p (w)
20972 struct window *w;
20973 {
20974 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20975 int in_mouse_face = 0;
20976
20977 if (WINDOWP (dpyinfo->mouse_face_window)
20978 && XWINDOW (dpyinfo->mouse_face_window) == w)
20979 {
20980 int hpos = w->phys_cursor.hpos;
20981 int vpos = w->phys_cursor.vpos;
20982
20983 if (vpos >= dpyinfo->mouse_face_beg_row
20984 && vpos <= dpyinfo->mouse_face_end_row
20985 && (vpos > dpyinfo->mouse_face_beg_row
20986 || hpos >= dpyinfo->mouse_face_beg_col)
20987 && (vpos < dpyinfo->mouse_face_end_row
20988 || hpos < dpyinfo->mouse_face_end_col
20989 || dpyinfo->mouse_face_past_end))
20990 in_mouse_face = 1;
20991 }
20992
20993 return in_mouse_face;
20994 }
20995
20996
20997
20998 \f
20999 /* Find the glyph matrix position of buffer position CHARPOS in window
21000 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
21001 current glyphs must be up to date. If CHARPOS is above window
21002 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
21003 of last line in W. In the row containing CHARPOS, stop before glyphs
21004 having STOP as object. */
21005
21006 #if 1 /* This is a version of fast_find_position that's more correct
21007 in the presence of hscrolling, for example. I didn't install
21008 it right away because the problem fixed is minor, it failed
21009 in 20.x as well, and I think it's too risky to install
21010 so near the release of 21.1. 2001-09-25 gerd. */
21011
21012 static int
21013 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
21014 struct window *w;
21015 int charpos;
21016 int *hpos, *vpos, *x, *y;
21017 Lisp_Object stop;
21018 {
21019 struct glyph_row *row, *first;
21020 struct glyph *glyph, *end;
21021 int past_end = 0;
21022
21023 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21024 if (charpos < MATRIX_ROW_START_CHARPOS (first))
21025 {
21026 *x = first->x;
21027 *y = first->y;
21028 *hpos = 0;
21029 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
21030 return 1;
21031 }
21032
21033 row = row_containing_pos (w, charpos, first, NULL, 0);
21034 if (row == NULL)
21035 {
21036 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
21037 past_end = 1;
21038 }
21039
21040 /* If whole rows or last part of a row came from a display overlay,
21041 row_containing_pos will skip over such rows because their end pos
21042 equals the start pos of the overlay or interval.
21043
21044 Move back if we have a STOP object and previous row's
21045 end glyph came from STOP. */
21046 if (!NILP (stop))
21047 {
21048 struct glyph_row *prev;
21049 while ((prev = row - 1, prev >= first)
21050 && MATRIX_ROW_END_CHARPOS (prev) == charpos
21051 && prev->used[TEXT_AREA] > 0)
21052 {
21053 struct glyph *beg = prev->glyphs[TEXT_AREA];
21054 glyph = beg + prev->used[TEXT_AREA];
21055 while (--glyph >= beg
21056 && INTEGERP (glyph->object));
21057 if (glyph < beg
21058 || !EQ (stop, glyph->object))
21059 break;
21060 row = prev;
21061 }
21062 }
21063
21064 *x = row->x;
21065 *y = row->y;
21066 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
21067
21068 glyph = row->glyphs[TEXT_AREA];
21069 end = glyph + row->used[TEXT_AREA];
21070
21071 /* Skip over glyphs not having an object at the start of the row.
21072 These are special glyphs like truncation marks on terminal
21073 frames. */
21074 if (row->displays_text_p)
21075 while (glyph < end
21076 && INTEGERP (glyph->object)
21077 && !EQ (stop, glyph->object)
21078 && glyph->charpos < 0)
21079 {
21080 *x += glyph->pixel_width;
21081 ++glyph;
21082 }
21083
21084 while (glyph < end
21085 && !INTEGERP (glyph->object)
21086 && !EQ (stop, glyph->object)
21087 && (!BUFFERP (glyph->object)
21088 || glyph->charpos < charpos))
21089 {
21090 *x += glyph->pixel_width;
21091 ++glyph;
21092 }
21093
21094 *hpos = glyph - row->glyphs[TEXT_AREA];
21095 return !past_end;
21096 }
21097
21098 #else /* not 1 */
21099
21100 static int
21101 fast_find_position (w, pos, hpos, vpos, x, y, stop)
21102 struct window *w;
21103 int pos;
21104 int *hpos, *vpos, *x, *y;
21105 Lisp_Object stop;
21106 {
21107 int i;
21108 int lastcol;
21109 int maybe_next_line_p = 0;
21110 int line_start_position;
21111 int yb = window_text_bottom_y (w);
21112 struct glyph_row *row, *best_row;
21113 int row_vpos, best_row_vpos;
21114 int current_x;
21115
21116 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21117 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
21118
21119 while (row->y < yb)
21120 {
21121 if (row->used[TEXT_AREA])
21122 line_start_position = row->glyphs[TEXT_AREA]->charpos;
21123 else
21124 line_start_position = 0;
21125
21126 if (line_start_position > pos)
21127 break;
21128 /* If the position sought is the end of the buffer,
21129 don't include the blank lines at the bottom of the window. */
21130 else if (line_start_position == pos
21131 && pos == BUF_ZV (XBUFFER (w->buffer)))
21132 {
21133 maybe_next_line_p = 1;
21134 break;
21135 }
21136 else if (line_start_position > 0)
21137 {
21138 best_row = row;
21139 best_row_vpos = row_vpos;
21140 }
21141
21142 if (row->y + row->height >= yb)
21143 break;
21144
21145 ++row;
21146 ++row_vpos;
21147 }
21148
21149 /* Find the right column within BEST_ROW. */
21150 lastcol = 0;
21151 current_x = best_row->x;
21152 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
21153 {
21154 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
21155 int charpos = glyph->charpos;
21156
21157 if (BUFFERP (glyph->object))
21158 {
21159 if (charpos == pos)
21160 {
21161 *hpos = i;
21162 *vpos = best_row_vpos;
21163 *x = current_x;
21164 *y = best_row->y;
21165 return 1;
21166 }
21167 else if (charpos > pos)
21168 break;
21169 }
21170 else if (EQ (glyph->object, stop))
21171 break;
21172
21173 if (charpos > 0)
21174 lastcol = i;
21175 current_x += glyph->pixel_width;
21176 }
21177
21178 /* If we're looking for the end of the buffer,
21179 and we didn't find it in the line we scanned,
21180 use the start of the following line. */
21181 if (maybe_next_line_p)
21182 {
21183 ++best_row;
21184 ++best_row_vpos;
21185 lastcol = 0;
21186 current_x = best_row->x;
21187 }
21188
21189 *vpos = best_row_vpos;
21190 *hpos = lastcol + 1;
21191 *x = current_x;
21192 *y = best_row->y;
21193 return 0;
21194 }
21195
21196 #endif /* not 1 */
21197
21198
21199 /* Find the position of the glyph for position POS in OBJECT in
21200 window W's current matrix, and return in *X, *Y the pixel
21201 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
21202
21203 RIGHT_P non-zero means return the position of the right edge of the
21204 glyph, RIGHT_P zero means return the left edge position.
21205
21206 If no glyph for POS exists in the matrix, return the position of
21207 the glyph with the next smaller position that is in the matrix, if
21208 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
21209 exists in the matrix, return the position of the glyph with the
21210 next larger position in OBJECT.
21211
21212 Value is non-zero if a glyph was found. */
21213
21214 static int
21215 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
21216 struct window *w;
21217 int pos;
21218 Lisp_Object object;
21219 int *hpos, *vpos, *x, *y;
21220 int right_p;
21221 {
21222 int yb = window_text_bottom_y (w);
21223 struct glyph_row *r;
21224 struct glyph *best_glyph = NULL;
21225 struct glyph_row *best_row = NULL;
21226 int best_x = 0;
21227
21228 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
21229 r->enabled_p && r->y < yb;
21230 ++r)
21231 {
21232 struct glyph *g = r->glyphs[TEXT_AREA];
21233 struct glyph *e = g + r->used[TEXT_AREA];
21234 int gx;
21235
21236 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
21237 if (EQ (g->object, object))
21238 {
21239 if (g->charpos == pos)
21240 {
21241 best_glyph = g;
21242 best_x = gx;
21243 best_row = r;
21244 goto found;
21245 }
21246 else if (best_glyph == NULL
21247 || ((abs (g->charpos - pos)
21248 < abs (best_glyph->charpos - pos))
21249 && (right_p
21250 ? g->charpos < pos
21251 : g->charpos > pos)))
21252 {
21253 best_glyph = g;
21254 best_x = gx;
21255 best_row = r;
21256 }
21257 }
21258 }
21259
21260 found:
21261
21262 if (best_glyph)
21263 {
21264 *x = best_x;
21265 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
21266
21267 if (right_p)
21268 {
21269 *x += best_glyph->pixel_width;
21270 ++*hpos;
21271 }
21272
21273 *y = best_row->y;
21274 *vpos = best_row - w->current_matrix->rows;
21275 }
21276
21277 return best_glyph != NULL;
21278 }
21279
21280
21281 /* See if position X, Y is within a hot-spot of an image. */
21282
21283 static int
21284 on_hot_spot_p (hot_spot, x, y)
21285 Lisp_Object hot_spot;
21286 int x, y;
21287 {
21288 if (!CONSP (hot_spot))
21289 return 0;
21290
21291 if (EQ (XCAR (hot_spot), Qrect))
21292 {
21293 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
21294 Lisp_Object rect = XCDR (hot_spot);
21295 Lisp_Object tem;
21296 if (!CONSP (rect))
21297 return 0;
21298 if (!CONSP (XCAR (rect)))
21299 return 0;
21300 if (!CONSP (XCDR (rect)))
21301 return 0;
21302 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
21303 return 0;
21304 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
21305 return 0;
21306 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
21307 return 0;
21308 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
21309 return 0;
21310 return 1;
21311 }
21312 else if (EQ (XCAR (hot_spot), Qcircle))
21313 {
21314 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
21315 Lisp_Object circ = XCDR (hot_spot);
21316 Lisp_Object lr, lx0, ly0;
21317 if (CONSP (circ)
21318 && CONSP (XCAR (circ))
21319 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
21320 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
21321 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
21322 {
21323 double r = XFLOATINT (lr);
21324 double dx = XINT (lx0) - x;
21325 double dy = XINT (ly0) - y;
21326 return (dx * dx + dy * dy <= r * r);
21327 }
21328 }
21329 else if (EQ (XCAR (hot_spot), Qpoly))
21330 {
21331 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
21332 if (VECTORP (XCDR (hot_spot)))
21333 {
21334 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
21335 Lisp_Object *poly = v->contents;
21336 int n = v->size;
21337 int i;
21338 int inside = 0;
21339 Lisp_Object lx, ly;
21340 int x0, y0;
21341
21342 /* Need an even number of coordinates, and at least 3 edges. */
21343 if (n < 6 || n & 1)
21344 return 0;
21345
21346 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
21347 If count is odd, we are inside polygon. Pixels on edges
21348 may or may not be included depending on actual geometry of the
21349 polygon. */
21350 if ((lx = poly[n-2], !INTEGERP (lx))
21351 || (ly = poly[n-1], !INTEGERP (lx)))
21352 return 0;
21353 x0 = XINT (lx), y0 = XINT (ly);
21354 for (i = 0; i < n; i += 2)
21355 {
21356 int x1 = x0, y1 = y0;
21357 if ((lx = poly[i], !INTEGERP (lx))
21358 || (ly = poly[i+1], !INTEGERP (ly)))
21359 return 0;
21360 x0 = XINT (lx), y0 = XINT (ly);
21361
21362 /* Does this segment cross the X line? */
21363 if (x0 >= x)
21364 {
21365 if (x1 >= x)
21366 continue;
21367 }
21368 else if (x1 < x)
21369 continue;
21370 if (y > y0 && y > y1)
21371 continue;
21372 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
21373 inside = !inside;
21374 }
21375 return inside;
21376 }
21377 }
21378 /* If we don't understand the format, pretend we're not in the hot-spot. */
21379 return 0;
21380 }
21381
21382 Lisp_Object
21383 find_hot_spot (map, x, y)
21384 Lisp_Object map;
21385 int x, y;
21386 {
21387 while (CONSP (map))
21388 {
21389 if (CONSP (XCAR (map))
21390 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
21391 return XCAR (map);
21392 map = XCDR (map);
21393 }
21394
21395 return Qnil;
21396 }
21397
21398 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
21399 3, 3, 0,
21400 doc: /* Lookup in image map MAP coordinates X and Y.
21401 An image map is an alist where each element has the format (AREA ID PLIST).
21402 An AREA is specified as either a rectangle, a circle, or a polygon:
21403 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
21404 pixel coordinates of the upper left and bottom right corners.
21405 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
21406 and the radius of the circle; r may be a float or integer.
21407 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
21408 vector describes one corner in the polygon.
21409 Returns the alist element for the first matching AREA in MAP. */)
21410 (map, x, y)
21411 Lisp_Object map;
21412 Lisp_Object x, y;
21413 {
21414 if (NILP (map))
21415 return Qnil;
21416
21417 CHECK_NUMBER (x);
21418 CHECK_NUMBER (y);
21419
21420 return find_hot_spot (map, XINT (x), XINT (y));
21421 }
21422
21423
21424 /* Display frame CURSOR, optionally using shape defined by POINTER. */
21425 static void
21426 define_frame_cursor1 (f, cursor, pointer)
21427 struct frame *f;
21428 Cursor cursor;
21429 Lisp_Object pointer;
21430 {
21431 /* Do not change cursor shape while dragging mouse. */
21432 if (!NILP (do_mouse_tracking))
21433 return;
21434
21435 if (!NILP (pointer))
21436 {
21437 if (EQ (pointer, Qarrow))
21438 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21439 else if (EQ (pointer, Qhand))
21440 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
21441 else if (EQ (pointer, Qtext))
21442 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21443 else if (EQ (pointer, intern ("hdrag")))
21444 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21445 #ifdef HAVE_X_WINDOWS
21446 else if (EQ (pointer, intern ("vdrag")))
21447 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
21448 #endif
21449 else if (EQ (pointer, intern ("hourglass")))
21450 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
21451 else if (EQ (pointer, Qmodeline))
21452 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
21453 else
21454 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21455 }
21456
21457 if (cursor != No_Cursor)
21458 rif->define_frame_cursor (f, cursor);
21459 }
21460
21461 /* Take proper action when mouse has moved to the mode or header line
21462 or marginal area AREA of window W, x-position X and y-position Y.
21463 X is relative to the start of the text display area of W, so the
21464 width of bitmap areas and scroll bars must be subtracted to get a
21465 position relative to the start of the mode line. */
21466
21467 static void
21468 note_mode_line_or_margin_highlight (window, x, y, area)
21469 Lisp_Object window;
21470 int x, y;
21471 enum window_part area;
21472 {
21473 struct window *w = XWINDOW (window);
21474 struct frame *f = XFRAME (w->frame);
21475 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21476 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21477 Lisp_Object pointer = Qnil;
21478 int charpos, dx, dy, width, height;
21479 Lisp_Object string, object = Qnil;
21480 Lisp_Object pos, help;
21481
21482 Lisp_Object mouse_face;
21483 int original_x_pixel = x;
21484 struct glyph * glyph = NULL;
21485 struct glyph_row *row;
21486
21487 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
21488 {
21489 int x0;
21490 struct glyph *end;
21491
21492 string = mode_line_string (w, area, &x, &y, &charpos,
21493 &object, &dx, &dy, &width, &height);
21494
21495 row = (area == ON_MODE_LINE
21496 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
21497 : MATRIX_HEADER_LINE_ROW (w->current_matrix));
21498
21499 /* Find glyph */
21500 if (row->mode_line_p && row->enabled_p)
21501 {
21502 glyph = row->glyphs[TEXT_AREA];
21503 end = glyph + row->used[TEXT_AREA];
21504
21505 for (x0 = original_x_pixel;
21506 glyph < end && x0 >= glyph->pixel_width;
21507 ++glyph)
21508 x0 -= glyph->pixel_width;
21509
21510 if (glyph >= end)
21511 glyph = NULL;
21512 }
21513 }
21514 else
21515 {
21516 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
21517 string = marginal_area_string (w, area, &x, &y, &charpos,
21518 &object, &dx, &dy, &width, &height);
21519 }
21520
21521 help = Qnil;
21522
21523 if (IMAGEP (object))
21524 {
21525 Lisp_Object image_map, hotspot;
21526 if ((image_map = Fplist_get (XCDR (object), QCmap),
21527 !NILP (image_map))
21528 && (hotspot = find_hot_spot (image_map, dx, dy),
21529 CONSP (hotspot))
21530 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21531 {
21532 Lisp_Object area_id, plist;
21533
21534 area_id = XCAR (hotspot);
21535 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21536 If so, we could look for mouse-enter, mouse-leave
21537 properties in PLIST (and do something...). */
21538 hotspot = XCDR (hotspot);
21539 if (CONSP (hotspot)
21540 && (plist = XCAR (hotspot), CONSP (plist)))
21541 {
21542 pointer = Fplist_get (plist, Qpointer);
21543 if (NILP (pointer))
21544 pointer = Qhand;
21545 help = Fplist_get (plist, Qhelp_echo);
21546 if (!NILP (help))
21547 {
21548 help_echo_string = help;
21549 /* Is this correct? ++kfs */
21550 XSETWINDOW (help_echo_window, w);
21551 help_echo_object = w->buffer;
21552 help_echo_pos = charpos;
21553 }
21554 }
21555 }
21556 if (NILP (pointer))
21557 pointer = Fplist_get (XCDR (object), QCpointer);
21558 }
21559
21560 if (STRINGP (string))
21561 {
21562 pos = make_number (charpos);
21563 /* If we're on a string with `help-echo' text property, arrange
21564 for the help to be displayed. This is done by setting the
21565 global variable help_echo_string to the help string. */
21566 if (NILP (help))
21567 {
21568 help = Fget_text_property (pos, Qhelp_echo, string);
21569 if (!NILP (help))
21570 {
21571 help_echo_string = help;
21572 XSETWINDOW (help_echo_window, w);
21573 help_echo_object = string;
21574 help_echo_pos = charpos;
21575 }
21576 }
21577
21578 if (NILP (pointer))
21579 pointer = Fget_text_property (pos, Qpointer, string);
21580
21581 /* Change the mouse pointer according to what is under X/Y. */
21582 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
21583 {
21584 Lisp_Object map;
21585 map = Fget_text_property (pos, Qlocal_map, string);
21586 if (!KEYMAPP (map))
21587 map = Fget_text_property (pos, Qkeymap, string);
21588 if (!KEYMAPP (map))
21589 cursor = dpyinfo->vertical_scroll_bar_cursor;
21590 }
21591
21592 /* Change the mouse face according to what is under X/Y. */
21593 mouse_face = Fget_text_property (pos, Qmouse_face, string);
21594 if (!NILP (mouse_face)
21595 && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
21596 && glyph)
21597 {
21598 Lisp_Object b, e;
21599
21600 struct glyph * tmp_glyph;
21601
21602 int gpos;
21603 int gseq_length;
21604 int total_pixel_width;
21605 int ignore;
21606
21607 int vpos, hpos;
21608
21609 b = Fprevious_single_property_change (make_number (charpos + 1),
21610 Qmouse_face, string, Qnil);
21611 if (NILP (b))
21612 b = make_number (0);
21613
21614 e = Fnext_single_property_change (pos, Qmouse_face, string, Qnil);
21615 if (NILP (e))
21616 e = make_number (SCHARS (string));
21617
21618 /* Calculate the position(glyph position: GPOS) of GLYPH in
21619 displayed string. GPOS is different from CHARPOS.
21620
21621 CHARPOS is the position of glyph in internal string
21622 object. A mode line string format has structures which
21623 is converted to a flatten by emacs lisp interpreter.
21624 The internal string is an element of the structures.
21625 The displayed string is the flatten string. */
21626 for (tmp_glyph = glyph - 1, gpos = 0;
21627 tmp_glyph->charpos >= XINT (b);
21628 tmp_glyph--, gpos++)
21629 {
21630 if (!EQ (tmp_glyph->object, glyph->object))
21631 break;
21632 }
21633
21634 /* Calculate the lenght(glyph sequence length: GSEQ_LENGTH) of
21635 displayed string holding GLYPH.
21636
21637 GSEQ_LENGTH is different from SCHARS (STRING).
21638 SCHARS (STRING) returns the length of the internal string. */
21639 for (tmp_glyph = glyph, gseq_length = gpos;
21640 tmp_glyph->charpos < XINT (e);
21641 tmp_glyph++, gseq_length++)
21642 {
21643 if (!EQ (tmp_glyph->object, glyph->object))
21644 break;
21645 }
21646
21647 total_pixel_width = 0;
21648 for (tmp_glyph = glyph - gpos; tmp_glyph != glyph; tmp_glyph++)
21649 total_pixel_width += tmp_glyph->pixel_width;
21650
21651 /* Pre calculation of re-rendering position */
21652 vpos = (x - gpos);
21653 hpos = (area == ON_MODE_LINE
21654 ? (w->current_matrix)->nrows - 1
21655 : 0);
21656
21657 /* If the re-rendering position is included in the last
21658 re-rendering area, we should do nothing. */
21659 if ( EQ (window, dpyinfo->mouse_face_window)
21660 && dpyinfo->mouse_face_beg_col <= vpos
21661 && vpos < dpyinfo->mouse_face_end_col
21662 && dpyinfo->mouse_face_beg_row == hpos )
21663 return;
21664
21665 if (clear_mouse_face (dpyinfo))
21666 cursor = No_Cursor;
21667
21668 dpyinfo->mouse_face_beg_col = vpos;
21669 dpyinfo->mouse_face_beg_row = hpos;
21670
21671 dpyinfo->mouse_face_beg_x = original_x_pixel - (total_pixel_width + dx);
21672 dpyinfo->mouse_face_beg_y = 0;
21673
21674 dpyinfo->mouse_face_end_col = vpos + gseq_length;
21675 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_beg_row;
21676
21677 dpyinfo->mouse_face_end_x = 0;
21678 dpyinfo->mouse_face_end_y = 0;
21679
21680 dpyinfo->mouse_face_past_end = 0;
21681 dpyinfo->mouse_face_window = window;
21682
21683 dpyinfo->mouse_face_face_id = face_at_string_position (w, string,
21684 charpos,
21685 0, 0, 0, &ignore,
21686 glyph->face_id, 1);
21687 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21688
21689 if (NILP (pointer))
21690 pointer = Qhand;
21691 }
21692 else if ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE))
21693 clear_mouse_face (dpyinfo);
21694 }
21695 define_frame_cursor1 (f, cursor, pointer);
21696 }
21697
21698
21699 /* EXPORT:
21700 Take proper action when the mouse has moved to position X, Y on
21701 frame F as regards highlighting characters that have mouse-face
21702 properties. Also de-highlighting chars where the mouse was before.
21703 X and Y can be negative or out of range. */
21704
21705 void
21706 note_mouse_highlight (f, x, y)
21707 struct frame *f;
21708 int x, y;
21709 {
21710 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21711 enum window_part part;
21712 Lisp_Object window;
21713 struct window *w;
21714 Cursor cursor = No_Cursor;
21715 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21716 struct buffer *b;
21717
21718 /* When a menu is active, don't highlight because this looks odd. */
21719 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21720 if (popup_activated ())
21721 return;
21722 #endif
21723
21724 if (NILP (Vmouse_highlight)
21725 || !f->glyphs_initialized_p)
21726 return;
21727
21728 dpyinfo->mouse_face_mouse_x = x;
21729 dpyinfo->mouse_face_mouse_y = y;
21730 dpyinfo->mouse_face_mouse_frame = f;
21731
21732 if (dpyinfo->mouse_face_defer)
21733 return;
21734
21735 if (gc_in_progress)
21736 {
21737 dpyinfo->mouse_face_deferred_gc = 1;
21738 return;
21739 }
21740
21741 /* Which window is that in? */
21742 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21743
21744 /* If we were displaying active text in another window, clear that.
21745 Also clear if we move out of text area in same window. */
21746 if (! EQ (window, dpyinfo->mouse_face_window)
21747 || (part != ON_TEXT && part != ON_MODE_LINE && part != ON_HEADER_LINE
21748 && !NILP (dpyinfo->mouse_face_window)))
21749 clear_mouse_face (dpyinfo);
21750
21751 /* Not on a window -> return. */
21752 if (!WINDOWP (window))
21753 return;
21754
21755 /* Reset help_echo_string. It will get recomputed below. */
21756 help_echo_string = Qnil;
21757
21758 /* Convert to window-relative pixel coordinates. */
21759 w = XWINDOW (window);
21760 frame_to_window_pixel_xy (w, &x, &y);
21761
21762 /* Handle tool-bar window differently since it doesn't display a
21763 buffer. */
21764 if (EQ (window, f->tool_bar_window))
21765 {
21766 note_tool_bar_highlight (f, x, y);
21767 return;
21768 }
21769
21770 /* Mouse is on the mode, header line or margin? */
21771 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21772 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21773 {
21774 note_mode_line_or_margin_highlight (window, x, y, part);
21775 return;
21776 }
21777
21778 if (part == ON_VERTICAL_BORDER)
21779 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21780 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21781 || part == ON_SCROLL_BAR)
21782 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21783 else
21784 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21785
21786 /* Are we in a window whose display is up to date?
21787 And verify the buffer's text has not changed. */
21788 b = XBUFFER (w->buffer);
21789 if (part == ON_TEXT
21790 && EQ (w->window_end_valid, w->buffer)
21791 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21792 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21793 {
21794 int hpos, vpos, pos, i, dx, dy, area;
21795 struct glyph *glyph;
21796 Lisp_Object object;
21797 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21798 Lisp_Object *overlay_vec = NULL;
21799 int noverlays;
21800 struct buffer *obuf;
21801 int obegv, ozv, same_region;
21802
21803 /* Find the glyph under X/Y. */
21804 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21805
21806 /* Look for :pointer property on image. */
21807 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21808 {
21809 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21810 if (img != NULL && IMAGEP (img->spec))
21811 {
21812 Lisp_Object image_map, hotspot;
21813 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
21814 !NILP (image_map))
21815 && (hotspot = find_hot_spot (image_map,
21816 glyph->slice.x + dx,
21817 glyph->slice.y + dy),
21818 CONSP (hotspot))
21819 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21820 {
21821 Lisp_Object area_id, plist;
21822
21823 area_id = XCAR (hotspot);
21824 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21825 If so, we could look for mouse-enter, mouse-leave
21826 properties in PLIST (and do something...). */
21827 hotspot = XCDR (hotspot);
21828 if (CONSP (hotspot)
21829 && (plist = XCAR (hotspot), CONSP (plist)))
21830 {
21831 pointer = Fplist_get (plist, Qpointer);
21832 if (NILP (pointer))
21833 pointer = Qhand;
21834 help_echo_string = Fplist_get (plist, Qhelp_echo);
21835 if (!NILP (help_echo_string))
21836 {
21837 help_echo_window = window;
21838 help_echo_object = glyph->object;
21839 help_echo_pos = glyph->charpos;
21840 }
21841 }
21842 }
21843 if (NILP (pointer))
21844 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21845 }
21846 }
21847
21848 /* Clear mouse face if X/Y not over text. */
21849 if (glyph == NULL
21850 || area != TEXT_AREA
21851 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21852 {
21853 if (clear_mouse_face (dpyinfo))
21854 cursor = No_Cursor;
21855 if (NILP (pointer))
21856 {
21857 if (area != TEXT_AREA)
21858 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21859 else
21860 pointer = Vvoid_text_area_pointer;
21861 }
21862 goto set_cursor;
21863 }
21864
21865 pos = glyph->charpos;
21866 object = glyph->object;
21867 if (!STRINGP (object) && !BUFFERP (object))
21868 goto set_cursor;
21869
21870 /* If we get an out-of-range value, return now; avoid an error. */
21871 if (BUFFERP (object) && pos > BUF_Z (b))
21872 goto set_cursor;
21873
21874 /* Make the window's buffer temporarily current for
21875 overlays_at and compute_char_face. */
21876 obuf = current_buffer;
21877 current_buffer = b;
21878 obegv = BEGV;
21879 ozv = ZV;
21880 BEGV = BEG;
21881 ZV = Z;
21882
21883 /* Is this char mouse-active or does it have help-echo? */
21884 position = make_number (pos);
21885
21886 if (BUFFERP (object))
21887 {
21888 /* Put all the overlays we want in a vector in overlay_vec. */
21889 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21890 /* Sort overlays into increasing priority order. */
21891 noverlays = sort_overlays (overlay_vec, noverlays, w);
21892 }
21893 else
21894 noverlays = 0;
21895
21896 same_region = (EQ (window, dpyinfo->mouse_face_window)
21897 && vpos >= dpyinfo->mouse_face_beg_row
21898 && vpos <= dpyinfo->mouse_face_end_row
21899 && (vpos > dpyinfo->mouse_face_beg_row
21900 || hpos >= dpyinfo->mouse_face_beg_col)
21901 && (vpos < dpyinfo->mouse_face_end_row
21902 || hpos < dpyinfo->mouse_face_end_col
21903 || dpyinfo->mouse_face_past_end));
21904
21905 if (same_region)
21906 cursor = No_Cursor;
21907
21908 /* Check mouse-face highlighting. */
21909 if (! same_region
21910 /* If there exists an overlay with mouse-face overlapping
21911 the one we are currently highlighting, we have to
21912 check if we enter the overlapping overlay, and then
21913 highlight only that. */
21914 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21915 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21916 {
21917 /* Find the highest priority overlay that has a mouse-face
21918 property. */
21919 overlay = Qnil;
21920 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21921 {
21922 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21923 if (!NILP (mouse_face))
21924 overlay = overlay_vec[i];
21925 }
21926
21927 /* If we're actually highlighting the same overlay as
21928 before, there's no need to do that again. */
21929 if (!NILP (overlay)
21930 && EQ (overlay, dpyinfo->mouse_face_overlay))
21931 goto check_help_echo;
21932
21933 dpyinfo->mouse_face_overlay = overlay;
21934
21935 /* Clear the display of the old active region, if any. */
21936 if (clear_mouse_face (dpyinfo))
21937 cursor = No_Cursor;
21938
21939 /* If no overlay applies, get a text property. */
21940 if (NILP (overlay))
21941 mouse_face = Fget_text_property (position, Qmouse_face, object);
21942
21943 /* Handle the overlay case. */
21944 if (!NILP (overlay))
21945 {
21946 /* Find the range of text around this char that
21947 should be active. */
21948 Lisp_Object before, after;
21949 int ignore;
21950
21951 before = Foverlay_start (overlay);
21952 after = Foverlay_end (overlay);
21953 /* Record this as the current active region. */
21954 fast_find_position (w, XFASTINT (before),
21955 &dpyinfo->mouse_face_beg_col,
21956 &dpyinfo->mouse_face_beg_row,
21957 &dpyinfo->mouse_face_beg_x,
21958 &dpyinfo->mouse_face_beg_y, Qnil);
21959
21960 dpyinfo->mouse_face_past_end
21961 = !fast_find_position (w, XFASTINT (after),
21962 &dpyinfo->mouse_face_end_col,
21963 &dpyinfo->mouse_face_end_row,
21964 &dpyinfo->mouse_face_end_x,
21965 &dpyinfo->mouse_face_end_y, Qnil);
21966 dpyinfo->mouse_face_window = window;
21967
21968 dpyinfo->mouse_face_face_id
21969 = face_at_buffer_position (w, pos, 0, 0,
21970 &ignore, pos + 1,
21971 !dpyinfo->mouse_face_hidden);
21972
21973 /* Display it as active. */
21974 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21975 cursor = No_Cursor;
21976 }
21977 /* Handle the text property case. */
21978 else if (!NILP (mouse_face) && BUFFERP (object))
21979 {
21980 /* Find the range of text around this char that
21981 should be active. */
21982 Lisp_Object before, after, beginning, end;
21983 int ignore;
21984
21985 beginning = Fmarker_position (w->start);
21986 end = make_number (BUF_Z (XBUFFER (object))
21987 - XFASTINT (w->window_end_pos));
21988 before
21989 = Fprevious_single_property_change (make_number (pos + 1),
21990 Qmouse_face,
21991 object, beginning);
21992 after
21993 = Fnext_single_property_change (position, Qmouse_face,
21994 object, end);
21995
21996 /* Record this as the current active region. */
21997 fast_find_position (w, XFASTINT (before),
21998 &dpyinfo->mouse_face_beg_col,
21999 &dpyinfo->mouse_face_beg_row,
22000 &dpyinfo->mouse_face_beg_x,
22001 &dpyinfo->mouse_face_beg_y, Qnil);
22002 dpyinfo->mouse_face_past_end
22003 = !fast_find_position (w, XFASTINT (after),
22004 &dpyinfo->mouse_face_end_col,
22005 &dpyinfo->mouse_face_end_row,
22006 &dpyinfo->mouse_face_end_x,
22007 &dpyinfo->mouse_face_end_y, Qnil);
22008 dpyinfo->mouse_face_window = window;
22009
22010 if (BUFFERP (object))
22011 dpyinfo->mouse_face_face_id
22012 = face_at_buffer_position (w, pos, 0, 0,
22013 &ignore, pos + 1,
22014 !dpyinfo->mouse_face_hidden);
22015
22016 /* Display it as active. */
22017 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22018 cursor = No_Cursor;
22019 }
22020 else if (!NILP (mouse_face) && STRINGP (object))
22021 {
22022 Lisp_Object b, e;
22023 int ignore;
22024
22025 b = Fprevious_single_property_change (make_number (pos + 1),
22026 Qmouse_face,
22027 object, Qnil);
22028 e = Fnext_single_property_change (position, Qmouse_face,
22029 object, Qnil);
22030 if (NILP (b))
22031 b = make_number (0);
22032 if (NILP (e))
22033 e = make_number (SCHARS (object) - 1);
22034
22035 fast_find_string_pos (w, XINT (b), object,
22036 &dpyinfo->mouse_face_beg_col,
22037 &dpyinfo->mouse_face_beg_row,
22038 &dpyinfo->mouse_face_beg_x,
22039 &dpyinfo->mouse_face_beg_y, 0);
22040 fast_find_string_pos (w, XINT (e), object,
22041 &dpyinfo->mouse_face_end_col,
22042 &dpyinfo->mouse_face_end_row,
22043 &dpyinfo->mouse_face_end_x,
22044 &dpyinfo->mouse_face_end_y, 1);
22045 dpyinfo->mouse_face_past_end = 0;
22046 dpyinfo->mouse_face_window = window;
22047 dpyinfo->mouse_face_face_id
22048 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
22049 glyph->face_id, 1);
22050 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22051 cursor = No_Cursor;
22052 }
22053 else if (STRINGP (object) && NILP (mouse_face))
22054 {
22055 /* A string which doesn't have mouse-face, but
22056 the text ``under'' it might have. */
22057 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
22058 int start = MATRIX_ROW_START_CHARPOS (r);
22059
22060 pos = string_buffer_position (w, object, start);
22061 if (pos > 0)
22062 mouse_face = get_char_property_and_overlay (make_number (pos),
22063 Qmouse_face,
22064 w->buffer,
22065 &overlay);
22066 if (!NILP (mouse_face) && !NILP (overlay))
22067 {
22068 Lisp_Object before = Foverlay_start (overlay);
22069 Lisp_Object after = Foverlay_end (overlay);
22070 int ignore;
22071
22072 /* Note that we might not be able to find position
22073 BEFORE in the glyph matrix if the overlay is
22074 entirely covered by a `display' property. In
22075 this case, we overshoot. So let's stop in
22076 the glyph matrix before glyphs for OBJECT. */
22077 fast_find_position (w, XFASTINT (before),
22078 &dpyinfo->mouse_face_beg_col,
22079 &dpyinfo->mouse_face_beg_row,
22080 &dpyinfo->mouse_face_beg_x,
22081 &dpyinfo->mouse_face_beg_y,
22082 object);
22083
22084 dpyinfo->mouse_face_past_end
22085 = !fast_find_position (w, XFASTINT (after),
22086 &dpyinfo->mouse_face_end_col,
22087 &dpyinfo->mouse_face_end_row,
22088 &dpyinfo->mouse_face_end_x,
22089 &dpyinfo->mouse_face_end_y,
22090 Qnil);
22091 dpyinfo->mouse_face_window = window;
22092 dpyinfo->mouse_face_face_id
22093 = face_at_buffer_position (w, pos, 0, 0,
22094 &ignore, pos + 1,
22095 !dpyinfo->mouse_face_hidden);
22096
22097 /* Display it as active. */
22098 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
22099 cursor = No_Cursor;
22100 }
22101 }
22102 }
22103
22104 check_help_echo:
22105
22106 /* Look for a `help-echo' property. */
22107 if (NILP (help_echo_string)) {
22108 Lisp_Object help, overlay;
22109
22110 /* Check overlays first. */
22111 help = overlay = Qnil;
22112 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
22113 {
22114 overlay = overlay_vec[i];
22115 help = Foverlay_get (overlay, Qhelp_echo);
22116 }
22117
22118 if (!NILP (help))
22119 {
22120 help_echo_string = help;
22121 help_echo_window = window;
22122 help_echo_object = overlay;
22123 help_echo_pos = pos;
22124 }
22125 else
22126 {
22127 Lisp_Object object = glyph->object;
22128 int charpos = glyph->charpos;
22129
22130 /* Try text properties. */
22131 if (STRINGP (object)
22132 && charpos >= 0
22133 && charpos < SCHARS (object))
22134 {
22135 help = Fget_text_property (make_number (charpos),
22136 Qhelp_echo, object);
22137 if (NILP (help))
22138 {
22139 /* If the string itself doesn't specify a help-echo,
22140 see if the buffer text ``under'' it does. */
22141 struct glyph_row *r
22142 = MATRIX_ROW (w->current_matrix, vpos);
22143 int start = MATRIX_ROW_START_CHARPOS (r);
22144 int pos = string_buffer_position (w, object, start);
22145 if (pos > 0)
22146 {
22147 help = Fget_char_property (make_number (pos),
22148 Qhelp_echo, w->buffer);
22149 if (!NILP (help))
22150 {
22151 charpos = pos;
22152 object = w->buffer;
22153 }
22154 }
22155 }
22156 }
22157 else if (BUFFERP (object)
22158 && charpos >= BEGV
22159 && charpos < ZV)
22160 help = Fget_text_property (make_number (charpos), Qhelp_echo,
22161 object);
22162
22163 if (!NILP (help))
22164 {
22165 help_echo_string = help;
22166 help_echo_window = window;
22167 help_echo_object = object;
22168 help_echo_pos = charpos;
22169 }
22170 }
22171 }
22172
22173 /* Look for a `pointer' property. */
22174 if (NILP (pointer))
22175 {
22176 /* Check overlays first. */
22177 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
22178 pointer = Foverlay_get (overlay_vec[i], Qpointer);
22179
22180 if (NILP (pointer))
22181 {
22182 Lisp_Object object = glyph->object;
22183 int charpos = glyph->charpos;
22184
22185 /* Try text properties. */
22186 if (STRINGP (object)
22187 && charpos >= 0
22188 && charpos < SCHARS (object))
22189 {
22190 pointer = Fget_text_property (make_number (charpos),
22191 Qpointer, object);
22192 if (NILP (pointer))
22193 {
22194 /* If the string itself doesn't specify a pointer,
22195 see if the buffer text ``under'' it does. */
22196 struct glyph_row *r
22197 = MATRIX_ROW (w->current_matrix, vpos);
22198 int start = MATRIX_ROW_START_CHARPOS (r);
22199 int pos = string_buffer_position (w, object, start);
22200 if (pos > 0)
22201 pointer = Fget_char_property (make_number (pos),
22202 Qpointer, w->buffer);
22203 }
22204 }
22205 else if (BUFFERP (object)
22206 && charpos >= BEGV
22207 && charpos < ZV)
22208 pointer = Fget_text_property (make_number (charpos),
22209 Qpointer, object);
22210 }
22211 }
22212
22213 BEGV = obegv;
22214 ZV = ozv;
22215 current_buffer = obuf;
22216 }
22217
22218 set_cursor:
22219
22220 define_frame_cursor1 (f, cursor, pointer);
22221 }
22222
22223
22224 /* EXPORT for RIF:
22225 Clear any mouse-face on window W. This function is part of the
22226 redisplay interface, and is called from try_window_id and similar
22227 functions to ensure the mouse-highlight is off. */
22228
22229 void
22230 x_clear_window_mouse_face (w)
22231 struct window *w;
22232 {
22233 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
22234 Lisp_Object window;
22235
22236 BLOCK_INPUT;
22237 XSETWINDOW (window, w);
22238 if (EQ (window, dpyinfo->mouse_face_window))
22239 clear_mouse_face (dpyinfo);
22240 UNBLOCK_INPUT;
22241 }
22242
22243
22244 /* EXPORT:
22245 Just discard the mouse face information for frame F, if any.
22246 This is used when the size of F is changed. */
22247
22248 void
22249 cancel_mouse_face (f)
22250 struct frame *f;
22251 {
22252 Lisp_Object window;
22253 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22254
22255 window = dpyinfo->mouse_face_window;
22256 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
22257 {
22258 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
22259 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
22260 dpyinfo->mouse_face_window = Qnil;
22261 }
22262 }
22263
22264
22265 #endif /* HAVE_WINDOW_SYSTEM */
22266
22267 \f
22268 /***********************************************************************
22269 Exposure Events
22270 ***********************************************************************/
22271
22272 #ifdef HAVE_WINDOW_SYSTEM
22273
22274 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
22275 which intersects rectangle R. R is in window-relative coordinates. */
22276
22277 static void
22278 expose_area (w, row, r, area)
22279 struct window *w;
22280 struct glyph_row *row;
22281 XRectangle *r;
22282 enum glyph_row_area area;
22283 {
22284 struct glyph *first = row->glyphs[area];
22285 struct glyph *end = row->glyphs[area] + row->used[area];
22286 struct glyph *last;
22287 int first_x, start_x, x;
22288
22289 if (area == TEXT_AREA && row->fill_line_p)
22290 /* If row extends face to end of line write the whole line. */
22291 draw_glyphs (w, 0, row, area,
22292 0, row->used[area],
22293 DRAW_NORMAL_TEXT, 0);
22294 else
22295 {
22296 /* Set START_X to the window-relative start position for drawing glyphs of
22297 AREA. The first glyph of the text area can be partially visible.
22298 The first glyphs of other areas cannot. */
22299 start_x = window_box_left_offset (w, area);
22300 x = start_x;
22301 if (area == TEXT_AREA)
22302 x += row->x;
22303
22304 /* Find the first glyph that must be redrawn. */
22305 while (first < end
22306 && x + first->pixel_width < r->x)
22307 {
22308 x += first->pixel_width;
22309 ++first;
22310 }
22311
22312 /* Find the last one. */
22313 last = first;
22314 first_x = x;
22315 while (last < end
22316 && x < r->x + r->width)
22317 {
22318 x += last->pixel_width;
22319 ++last;
22320 }
22321
22322 /* Repaint. */
22323 if (last > first)
22324 draw_glyphs (w, first_x - start_x, row, area,
22325 first - row->glyphs[area], last - row->glyphs[area],
22326 DRAW_NORMAL_TEXT, 0);
22327 }
22328 }
22329
22330
22331 /* Redraw the parts of the glyph row ROW on window W intersecting
22332 rectangle R. R is in window-relative coordinates. Value is
22333 non-zero if mouse-face was overwritten. */
22334
22335 static int
22336 expose_line (w, row, r)
22337 struct window *w;
22338 struct glyph_row *row;
22339 XRectangle *r;
22340 {
22341 xassert (row->enabled_p);
22342
22343 if (row->mode_line_p || w->pseudo_window_p)
22344 draw_glyphs (w, 0, row, TEXT_AREA,
22345 0, row->used[TEXT_AREA],
22346 DRAW_NORMAL_TEXT, 0);
22347 else
22348 {
22349 if (row->used[LEFT_MARGIN_AREA])
22350 expose_area (w, row, r, LEFT_MARGIN_AREA);
22351 if (row->used[TEXT_AREA])
22352 expose_area (w, row, r, TEXT_AREA);
22353 if (row->used[RIGHT_MARGIN_AREA])
22354 expose_area (w, row, r, RIGHT_MARGIN_AREA);
22355 draw_row_fringe_bitmaps (w, row);
22356 }
22357
22358 return row->mouse_face_p;
22359 }
22360
22361
22362 /* Redraw those parts of glyphs rows during expose event handling that
22363 overlap other rows. Redrawing of an exposed line writes over parts
22364 of lines overlapping that exposed line; this function fixes that.
22365
22366 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
22367 row in W's current matrix that is exposed and overlaps other rows.
22368 LAST_OVERLAPPING_ROW is the last such row. */
22369
22370 static void
22371 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
22372 struct window *w;
22373 struct glyph_row *first_overlapping_row;
22374 struct glyph_row *last_overlapping_row;
22375 {
22376 struct glyph_row *row;
22377
22378 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
22379 if (row->overlapping_p)
22380 {
22381 xassert (row->enabled_p && !row->mode_line_p);
22382
22383 if (row->used[LEFT_MARGIN_AREA])
22384 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
22385
22386 if (row->used[TEXT_AREA])
22387 x_fix_overlapping_area (w, row, TEXT_AREA);
22388
22389 if (row->used[RIGHT_MARGIN_AREA])
22390 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
22391 }
22392 }
22393
22394
22395 /* Return non-zero if W's cursor intersects rectangle R. */
22396
22397 static int
22398 phys_cursor_in_rect_p (w, r)
22399 struct window *w;
22400 XRectangle *r;
22401 {
22402 XRectangle cr, result;
22403 struct glyph *cursor_glyph;
22404
22405 cursor_glyph = get_phys_cursor_glyph (w);
22406 if (cursor_glyph)
22407 {
22408 /* r is relative to W's box, but w->phys_cursor.x is relative
22409 to left edge of W's TEXT area. Adjust it. */
22410 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
22411 cr.y = w->phys_cursor.y;
22412 cr.width = cursor_glyph->pixel_width;
22413 cr.height = w->phys_cursor_height;
22414 /* ++KFS: W32 version used W32-specific IntersectRect here, but
22415 I assume the effect is the same -- and this is portable. */
22416 return x_intersect_rectangles (&cr, r, &result);
22417 }
22418 else
22419 return 0;
22420 }
22421
22422
22423 /* EXPORT:
22424 Draw a vertical window border to the right of window W if W doesn't
22425 have vertical scroll bars. */
22426
22427 void
22428 x_draw_vertical_border (w)
22429 struct window *w;
22430 {
22431 /* We could do better, if we knew what type of scroll-bar the adjacent
22432 windows (on either side) have... But we don't :-(
22433 However, I think this works ok. ++KFS 2003-04-25 */
22434
22435 /* Redraw borders between horizontally adjacent windows. Don't
22436 do it for frames with vertical scroll bars because either the
22437 right scroll bar of a window, or the left scroll bar of its
22438 neighbor will suffice as a border. */
22439 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
22440 return;
22441
22442 if (!WINDOW_RIGHTMOST_P (w)
22443 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
22444 {
22445 int x0, x1, y0, y1;
22446
22447 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22448 y1 -= 1;
22449
22450 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
22451 x1 -= 1;
22452
22453 rif->draw_vertical_window_border (w, x1, y0, y1);
22454 }
22455 else if (!WINDOW_LEFTMOST_P (w)
22456 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
22457 {
22458 int x0, x1, y0, y1;
22459
22460 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22461 y1 -= 1;
22462
22463 if (WINDOW_LEFT_FRINGE_WIDTH (w) == 0)
22464 x0 -= 1;
22465
22466 rif->draw_vertical_window_border (w, x0, y0, y1);
22467 }
22468 }
22469
22470
22471 /* Redraw the part of window W intersection rectangle FR. Pixel
22472 coordinates in FR are frame-relative. Call this function with
22473 input blocked. Value is non-zero if the exposure overwrites
22474 mouse-face. */
22475
22476 static int
22477 expose_window (w, fr)
22478 struct window *w;
22479 XRectangle *fr;
22480 {
22481 struct frame *f = XFRAME (w->frame);
22482 XRectangle wr, r;
22483 int mouse_face_overwritten_p = 0;
22484
22485 /* If window is not yet fully initialized, do nothing. This can
22486 happen when toolkit scroll bars are used and a window is split.
22487 Reconfiguring the scroll bar will generate an expose for a newly
22488 created window. */
22489 if (w->current_matrix == NULL)
22490 return 0;
22491
22492 /* When we're currently updating the window, display and current
22493 matrix usually don't agree. Arrange for a thorough display
22494 later. */
22495 if (w == updated_window)
22496 {
22497 SET_FRAME_GARBAGED (f);
22498 return 0;
22499 }
22500
22501 /* Frame-relative pixel rectangle of W. */
22502 wr.x = WINDOW_LEFT_EDGE_X (w);
22503 wr.y = WINDOW_TOP_EDGE_Y (w);
22504 wr.width = WINDOW_TOTAL_WIDTH (w);
22505 wr.height = WINDOW_TOTAL_HEIGHT (w);
22506
22507 if (x_intersect_rectangles (fr, &wr, &r))
22508 {
22509 int yb = window_text_bottom_y (w);
22510 struct glyph_row *row;
22511 int cursor_cleared_p;
22512 struct glyph_row *first_overlapping_row, *last_overlapping_row;
22513
22514 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
22515 r.x, r.y, r.width, r.height));
22516
22517 /* Convert to window coordinates. */
22518 r.x -= WINDOW_LEFT_EDGE_X (w);
22519 r.y -= WINDOW_TOP_EDGE_Y (w);
22520
22521 /* Turn off the cursor. */
22522 if (!w->pseudo_window_p
22523 && phys_cursor_in_rect_p (w, &r))
22524 {
22525 x_clear_cursor (w);
22526 cursor_cleared_p = 1;
22527 }
22528 else
22529 cursor_cleared_p = 0;
22530
22531 /* Update lines intersecting rectangle R. */
22532 first_overlapping_row = last_overlapping_row = NULL;
22533 for (row = w->current_matrix->rows;
22534 row->enabled_p;
22535 ++row)
22536 {
22537 int y0 = row->y;
22538 int y1 = MATRIX_ROW_BOTTOM_Y (row);
22539
22540 if ((y0 >= r.y && y0 < r.y + r.height)
22541 || (y1 > r.y && y1 < r.y + r.height)
22542 || (r.y >= y0 && r.y < y1)
22543 || (r.y + r.height > y0 && r.y + r.height < y1))
22544 {
22545 /* A header line may be overlapping, but there is no need
22546 to fix overlapping areas for them. KFS 2005-02-12 */
22547 if (row->overlapping_p && !row->mode_line_p)
22548 {
22549 if (first_overlapping_row == NULL)
22550 first_overlapping_row = row;
22551 last_overlapping_row = row;
22552 }
22553
22554 if (expose_line (w, row, &r))
22555 mouse_face_overwritten_p = 1;
22556 }
22557
22558 if (y1 >= yb)
22559 break;
22560 }
22561
22562 /* Display the mode line if there is one. */
22563 if (WINDOW_WANTS_MODELINE_P (w)
22564 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
22565 row->enabled_p)
22566 && row->y < r.y + r.height)
22567 {
22568 if (expose_line (w, row, &r))
22569 mouse_face_overwritten_p = 1;
22570 }
22571
22572 if (!w->pseudo_window_p)
22573 {
22574 /* Fix the display of overlapping rows. */
22575 if (first_overlapping_row)
22576 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
22577
22578 /* Draw border between windows. */
22579 x_draw_vertical_border (w);
22580
22581 /* Turn the cursor on again. */
22582 if (cursor_cleared_p)
22583 update_window_cursor (w, 1);
22584 }
22585 }
22586
22587 return mouse_face_overwritten_p;
22588 }
22589
22590
22591
22592 /* Redraw (parts) of all windows in the window tree rooted at W that
22593 intersect R. R contains frame pixel coordinates. Value is
22594 non-zero if the exposure overwrites mouse-face. */
22595
22596 static int
22597 expose_window_tree (w, r)
22598 struct window *w;
22599 XRectangle *r;
22600 {
22601 struct frame *f = XFRAME (w->frame);
22602 int mouse_face_overwritten_p = 0;
22603
22604 while (w && !FRAME_GARBAGED_P (f))
22605 {
22606 if (!NILP (w->hchild))
22607 mouse_face_overwritten_p
22608 |= expose_window_tree (XWINDOW (w->hchild), r);
22609 else if (!NILP (w->vchild))
22610 mouse_face_overwritten_p
22611 |= expose_window_tree (XWINDOW (w->vchild), r);
22612 else
22613 mouse_face_overwritten_p |= expose_window (w, r);
22614
22615 w = NILP (w->next) ? NULL : XWINDOW (w->next);
22616 }
22617
22618 return mouse_face_overwritten_p;
22619 }
22620
22621
22622 /* EXPORT:
22623 Redisplay an exposed area of frame F. X and Y are the upper-left
22624 corner of the exposed rectangle. W and H are width and height of
22625 the exposed area. All are pixel values. W or H zero means redraw
22626 the entire frame. */
22627
22628 void
22629 expose_frame (f, x, y, w, h)
22630 struct frame *f;
22631 int x, y, w, h;
22632 {
22633 XRectangle r;
22634 int mouse_face_overwritten_p = 0;
22635
22636 TRACE ((stderr, "expose_frame "));
22637
22638 /* No need to redraw if frame will be redrawn soon. */
22639 if (FRAME_GARBAGED_P (f))
22640 {
22641 TRACE ((stderr, " garbaged\n"));
22642 return;
22643 }
22644
22645 /* If basic faces haven't been realized yet, there is no point in
22646 trying to redraw anything. This can happen when we get an expose
22647 event while Emacs is starting, e.g. by moving another window. */
22648 if (FRAME_FACE_CACHE (f) == NULL
22649 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
22650 {
22651 TRACE ((stderr, " no faces\n"));
22652 return;
22653 }
22654
22655 if (w == 0 || h == 0)
22656 {
22657 r.x = r.y = 0;
22658 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
22659 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
22660 }
22661 else
22662 {
22663 r.x = x;
22664 r.y = y;
22665 r.width = w;
22666 r.height = h;
22667 }
22668
22669 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
22670 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
22671
22672 if (WINDOWP (f->tool_bar_window))
22673 mouse_face_overwritten_p
22674 |= expose_window (XWINDOW (f->tool_bar_window), &r);
22675
22676 #ifdef HAVE_X_WINDOWS
22677 #ifndef MSDOS
22678 #ifndef USE_X_TOOLKIT
22679 if (WINDOWP (f->menu_bar_window))
22680 mouse_face_overwritten_p
22681 |= expose_window (XWINDOW (f->menu_bar_window), &r);
22682 #endif /* not USE_X_TOOLKIT */
22683 #endif
22684 #endif
22685
22686 /* Some window managers support a focus-follows-mouse style with
22687 delayed raising of frames. Imagine a partially obscured frame,
22688 and moving the mouse into partially obscured mouse-face on that
22689 frame. The visible part of the mouse-face will be highlighted,
22690 then the WM raises the obscured frame. With at least one WM, KDE
22691 2.1, Emacs is not getting any event for the raising of the frame
22692 (even tried with SubstructureRedirectMask), only Expose events.
22693 These expose events will draw text normally, i.e. not
22694 highlighted. Which means we must redo the highlight here.
22695 Subsume it under ``we love X''. --gerd 2001-08-15 */
22696 /* Included in Windows version because Windows most likely does not
22697 do the right thing if any third party tool offers
22698 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22699 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22700 {
22701 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22702 if (f == dpyinfo->mouse_face_mouse_frame)
22703 {
22704 int x = dpyinfo->mouse_face_mouse_x;
22705 int y = dpyinfo->mouse_face_mouse_y;
22706 clear_mouse_face (dpyinfo);
22707 note_mouse_highlight (f, x, y);
22708 }
22709 }
22710 }
22711
22712
22713 /* EXPORT:
22714 Determine the intersection of two rectangles R1 and R2. Return
22715 the intersection in *RESULT. Value is non-zero if RESULT is not
22716 empty. */
22717
22718 int
22719 x_intersect_rectangles (r1, r2, result)
22720 XRectangle *r1, *r2, *result;
22721 {
22722 XRectangle *left, *right;
22723 XRectangle *upper, *lower;
22724 int intersection_p = 0;
22725
22726 /* Rearrange so that R1 is the left-most rectangle. */
22727 if (r1->x < r2->x)
22728 left = r1, right = r2;
22729 else
22730 left = r2, right = r1;
22731
22732 /* X0 of the intersection is right.x0, if this is inside R1,
22733 otherwise there is no intersection. */
22734 if (right->x <= left->x + left->width)
22735 {
22736 result->x = right->x;
22737
22738 /* The right end of the intersection is the minimum of the
22739 the right ends of left and right. */
22740 result->width = (min (left->x + left->width, right->x + right->width)
22741 - result->x);
22742
22743 /* Same game for Y. */
22744 if (r1->y < r2->y)
22745 upper = r1, lower = r2;
22746 else
22747 upper = r2, lower = r1;
22748
22749 /* The upper end of the intersection is lower.y0, if this is inside
22750 of upper. Otherwise, there is no intersection. */
22751 if (lower->y <= upper->y + upper->height)
22752 {
22753 result->y = lower->y;
22754
22755 /* The lower end of the intersection is the minimum of the lower
22756 ends of upper and lower. */
22757 result->height = (min (lower->y + lower->height,
22758 upper->y + upper->height)
22759 - result->y);
22760 intersection_p = 1;
22761 }
22762 }
22763
22764 return intersection_p;
22765 }
22766
22767 #endif /* HAVE_WINDOW_SYSTEM */
22768
22769 \f
22770 /***********************************************************************
22771 Initialization
22772 ***********************************************************************/
22773
22774 void
22775 syms_of_xdisp ()
22776 {
22777 Vwith_echo_area_save_vector = Qnil;
22778 staticpro (&Vwith_echo_area_save_vector);
22779
22780 Vmessage_stack = Qnil;
22781 staticpro (&Vmessage_stack);
22782
22783 Qinhibit_redisplay = intern ("inhibit-redisplay");
22784 staticpro (&Qinhibit_redisplay);
22785
22786 message_dolog_marker1 = Fmake_marker ();
22787 staticpro (&message_dolog_marker1);
22788 message_dolog_marker2 = Fmake_marker ();
22789 staticpro (&message_dolog_marker2);
22790 message_dolog_marker3 = Fmake_marker ();
22791 staticpro (&message_dolog_marker3);
22792
22793 #if GLYPH_DEBUG
22794 defsubr (&Sdump_frame_glyph_matrix);
22795 defsubr (&Sdump_glyph_matrix);
22796 defsubr (&Sdump_glyph_row);
22797 defsubr (&Sdump_tool_bar_row);
22798 defsubr (&Strace_redisplay);
22799 defsubr (&Strace_to_stderr);
22800 #endif
22801 #ifdef HAVE_WINDOW_SYSTEM
22802 defsubr (&Stool_bar_lines_needed);
22803 defsubr (&Slookup_image_map);
22804 #endif
22805 defsubr (&Sformat_mode_line);
22806
22807 staticpro (&Qmenu_bar_update_hook);
22808 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22809
22810 staticpro (&Qoverriding_terminal_local_map);
22811 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22812
22813 staticpro (&Qoverriding_local_map);
22814 Qoverriding_local_map = intern ("overriding-local-map");
22815
22816 staticpro (&Qwindow_scroll_functions);
22817 Qwindow_scroll_functions = intern ("window-scroll-functions");
22818
22819 staticpro (&Qredisplay_end_trigger_functions);
22820 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22821
22822 staticpro (&Qinhibit_point_motion_hooks);
22823 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22824
22825 QCdata = intern (":data");
22826 staticpro (&QCdata);
22827 Qdisplay = intern ("display");
22828 staticpro (&Qdisplay);
22829 Qspace_width = intern ("space-width");
22830 staticpro (&Qspace_width);
22831 Qraise = intern ("raise");
22832 staticpro (&Qraise);
22833 Qslice = intern ("slice");
22834 staticpro (&Qslice);
22835 Qspace = intern ("space");
22836 staticpro (&Qspace);
22837 Qmargin = intern ("margin");
22838 staticpro (&Qmargin);
22839 Qpointer = intern ("pointer");
22840 staticpro (&Qpointer);
22841 Qleft_margin = intern ("left-margin");
22842 staticpro (&Qleft_margin);
22843 Qright_margin = intern ("right-margin");
22844 staticpro (&Qright_margin);
22845 Qcenter = intern ("center");
22846 staticpro (&Qcenter);
22847 Qline_height = intern ("line-height");
22848 staticpro (&Qline_height);
22849 QCalign_to = intern (":align-to");
22850 staticpro (&QCalign_to);
22851 QCrelative_width = intern (":relative-width");
22852 staticpro (&QCrelative_width);
22853 QCrelative_height = intern (":relative-height");
22854 staticpro (&QCrelative_height);
22855 QCeval = intern (":eval");
22856 staticpro (&QCeval);
22857 QCpropertize = intern (":propertize");
22858 staticpro (&QCpropertize);
22859 QCfile = intern (":file");
22860 staticpro (&QCfile);
22861 Qfontified = intern ("fontified");
22862 staticpro (&Qfontified);
22863 Qfontification_functions = intern ("fontification-functions");
22864 staticpro (&Qfontification_functions);
22865 Qtrailing_whitespace = intern ("trailing-whitespace");
22866 staticpro (&Qtrailing_whitespace);
22867 Qescape_glyph = intern ("escape-glyph");
22868 staticpro (&Qescape_glyph);
22869 Qnobreak_space = intern ("nobreak-space");
22870 staticpro (&Qnobreak_space);
22871 Qimage = intern ("image");
22872 staticpro (&Qimage);
22873 QCmap = intern (":map");
22874 staticpro (&QCmap);
22875 QCpointer = intern (":pointer");
22876 staticpro (&QCpointer);
22877 Qrect = intern ("rect");
22878 staticpro (&Qrect);
22879 Qcircle = intern ("circle");
22880 staticpro (&Qcircle);
22881 Qpoly = intern ("poly");
22882 staticpro (&Qpoly);
22883 Qmessage_truncate_lines = intern ("message-truncate-lines");
22884 staticpro (&Qmessage_truncate_lines);
22885 Qgrow_only = intern ("grow-only");
22886 staticpro (&Qgrow_only);
22887 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22888 staticpro (&Qinhibit_menubar_update);
22889 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22890 staticpro (&Qinhibit_eval_during_redisplay);
22891 Qposition = intern ("position");
22892 staticpro (&Qposition);
22893 Qbuffer_position = intern ("buffer-position");
22894 staticpro (&Qbuffer_position);
22895 Qobject = intern ("object");
22896 staticpro (&Qobject);
22897 Qbar = intern ("bar");
22898 staticpro (&Qbar);
22899 Qhbar = intern ("hbar");
22900 staticpro (&Qhbar);
22901 Qbox = intern ("box");
22902 staticpro (&Qbox);
22903 Qhollow = intern ("hollow");
22904 staticpro (&Qhollow);
22905 Qhand = intern ("hand");
22906 staticpro (&Qhand);
22907 Qarrow = intern ("arrow");
22908 staticpro (&Qarrow);
22909 Qtext = intern ("text");
22910 staticpro (&Qtext);
22911 Qrisky_local_variable = intern ("risky-local-variable");
22912 staticpro (&Qrisky_local_variable);
22913 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22914 staticpro (&Qinhibit_free_realized_faces);
22915
22916 list_of_error = Fcons (Fcons (intern ("error"),
22917 Fcons (intern ("void-variable"), Qnil)),
22918 Qnil);
22919 staticpro (&list_of_error);
22920
22921 Qlast_arrow_position = intern ("last-arrow-position");
22922 staticpro (&Qlast_arrow_position);
22923 Qlast_arrow_string = intern ("last-arrow-string");
22924 staticpro (&Qlast_arrow_string);
22925
22926 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22927 staticpro (&Qoverlay_arrow_string);
22928 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22929 staticpro (&Qoverlay_arrow_bitmap);
22930
22931 echo_buffer[0] = echo_buffer[1] = Qnil;
22932 staticpro (&echo_buffer[0]);
22933 staticpro (&echo_buffer[1]);
22934
22935 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22936 staticpro (&echo_area_buffer[0]);
22937 staticpro (&echo_area_buffer[1]);
22938
22939 Vmessages_buffer_name = build_string ("*Messages*");
22940 staticpro (&Vmessages_buffer_name);
22941
22942 mode_line_proptrans_alist = Qnil;
22943 staticpro (&mode_line_proptrans_alist);
22944 mode_line_string_list = Qnil;
22945 staticpro (&mode_line_string_list);
22946 mode_line_string_face = Qnil;
22947 staticpro (&mode_line_string_face);
22948 mode_line_string_face_prop = Qnil;
22949 staticpro (&mode_line_string_face_prop);
22950 Vmode_line_unwind_vector = Qnil;
22951 staticpro (&Vmode_line_unwind_vector);
22952
22953 help_echo_string = Qnil;
22954 staticpro (&help_echo_string);
22955 help_echo_object = Qnil;
22956 staticpro (&help_echo_object);
22957 help_echo_window = Qnil;
22958 staticpro (&help_echo_window);
22959 previous_help_echo_string = Qnil;
22960 staticpro (&previous_help_echo_string);
22961 help_echo_pos = -1;
22962
22963 #ifdef HAVE_WINDOW_SYSTEM
22964 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22965 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22966 For example, if a block cursor is over a tab, it will be drawn as
22967 wide as that tab on the display. */);
22968 x_stretch_cursor_p = 0;
22969 #endif
22970
22971 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22972 doc: /* *Non-nil means highlight trailing whitespace.
22973 The face used for trailing whitespace is `trailing-whitespace'. */);
22974 Vshow_trailing_whitespace = Qnil;
22975
22976 DEFVAR_LISP ("nobreak-char-display", &Vnobreak_char_display,
22977 doc: /* *Control highlighting of nobreak space and soft hyphen.
22978 A value of t means highlight the character itself (for nobreak space,
22979 use face `nobreak-space').
22980 A value of nil means no highlighting.
22981 Other values mean display the escape glyph followed by an ordinary
22982 space or ordinary hyphen. */);
22983 Vnobreak_char_display = Qt;
22984
22985 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22986 doc: /* *The pointer shape to show in void text areas.
22987 A value of nil means to show the text pointer. Other options are `arrow',
22988 `text', `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22989 Vvoid_text_area_pointer = Qarrow;
22990
22991 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22992 doc: /* Non-nil means don't actually do any redisplay.
22993 This is used for internal purposes. */);
22994 Vinhibit_redisplay = Qnil;
22995
22996 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22997 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22998 Vglobal_mode_string = Qnil;
22999
23000 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
23001 doc: /* Marker for where to display an arrow on top of the buffer text.
23002 This must be the beginning of a line in order to work.
23003 See also `overlay-arrow-string'. */);
23004 Voverlay_arrow_position = Qnil;
23005
23006 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
23007 doc: /* String to display as an arrow in non-window frames.
23008 See also `overlay-arrow-position'. */);
23009 Voverlay_arrow_string = build_string ("=>");
23010
23011 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
23012 doc: /* List of variables (symbols) which hold markers for overlay arrows.
23013 The symbols on this list are examined during redisplay to determine
23014 where to display overlay arrows. */);
23015 Voverlay_arrow_variable_list
23016 = Fcons (intern ("overlay-arrow-position"), Qnil);
23017
23018 DEFVAR_INT ("scroll-step", &scroll_step,
23019 doc: /* *The number of lines to try scrolling a window by when point moves out.
23020 If that fails to bring point back on frame, point is centered instead.
23021 If this is zero, point is always centered after it moves off frame.
23022 If you want scrolling to always be a line at a time, you should set
23023 `scroll-conservatively' to a large value rather than set this to 1. */);
23024
23025 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
23026 doc: /* *Scroll up to this many lines, to bring point back on screen.
23027 A value of zero means to scroll the text to center point vertically
23028 in the window. */);
23029 scroll_conservatively = 0;
23030
23031 DEFVAR_INT ("scroll-margin", &scroll_margin,
23032 doc: /* *Number of lines of margin at the top and bottom of a window.
23033 Recenter the window whenever point gets within this many lines
23034 of the top or bottom of the window. */);
23035 scroll_margin = 0;
23036
23037 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
23038 doc: /* Pixels per inch on current display.
23039 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
23040 Vdisplay_pixels_per_inch = make_float (72.0);
23041
23042 #if GLYPH_DEBUG
23043 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
23044 #endif
23045
23046 DEFVAR_BOOL ("truncate-partial-width-windows",
23047 &truncate_partial_width_windows,
23048 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
23049 truncate_partial_width_windows = 1;
23050
23051 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
23052 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
23053 Any other value means to use the appropriate face, `mode-line',
23054 `header-line', or `menu' respectively. */);
23055 mode_line_inverse_video = 1;
23056
23057 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
23058 doc: /* *Maximum buffer size for which line number should be displayed.
23059 If the buffer is bigger than this, the line number does not appear
23060 in the mode line. A value of nil means no limit. */);
23061 Vline_number_display_limit = Qnil;
23062
23063 DEFVAR_INT ("line-number-display-limit-width",
23064 &line_number_display_limit_width,
23065 doc: /* *Maximum line width (in characters) for line number display.
23066 If the average length of the lines near point is bigger than this, then the
23067 line number may be omitted from the mode line. */);
23068 line_number_display_limit_width = 200;
23069
23070 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
23071 doc: /* *Non-nil means highlight region even in nonselected windows. */);
23072 highlight_nonselected_windows = 0;
23073
23074 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
23075 doc: /* Non-nil if more than one frame is visible on this display.
23076 Minibuffer-only frames don't count, but iconified frames do.
23077 This variable is not guaranteed to be accurate except while processing
23078 `frame-title-format' and `icon-title-format'. */);
23079
23080 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
23081 doc: /* Template for displaying the title bar of visible frames.
23082 \(Assuming the window manager supports this feature.)
23083 This variable has the same structure as `mode-line-format' (which see),
23084 and is used only on frames for which no explicit name has been set
23085 \(see `modify-frame-parameters'). */);
23086
23087 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
23088 doc: /* Template for displaying the title bar of an iconified frame.
23089 \(Assuming the window manager supports this feature.)
23090 This variable has the same structure as `mode-line-format' (which see),
23091 and is used only on frames for which no explicit name has been set
23092 \(see `modify-frame-parameters'). */);
23093 Vicon_title_format
23094 = Vframe_title_format
23095 = Fcons (intern ("multiple-frames"),
23096 Fcons (build_string ("%b"),
23097 Fcons (Fcons (empty_string,
23098 Fcons (intern ("invocation-name"),
23099 Fcons (build_string ("@"),
23100 Fcons (intern ("system-name"),
23101 Qnil)))),
23102 Qnil)));
23103
23104 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
23105 doc: /* Maximum number of lines to keep in the message log buffer.
23106 If nil, disable message logging. If t, log messages but don't truncate
23107 the buffer when it becomes large. */);
23108 Vmessage_log_max = make_number (50);
23109
23110 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
23111 doc: /* Functions called before redisplay, if window sizes have changed.
23112 The value should be a list of functions that take one argument.
23113 Just before redisplay, for each frame, if any of its windows have changed
23114 size since the last redisplay, or have been split or deleted,
23115 all the functions in the list are called, with the frame as argument. */);
23116 Vwindow_size_change_functions = Qnil;
23117
23118 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
23119 doc: /* List of functions to call before redisplaying a window with scrolling.
23120 Each function is called with two arguments, the window
23121 and its new display-start position. Note that the value of `window-end'
23122 is not valid when these functions are called. */);
23123 Vwindow_scroll_functions = Qnil;
23124
23125 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
23126 doc: /* *Non-nil means autoselect window with mouse pointer. */);
23127 mouse_autoselect_window = 0;
23128
23129 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
23130 doc: /* *Non-nil means automatically resize tool-bars.
23131 This increases a tool-bar's height if not all tool-bar items are visible.
23132 It decreases a tool-bar's height when it would display blank lines
23133 otherwise. */);
23134 auto_resize_tool_bars_p = 1;
23135
23136 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
23137 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
23138 auto_raise_tool_bar_buttons_p = 1;
23139
23140 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
23141 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
23142 make_cursor_line_fully_visible_p = 1;
23143
23144 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
23145 doc: /* *Margin around tool-bar buttons in pixels.
23146 If an integer, use that for both horizontal and vertical margins.
23147 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
23148 HORZ specifying the horizontal margin, and VERT specifying the
23149 vertical margin. */);
23150 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
23151
23152 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
23153 doc: /* *Relief thickness of tool-bar buttons. */);
23154 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
23155
23156 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
23157 doc: /* List of functions to call to fontify regions of text.
23158 Each function is called with one argument POS. Functions must
23159 fontify a region starting at POS in the current buffer, and give
23160 fontified regions the property `fontified'. */);
23161 Vfontification_functions = Qnil;
23162 Fmake_variable_buffer_local (Qfontification_functions);
23163
23164 DEFVAR_BOOL ("unibyte-display-via-language-environment",
23165 &unibyte_display_via_language_environment,
23166 doc: /* *Non-nil means display unibyte text according to language environment.
23167 Specifically this means that unibyte non-ASCII characters
23168 are displayed by converting them to the equivalent multibyte characters
23169 according to the current language environment. As a result, they are
23170 displayed according to the current fontset. */);
23171 unibyte_display_via_language_environment = 0;
23172
23173 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
23174 doc: /* *Maximum height for resizing mini-windows.
23175 If a float, it specifies a fraction of the mini-window frame's height.
23176 If an integer, it specifies a number of lines. */);
23177 Vmax_mini_window_height = make_float (0.25);
23178
23179 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
23180 doc: /* *How to resize mini-windows.
23181 A value of nil means don't automatically resize mini-windows.
23182 A value of t means resize them to fit the text displayed in them.
23183 A value of `grow-only', the default, means let mini-windows grow
23184 only, until their display becomes empty, at which point the windows
23185 go back to their normal size. */);
23186 Vresize_mini_windows = Qgrow_only;
23187
23188 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
23189 doc: /* Alist specifying how to blink the cursor off.
23190 Each element has the form (ON-STATE . OFF-STATE). Whenever the
23191 `cursor-type' frame-parameter or variable equals ON-STATE,
23192 comparing using `equal', Emacs uses OFF-STATE to specify
23193 how to blink it off. */);
23194 Vblink_cursor_alist = Qnil;
23195
23196 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
23197 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
23198 automatic_hscrolling_p = 1;
23199
23200 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
23201 doc: /* *How many columns away from the window edge point is allowed to get
23202 before automatic hscrolling will horizontally scroll the window. */);
23203 hscroll_margin = 5;
23204
23205 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
23206 doc: /* *How many columns to scroll the window when point gets too close to the edge.
23207 When point is less than `automatic-hscroll-margin' columns from the window
23208 edge, automatic hscrolling will scroll the window by the amount of columns
23209 determined by this variable. If its value is a positive integer, scroll that
23210 many columns. If it's a positive floating-point number, it specifies the
23211 fraction of the window's width to scroll. If it's nil or zero, point will be
23212 centered horizontally after the scroll. Any other value, including negative
23213 numbers, are treated as if the value were zero.
23214
23215 Automatic hscrolling always moves point outside the scroll margin, so if
23216 point was more than scroll step columns inside the margin, the window will
23217 scroll more than the value given by the scroll step.
23218
23219 Note that the lower bound for automatic hscrolling specified by `scroll-left'
23220 and `scroll-right' overrides this variable's effect. */);
23221 Vhscroll_step = make_number (0);
23222
23223 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
23224 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
23225 Bind this around calls to `message' to let it take effect. */);
23226 message_truncate_lines = 0;
23227
23228 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
23229 doc: /* Normal hook run to update the menu bar definitions.
23230 Redisplay runs this hook before it redisplays the menu bar.
23231 This is used to update submenus such as Buffers,
23232 whose contents depend on various data. */);
23233 Vmenu_bar_update_hook = Qnil;
23234
23235 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
23236 doc: /* Non-nil means don't update menu bars. Internal use only. */);
23237 inhibit_menubar_update = 0;
23238
23239 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
23240 doc: /* Non-nil means don't eval Lisp during redisplay. */);
23241 inhibit_eval_during_redisplay = 0;
23242
23243 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
23244 doc: /* Non-nil means don't free realized faces. Internal use only. */);
23245 inhibit_free_realized_faces = 0;
23246
23247 #if GLYPH_DEBUG
23248 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
23249 doc: /* Inhibit try_window_id display optimization. */);
23250 inhibit_try_window_id = 0;
23251
23252 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
23253 doc: /* Inhibit try_window_reusing display optimization. */);
23254 inhibit_try_window_reusing = 0;
23255
23256 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
23257 doc: /* Inhibit try_cursor_movement display optimization. */);
23258 inhibit_try_cursor_movement = 0;
23259 #endif /* GLYPH_DEBUG */
23260 }
23261
23262
23263 /* Initialize this module when Emacs starts. */
23264
23265 void
23266 init_xdisp ()
23267 {
23268 Lisp_Object root_window;
23269 struct window *mini_w;
23270
23271 current_header_line_height = current_mode_line_height = -1;
23272
23273 CHARPOS (this_line_start_pos) = 0;
23274
23275 mini_w = XWINDOW (minibuf_window);
23276 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
23277
23278 if (!noninteractive)
23279 {
23280 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
23281 int i;
23282
23283 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
23284 set_window_height (root_window,
23285 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
23286 0);
23287 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
23288 set_window_height (minibuf_window, 1, 0);
23289
23290 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
23291 mini_w->total_cols = make_number (FRAME_COLS (f));
23292
23293 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
23294 scratch_glyph_row.glyphs[TEXT_AREA + 1]
23295 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
23296
23297 /* The default ellipsis glyphs `...'. */
23298 for (i = 0; i < 3; ++i)
23299 default_invis_vector[i] = make_number ('.');
23300 }
23301
23302 {
23303 /* Allocate the buffer for frame titles.
23304 Also used for `format-mode-line'. */
23305 int size = 100;
23306 mode_line_noprop_buf = (char *) xmalloc (size);
23307 mode_line_noprop_buf_end = mode_line_noprop_buf + size;
23308 mode_line_noprop_ptr = mode_line_noprop_buf;
23309 mode_line_target = MODE_LINE_DISPLAY;
23310 }
23311
23312 help_echo_showing_p = 0;
23313 }
23314
23315
23316 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
23317 (do not change this comment) */