]> code.delx.au - gnu-emacs/blob - src/xdisp.c
(set_message_1): Delete xassert.
[gnu-emacs] / src / xdisp.c
1 /* Display generation from window structure and buffer text.
2 Copyright (C) 1985, 1986, 1987, 1988, 1993, 1994, 1995, 1997, 1998, 1999,
3 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
4
5 This file is part of GNU Emacs.
6
7 GNU Emacs is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* New redisplay written by Gerd Moellmann <gerd@gnu.org>.
23
24 Redisplay.
25
26 Emacs separates the task of updating the display from code
27 modifying global state, e.g. buffer text. This way functions
28 operating on buffers don't also have to be concerned with updating
29 the display.
30
31 Updating the display is triggered by the Lisp interpreter when it
32 decides it's time to do it. This is done either automatically for
33 you as part of the interpreter's command loop or as the result of
34 calling Lisp functions like `sit-for'. The C function `redisplay'
35 in xdisp.c is the only entry into the inner redisplay code. (Or,
36 let's say almost---see the description of direct update
37 operations, below.)
38
39 The following diagram shows how redisplay code is invoked. As you
40 can see, Lisp calls redisplay and vice versa. Under window systems
41 like X, some portions of the redisplay code are also called
42 asynchronously during mouse movement or expose events. It is very
43 important that these code parts do NOT use the C library (malloc,
44 free) because many C libraries under Unix are not reentrant. They
45 may also NOT call functions of the Lisp interpreter which could
46 change the interpreter's state. If you don't follow these rules,
47 you will encounter bugs which are very hard to explain.
48
49 (Direct functions, see below)
50 direct_output_for_insert,
51 direct_forward_char (dispnew.c)
52 +---------------------------------+
53 | |
54 | V
55 +--------------+ redisplay +----------------+
56 | Lisp machine |---------------->| Redisplay code |<--+
57 +--------------+ (xdisp.c) +----------------+ |
58 ^ | |
59 +----------------------------------+ |
60 Don't use this path when called |
61 asynchronously! |
62 |
63 expose_window (asynchronous) |
64 |
65 X expose events -----+
66
67 What does redisplay do? Obviously, it has to figure out somehow what
68 has been changed since the last time the display has been updated,
69 and to make these changes visible. Preferably it would do that in
70 a moderately intelligent way, i.e. fast.
71
72 Changes in buffer text can be deduced from window and buffer
73 structures, and from some global variables like `beg_unchanged' and
74 `end_unchanged'. The contents of the display are additionally
75 recorded in a `glyph matrix', a two-dimensional matrix of glyph
76 structures. Each row in such a matrix corresponds to a line on the
77 display, and each glyph in a row corresponds to a column displaying
78 a character, an image, or what else. This matrix is called the
79 `current glyph matrix' or `current matrix' in redisplay
80 terminology.
81
82 For buffer parts that have been changed since the last update, a
83 second glyph matrix is constructed, the so called `desired glyph
84 matrix' or short `desired matrix'. Current and desired matrix are
85 then compared to find a cheap way to update the display, e.g. by
86 reusing part of the display by scrolling lines.
87
88
89 Direct operations.
90
91 You will find a lot of redisplay optimizations when you start
92 looking at the innards of redisplay. The overall goal of all these
93 optimizations is to make redisplay fast because it is done
94 frequently.
95
96 Two optimizations are not found in xdisp.c. These are the direct
97 operations mentioned above. As the name suggests they follow a
98 different principle than the rest of redisplay. Instead of
99 building a desired matrix and then comparing it with the current
100 display, they perform their actions directly on the display and on
101 the current matrix.
102
103 One direct operation updates the display after one character has
104 been entered. The other one moves the cursor by one position
105 forward or backward. You find these functions under the names
106 `direct_output_for_insert' and `direct_output_forward_char' in
107 dispnew.c.
108
109
110 Desired matrices.
111
112 Desired matrices are always built per Emacs window. The function
113 `display_line' is the central function to look at if you are
114 interested. It constructs one row in a desired matrix given an
115 iterator structure containing both a buffer position and a
116 description of the environment in which the text is to be
117 displayed. But this is too early, read on.
118
119 Characters and pixmaps displayed for a range of buffer text depend
120 on various settings of buffers and windows, on overlays and text
121 properties, on display tables, on selective display. The good news
122 is that all this hairy stuff is hidden behind a small set of
123 interface functions taking an iterator structure (struct it)
124 argument.
125
126 Iteration over things to be displayed is then simple. It is
127 started by initializing an iterator with a call to init_iterator.
128 Calls to get_next_display_element fill the iterator structure with
129 relevant information about the next thing to display. Calls to
130 set_iterator_to_next move the iterator to the next thing.
131
132 Besides this, an iterator also contains information about the
133 display environment in which glyphs for display elements are to be
134 produced. It has fields for the width and height of the display,
135 the information whether long lines are truncated or continued, a
136 current X and Y position, and lots of other stuff you can better
137 see in dispextern.h.
138
139 Glyphs in a desired matrix are normally constructed in a loop
140 calling get_next_display_element and then produce_glyphs. The call
141 to produce_glyphs will fill the iterator structure with pixel
142 information about the element being displayed and at the same time
143 produce glyphs for it. If the display element fits on the line
144 being displayed, set_iterator_to_next is called next, otherwise the
145 glyphs produced are discarded.
146
147
148 Frame matrices.
149
150 That just couldn't be all, could it? What about terminal types not
151 supporting operations on sub-windows of the screen? To update the
152 display on such a terminal, window-based glyph matrices are not
153 well suited. To be able to reuse part of the display (scrolling
154 lines up and down), we must instead have a view of the whole
155 screen. This is what `frame matrices' are for. They are a trick.
156
157 Frames on terminals like above have a glyph pool. Windows on such
158 a frame sub-allocate their glyph memory from their frame's glyph
159 pool. The frame itself is given its own glyph matrices. By
160 coincidence---or maybe something else---rows in window glyph
161 matrices are slices of corresponding rows in frame matrices. Thus
162 writing to window matrices implicitly updates a frame matrix which
163 provides us with the view of the whole screen that we originally
164 wanted to have without having to move many bytes around. To be
165 honest, there is a little bit more done, but not much more. If you
166 plan to extend that code, take a look at dispnew.c. The function
167 build_frame_matrix is a good starting point. */
168
169 #include <config.h>
170 #include <stdio.h>
171
172 #include "lisp.h"
173 #include "keyboard.h"
174 #include "frame.h"
175 #include "window.h"
176 #include "termchar.h"
177 #include "dispextern.h"
178 #include "buffer.h"
179 #include "charset.h"
180 #include "indent.h"
181 #include "commands.h"
182 #include "keymap.h"
183 #include "macros.h"
184 #include "disptab.h"
185 #include "termhooks.h"
186 #include "intervals.h"
187 #include "coding.h"
188 #include "process.h"
189 #include "region-cache.h"
190 #include "fontset.h"
191 #include "blockinput.h"
192
193 #ifdef HAVE_X_WINDOWS
194 #include "xterm.h"
195 #endif
196 #ifdef WINDOWSNT
197 #include "w32term.h"
198 #endif
199 #ifdef MAC_OS
200 #include "macterm.h"
201 #endif
202
203 #ifndef FRAME_X_OUTPUT
204 #define FRAME_X_OUTPUT(f) ((f)->output_data.x)
205 #endif
206
207 #define INFINITY 10000000
208
209 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
210 || defined (USE_GTK)
211 extern void set_frame_menubar P_ ((struct frame *f, int, int));
212 extern int pending_menu_activation;
213 #endif
214
215 extern int interrupt_input;
216 extern int command_loop_level;
217
218 extern Lisp_Object do_mouse_tracking;
219
220 extern int minibuffer_auto_raise;
221 extern Lisp_Object Vminibuffer_list;
222
223 extern Lisp_Object Qface;
224 extern Lisp_Object Qmode_line, Qmode_line_inactive, Qheader_line;
225
226 extern Lisp_Object Voverriding_local_map;
227 extern Lisp_Object Voverriding_local_map_menu_flag;
228 extern Lisp_Object Qmenu_item;
229 extern Lisp_Object Qwhen;
230 extern Lisp_Object Qhelp_echo;
231
232 Lisp_Object Qoverriding_local_map, Qoverriding_terminal_local_map;
233 Lisp_Object Qwindow_scroll_functions, Vwindow_scroll_functions;
234 Lisp_Object Qredisplay_end_trigger_functions;
235 Lisp_Object Qinhibit_point_motion_hooks;
236 Lisp_Object QCeval, QCfile, QCdata, QCpropertize;
237 Lisp_Object Qfontified;
238 Lisp_Object Qgrow_only;
239 Lisp_Object Qinhibit_eval_during_redisplay;
240 Lisp_Object Qbuffer_position, Qposition, Qobject;
241
242 /* Cursor shapes */
243 Lisp_Object Qbar, Qhbar, Qbox, Qhollow;
244
245 /* Pointer shapes */
246 Lisp_Object Qarrow, Qhand, Qtext;
247
248 Lisp_Object Qrisky_local_variable;
249
250 /* Holds the list (error). */
251 Lisp_Object list_of_error;
252
253 /* Functions called to fontify regions of text. */
254
255 Lisp_Object Vfontification_functions;
256 Lisp_Object Qfontification_functions;
257
258 /* Non-zero means automatically select any window when the mouse
259 cursor moves into it. */
260 int mouse_autoselect_window;
261
262 /* Non-zero means draw tool bar buttons raised when the mouse moves
263 over them. */
264
265 int auto_raise_tool_bar_buttons_p;
266
267 /* Non-zero means to reposition window if cursor line is only partially visible. */
268
269 int make_cursor_line_fully_visible_p;
270
271 /* Margin around tool bar buttons in pixels. */
272
273 Lisp_Object Vtool_bar_button_margin;
274
275 /* Thickness of shadow to draw around tool bar buttons. */
276
277 EMACS_INT tool_bar_button_relief;
278
279 /* Non-zero means automatically resize tool-bars so that all tool-bar
280 items are visible, and no blank lines remain. */
281
282 int auto_resize_tool_bars_p;
283
284 /* Non-zero means draw block and hollow cursor as wide as the glyph
285 under it. For example, if a block cursor is over a tab, it will be
286 drawn as wide as that tab on the display. */
287
288 int x_stretch_cursor_p;
289
290 /* Non-nil means don't actually do any redisplay. */
291
292 Lisp_Object Vinhibit_redisplay, Qinhibit_redisplay;
293
294 /* Non-zero means Lisp evaluation during redisplay is inhibited. */
295
296 int inhibit_eval_during_redisplay;
297
298 /* Names of text properties relevant for redisplay. */
299
300 Lisp_Object Qdisplay;
301 extern Lisp_Object Qface, Qinvisible, Qwidth;
302
303 /* Symbols used in text property values. */
304
305 Lisp_Object Vdisplay_pixels_per_inch;
306 Lisp_Object Qspace, QCalign_to, QCrelative_width, QCrelative_height;
307 Lisp_Object Qleft_margin, Qright_margin, Qspace_width, Qraise;
308 Lisp_Object Qslice;
309 Lisp_Object Qcenter;
310 Lisp_Object Qmargin, Qpointer;
311 Lisp_Object Qline_height;
312 extern Lisp_Object Qheight;
313 extern Lisp_Object QCwidth, QCheight, QCascent;
314 extern Lisp_Object Qscroll_bar;
315 extern Lisp_Object Qcursor;
316
317 /* Non-nil means highlight trailing whitespace. */
318
319 Lisp_Object Vshow_trailing_whitespace;
320
321 /* Non-nil means escape non-break space and hyphens. */
322
323 Lisp_Object Vshow_nonbreak_escape;
324
325 #ifdef HAVE_WINDOW_SYSTEM
326 extern Lisp_Object Voverflow_newline_into_fringe;
327
328 /* Test if overflow newline into fringe. Called with iterator IT
329 at or past right window margin, and with IT->current_x set. */
330
331 #define IT_OVERFLOW_NEWLINE_INTO_FRINGE(it) \
332 (!NILP (Voverflow_newline_into_fringe) \
333 && FRAME_WINDOW_P (it->f) \
334 && WINDOW_RIGHT_FRINGE_WIDTH (it->w) > 0 \
335 && it->current_x == it->last_visible_x)
336
337 #endif /* HAVE_WINDOW_SYSTEM */
338
339 /* Non-nil means show the text cursor in void text areas
340 i.e. in blank areas after eol and eob. This used to be
341 the default in 21.3. */
342
343 Lisp_Object Vvoid_text_area_pointer;
344
345 /* Name of the face used to highlight trailing whitespace. */
346
347 Lisp_Object Qtrailing_whitespace;
348
349 /* Name and number of the face used to highlight escape glyphs. */
350
351 Lisp_Object Qescape_glyph;
352
353 /* The symbol `image' which is the car of the lists used to represent
354 images in Lisp. */
355
356 Lisp_Object Qimage;
357
358 /* The image map types. */
359 Lisp_Object QCmap, QCpointer;
360 Lisp_Object Qrect, Qcircle, Qpoly;
361
362 /* Non-zero means print newline to stdout before next mini-buffer
363 message. */
364
365 int noninteractive_need_newline;
366
367 /* Non-zero means print newline to message log before next message. */
368
369 static int message_log_need_newline;
370
371 /* Three markers that message_dolog uses.
372 It could allocate them itself, but that causes trouble
373 in handling memory-full errors. */
374 static Lisp_Object message_dolog_marker1;
375 static Lisp_Object message_dolog_marker2;
376 static Lisp_Object message_dolog_marker3;
377 \f
378 /* The buffer position of the first character appearing entirely or
379 partially on the line of the selected window which contains the
380 cursor; <= 0 if not known. Set by set_cursor_from_row, used for
381 redisplay optimization in redisplay_internal. */
382
383 static struct text_pos this_line_start_pos;
384
385 /* Number of characters past the end of the line above, including the
386 terminating newline. */
387
388 static struct text_pos this_line_end_pos;
389
390 /* The vertical positions and the height of this line. */
391
392 static int this_line_vpos;
393 static int this_line_y;
394 static int this_line_pixel_height;
395
396 /* X position at which this display line starts. Usually zero;
397 negative if first character is partially visible. */
398
399 static int this_line_start_x;
400
401 /* Buffer that this_line_.* variables are referring to. */
402
403 static struct buffer *this_line_buffer;
404
405 /* Nonzero means truncate lines in all windows less wide than the
406 frame. */
407
408 int truncate_partial_width_windows;
409
410 /* A flag to control how to display unibyte 8-bit character. */
411
412 int unibyte_display_via_language_environment;
413
414 /* Nonzero means we have more than one non-mini-buffer-only frame.
415 Not guaranteed to be accurate except while parsing
416 frame-title-format. */
417
418 int multiple_frames;
419
420 Lisp_Object Vglobal_mode_string;
421
422
423 /* List of variables (symbols) which hold markers for overlay arrows.
424 The symbols on this list are examined during redisplay to determine
425 where to display overlay arrows. */
426
427 Lisp_Object Voverlay_arrow_variable_list;
428
429 /* Marker for where to display an arrow on top of the buffer text. */
430
431 Lisp_Object Voverlay_arrow_position;
432
433 /* String to display for the arrow. Only used on terminal frames. */
434
435 Lisp_Object Voverlay_arrow_string;
436
437 /* Values of those variables at last redisplay are stored as
438 properties on `overlay-arrow-position' symbol. However, if
439 Voverlay_arrow_position is a marker, last-arrow-position is its
440 numerical position. */
441
442 Lisp_Object Qlast_arrow_position, Qlast_arrow_string;
443
444 /* Alternative overlay-arrow-string and overlay-arrow-bitmap
445 properties on a symbol in overlay-arrow-variable-list. */
446
447 Lisp_Object Qoverlay_arrow_string, Qoverlay_arrow_bitmap;
448
449 /* Like mode-line-format, but for the title bar on a visible frame. */
450
451 Lisp_Object Vframe_title_format;
452
453 /* Like mode-line-format, but for the title bar on an iconified frame. */
454
455 Lisp_Object Vicon_title_format;
456
457 /* List of functions to call when a window's size changes. These
458 functions get one arg, a frame on which one or more windows' sizes
459 have changed. */
460
461 static Lisp_Object Vwindow_size_change_functions;
462
463 Lisp_Object Qmenu_bar_update_hook, Vmenu_bar_update_hook;
464
465 /* Nonzero if an overlay arrow has been displayed in this window. */
466
467 static int overlay_arrow_seen;
468
469 /* Nonzero means highlight the region even in nonselected windows. */
470
471 int highlight_nonselected_windows;
472
473 /* If cursor motion alone moves point off frame, try scrolling this
474 many lines up or down if that will bring it back. */
475
476 static EMACS_INT scroll_step;
477
478 /* Nonzero means scroll just far enough to bring point back on the
479 screen, when appropriate. */
480
481 static EMACS_INT scroll_conservatively;
482
483 /* Recenter the window whenever point gets within this many lines of
484 the top or bottom of the window. This value is translated into a
485 pixel value by multiplying it with FRAME_LINE_HEIGHT, which means
486 that there is really a fixed pixel height scroll margin. */
487
488 EMACS_INT scroll_margin;
489
490 /* Number of windows showing the buffer of the selected window (or
491 another buffer with the same base buffer). keyboard.c refers to
492 this. */
493
494 int buffer_shared;
495
496 /* Vector containing glyphs for an ellipsis `...'. */
497
498 static Lisp_Object default_invis_vector[3];
499
500 /* Zero means display the mode-line/header-line/menu-bar in the default face
501 (this slightly odd definition is for compatibility with previous versions
502 of emacs), non-zero means display them using their respective faces.
503
504 This variable is deprecated. */
505
506 int mode_line_inverse_video;
507
508 /* Prompt to display in front of the mini-buffer contents. */
509
510 Lisp_Object minibuf_prompt;
511
512 /* Width of current mini-buffer prompt. Only set after display_line
513 of the line that contains the prompt. */
514
515 int minibuf_prompt_width;
516
517 /* This is the window where the echo area message was displayed. It
518 is always a mini-buffer window, but it may not be the same window
519 currently active as a mini-buffer. */
520
521 Lisp_Object echo_area_window;
522
523 /* List of pairs (MESSAGE . MULTIBYTE). The function save_message
524 pushes the current message and the value of
525 message_enable_multibyte on the stack, the function restore_message
526 pops the stack and displays MESSAGE again. */
527
528 Lisp_Object Vmessage_stack;
529
530 /* Nonzero means multibyte characters were enabled when the echo area
531 message was specified. */
532
533 int message_enable_multibyte;
534
535 /* Nonzero if we should redraw the mode lines on the next redisplay. */
536
537 int update_mode_lines;
538
539 /* Nonzero if window sizes or contents have changed since last
540 redisplay that finished. */
541
542 int windows_or_buffers_changed;
543
544 /* Nonzero means a frame's cursor type has been changed. */
545
546 int cursor_type_changed;
547
548 /* Nonzero after display_mode_line if %l was used and it displayed a
549 line number. */
550
551 int line_number_displayed;
552
553 /* Maximum buffer size for which to display line numbers. */
554
555 Lisp_Object Vline_number_display_limit;
556
557 /* Line width to consider when repositioning for line number display. */
558
559 static EMACS_INT line_number_display_limit_width;
560
561 /* Number of lines to keep in the message log buffer. t means
562 infinite. nil means don't log at all. */
563
564 Lisp_Object Vmessage_log_max;
565
566 /* The name of the *Messages* buffer, a string. */
567
568 static Lisp_Object Vmessages_buffer_name;
569
570 /* Index 0 is the buffer that holds the current (desired) echo area message,
571 or nil if none is desired right now.
572
573 Index 1 is the buffer that holds the previously displayed echo area message,
574 or nil to indicate no message. This is normally what's on the screen now.
575
576 These two can point to the same buffer. That happens when the last
577 message output by the user (or made by echoing) has been displayed. */
578
579 Lisp_Object echo_area_buffer[2];
580
581 /* Permanent pointers to the two buffers that are used for echo area
582 purposes. Once the two buffers are made, and their pointers are
583 placed here, these two slots remain unchanged unless those buffers
584 need to be created afresh. */
585
586 static Lisp_Object echo_buffer[2];
587
588 /* A vector saved used in with_area_buffer to reduce consing. */
589
590 static Lisp_Object Vwith_echo_area_save_vector;
591
592 /* Non-zero means display_echo_area should display the last echo area
593 message again. Set by redisplay_preserve_echo_area. */
594
595 static int display_last_displayed_message_p;
596
597 /* Nonzero if echo area is being used by print; zero if being used by
598 message. */
599
600 int message_buf_print;
601
602 /* The symbol `inhibit-menubar-update' and its DEFVAR_BOOL variable. */
603
604 Lisp_Object Qinhibit_menubar_update;
605 int inhibit_menubar_update;
606
607 /* Maximum height for resizing mini-windows. Either a float
608 specifying a fraction of the available height, or an integer
609 specifying a number of lines. */
610
611 Lisp_Object Vmax_mini_window_height;
612
613 /* Non-zero means messages should be displayed with truncated
614 lines instead of being continued. */
615
616 int message_truncate_lines;
617 Lisp_Object Qmessage_truncate_lines;
618
619 /* Set to 1 in clear_message to make redisplay_internal aware
620 of an emptied echo area. */
621
622 static int message_cleared_p;
623
624 /* Non-zero means we want a hollow cursor in windows that are not
625 selected. Zero means there's no cursor in such windows. */
626
627 Lisp_Object Vcursor_in_non_selected_windows;
628 Lisp_Object Qcursor_in_non_selected_windows;
629
630 /* How to blink the default frame cursor off. */
631 Lisp_Object Vblink_cursor_alist;
632
633 /* A scratch glyph row with contents used for generating truncation
634 glyphs. Also used in direct_output_for_insert. */
635
636 #define MAX_SCRATCH_GLYPHS 100
637 struct glyph_row scratch_glyph_row;
638 static struct glyph scratch_glyphs[MAX_SCRATCH_GLYPHS];
639
640 /* Ascent and height of the last line processed by move_it_to. */
641
642 static int last_max_ascent, last_height;
643
644 /* Non-zero if there's a help-echo in the echo area. */
645
646 int help_echo_showing_p;
647
648 /* If >= 0, computed, exact values of mode-line and header-line height
649 to use in the macros CURRENT_MODE_LINE_HEIGHT and
650 CURRENT_HEADER_LINE_HEIGHT. */
651
652 int current_mode_line_height, current_header_line_height;
653
654 /* The maximum distance to look ahead for text properties. Values
655 that are too small let us call compute_char_face and similar
656 functions too often which is expensive. Values that are too large
657 let us call compute_char_face and alike too often because we
658 might not be interested in text properties that far away. */
659
660 #define TEXT_PROP_DISTANCE_LIMIT 100
661
662 #if GLYPH_DEBUG
663
664 /* Variables to turn off display optimizations from Lisp. */
665
666 int inhibit_try_window_id, inhibit_try_window_reusing;
667 int inhibit_try_cursor_movement;
668
669 /* Non-zero means print traces of redisplay if compiled with
670 GLYPH_DEBUG != 0. */
671
672 int trace_redisplay_p;
673
674 #endif /* GLYPH_DEBUG */
675
676 #ifdef DEBUG_TRACE_MOVE
677 /* Non-zero means trace with TRACE_MOVE to stderr. */
678 int trace_move;
679
680 #define TRACE_MOVE(x) if (trace_move) fprintf x; else (void) 0
681 #else
682 #define TRACE_MOVE(x) (void) 0
683 #endif
684
685 /* Non-zero means automatically scroll windows horizontally to make
686 point visible. */
687
688 int automatic_hscrolling_p;
689
690 /* How close to the margin can point get before the window is scrolled
691 horizontally. */
692 EMACS_INT hscroll_margin;
693
694 /* How much to scroll horizontally when point is inside the above margin. */
695 Lisp_Object Vhscroll_step;
696
697 /* The variable `resize-mini-windows'. If nil, don't resize
698 mini-windows. If t, always resize them to fit the text they
699 display. If `grow-only', let mini-windows grow only until they
700 become empty. */
701
702 Lisp_Object Vresize_mini_windows;
703
704 /* Buffer being redisplayed -- for redisplay_window_error. */
705
706 struct buffer *displayed_buffer;
707
708 /* Value returned from text property handlers (see below). */
709
710 enum prop_handled
711 {
712 HANDLED_NORMALLY,
713 HANDLED_RECOMPUTE_PROPS,
714 HANDLED_OVERLAY_STRING_CONSUMED,
715 HANDLED_RETURN
716 };
717
718 /* A description of text properties that redisplay is interested
719 in. */
720
721 struct props
722 {
723 /* The name of the property. */
724 Lisp_Object *name;
725
726 /* A unique index for the property. */
727 enum prop_idx idx;
728
729 /* A handler function called to set up iterator IT from the property
730 at IT's current position. Value is used to steer handle_stop. */
731 enum prop_handled (*handler) P_ ((struct it *it));
732 };
733
734 static enum prop_handled handle_face_prop P_ ((struct it *));
735 static enum prop_handled handle_invisible_prop P_ ((struct it *));
736 static enum prop_handled handle_display_prop P_ ((struct it *));
737 static enum prop_handled handle_composition_prop P_ ((struct it *));
738 static enum prop_handled handle_overlay_change P_ ((struct it *));
739 static enum prop_handled handle_fontified_prop P_ ((struct it *));
740
741 /* Properties handled by iterators. */
742
743 static struct props it_props[] =
744 {
745 {&Qfontified, FONTIFIED_PROP_IDX, handle_fontified_prop},
746 /* Handle `face' before `display' because some sub-properties of
747 `display' need to know the face. */
748 {&Qface, FACE_PROP_IDX, handle_face_prop},
749 {&Qdisplay, DISPLAY_PROP_IDX, handle_display_prop},
750 {&Qinvisible, INVISIBLE_PROP_IDX, handle_invisible_prop},
751 {&Qcomposition, COMPOSITION_PROP_IDX, handle_composition_prop},
752 {NULL, 0, NULL}
753 };
754
755 /* Value is the position described by X. If X is a marker, value is
756 the marker_position of X. Otherwise, value is X. */
757
758 #define COERCE_MARKER(X) (MARKERP ((X)) ? Fmarker_position (X) : (X))
759
760 /* Enumeration returned by some move_it_.* functions internally. */
761
762 enum move_it_result
763 {
764 /* Not used. Undefined value. */
765 MOVE_UNDEFINED,
766
767 /* Move ended at the requested buffer position or ZV. */
768 MOVE_POS_MATCH_OR_ZV,
769
770 /* Move ended at the requested X pixel position. */
771 MOVE_X_REACHED,
772
773 /* Move within a line ended at the end of a line that must be
774 continued. */
775 MOVE_LINE_CONTINUED,
776
777 /* Move within a line ended at the end of a line that would
778 be displayed truncated. */
779 MOVE_LINE_TRUNCATED,
780
781 /* Move within a line ended at a line end. */
782 MOVE_NEWLINE_OR_CR
783 };
784
785 /* This counter is used to clear the face cache every once in a while
786 in redisplay_internal. It is incremented for each redisplay.
787 Every CLEAR_FACE_CACHE_COUNT full redisplays, the face cache is
788 cleared. */
789
790 #define CLEAR_FACE_CACHE_COUNT 500
791 static int clear_face_cache_count;
792
793 /* Similarly for the image cache. */
794
795 #ifdef HAVE_WINDOW_SYSTEM
796 #define CLEAR_IMAGE_CACHE_COUNT 101
797 static int clear_image_cache_count;
798 #endif
799
800 /* Record the previous terminal frame we displayed. */
801
802 static struct frame *previous_terminal_frame;
803
804 /* Non-zero while redisplay_internal is in progress. */
805
806 int redisplaying_p;
807
808 /* Non-zero means don't free realized faces. Bound while freeing
809 realized faces is dangerous because glyph matrices might still
810 reference them. */
811
812 int inhibit_free_realized_faces;
813 Lisp_Object Qinhibit_free_realized_faces;
814
815 /* If a string, XTread_socket generates an event to display that string.
816 (The display is done in read_char.) */
817
818 Lisp_Object help_echo_string;
819 Lisp_Object help_echo_window;
820 Lisp_Object help_echo_object;
821 int help_echo_pos;
822
823 /* Temporary variable for XTread_socket. */
824
825 Lisp_Object previous_help_echo_string;
826
827 /* Null glyph slice */
828
829 static struct glyph_slice null_glyph_slice = { 0, 0, 0, 0 };
830
831 \f
832 /* Function prototypes. */
833
834 static void setup_for_ellipsis P_ ((struct it *, int));
835 static void mark_window_display_accurate_1 P_ ((struct window *, int));
836 static int single_display_spec_string_p P_ ((Lisp_Object, Lisp_Object));
837 static int display_prop_string_p P_ ((Lisp_Object, Lisp_Object));
838 static int cursor_row_p P_ ((struct window *, struct glyph_row *));
839 static int redisplay_mode_lines P_ ((Lisp_Object, int));
840 static char *decode_mode_spec_coding P_ ((Lisp_Object, char *, int));
841
842 #if 0
843 static int invisible_text_between_p P_ ((struct it *, int, int));
844 #endif
845
846 static void pint2str P_ ((char *, int, int));
847 static void pint2hrstr P_ ((char *, int, int));
848 static struct text_pos run_window_scroll_functions P_ ((Lisp_Object,
849 struct text_pos));
850 static void reconsider_clip_changes P_ ((struct window *, struct buffer *));
851 static int text_outside_line_unchanged_p P_ ((struct window *, int, int));
852 static void store_frame_title_char P_ ((char));
853 static int store_frame_title P_ ((const unsigned char *, int, int));
854 static void x_consider_frame_title P_ ((Lisp_Object));
855 static void handle_stop P_ ((struct it *));
856 static int tool_bar_lines_needed P_ ((struct frame *));
857 static int single_display_spec_intangible_p P_ ((Lisp_Object));
858 static void ensure_echo_area_buffers P_ ((void));
859 static Lisp_Object unwind_with_echo_area_buffer P_ ((Lisp_Object));
860 static Lisp_Object with_echo_area_buffer_unwind_data P_ ((struct window *));
861 static int with_echo_area_buffer P_ ((struct window *, int,
862 int (*) (EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT),
863 EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
864 static void clear_garbaged_frames P_ ((void));
865 static int current_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
866 static int truncate_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
867 static int set_message_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
868 static int display_echo_area P_ ((struct window *));
869 static int display_echo_area_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
870 static int resize_mini_window_1 P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
871 static Lisp_Object unwind_redisplay P_ ((Lisp_Object));
872 static int string_char_and_length P_ ((const unsigned char *, int, int *));
873 static struct text_pos display_prop_end P_ ((struct it *, Lisp_Object,
874 struct text_pos));
875 static int compute_window_start_on_continuation_line P_ ((struct window *));
876 static Lisp_Object safe_eval_handler P_ ((Lisp_Object));
877 static void insert_left_trunc_glyphs P_ ((struct it *));
878 static struct glyph_row *get_overlay_arrow_glyph_row P_ ((struct window *,
879 Lisp_Object));
880 static void extend_face_to_end_of_line P_ ((struct it *));
881 static int append_space_for_newline P_ ((struct it *, int));
882 static int cursor_row_fully_visible_p P_ ((struct window *, int, int));
883 static int try_scrolling P_ ((Lisp_Object, int, EMACS_INT, EMACS_INT, int, int));
884 static int try_cursor_movement P_ ((Lisp_Object, struct text_pos, int *));
885 static int trailing_whitespace_p P_ ((int));
886 static int message_log_check_duplicate P_ ((int, int, int, int));
887 static void push_it P_ ((struct it *));
888 static void pop_it P_ ((struct it *));
889 static void sync_frame_with_window_matrix_rows P_ ((struct window *));
890 static void select_frame_for_redisplay P_ ((Lisp_Object));
891 static void redisplay_internal P_ ((int));
892 static int echo_area_display P_ ((int));
893 static void redisplay_windows P_ ((Lisp_Object));
894 static void redisplay_window P_ ((Lisp_Object, int));
895 static Lisp_Object redisplay_window_error ();
896 static Lisp_Object redisplay_window_0 P_ ((Lisp_Object));
897 static Lisp_Object redisplay_window_1 P_ ((Lisp_Object));
898 static void update_menu_bar P_ ((struct frame *, int));
899 static int try_window_reusing_current_matrix P_ ((struct window *));
900 static int try_window_id P_ ((struct window *));
901 static int display_line P_ ((struct it *));
902 static int display_mode_lines P_ ((struct window *));
903 static int display_mode_line P_ ((struct window *, enum face_id, Lisp_Object));
904 static int display_mode_element P_ ((struct it *, int, int, int, Lisp_Object, Lisp_Object, int));
905 static int store_mode_line_string P_ ((char *, Lisp_Object, int, int, int, Lisp_Object));
906 static char *decode_mode_spec P_ ((struct window *, int, int, int, int *));
907 static void display_menu_bar P_ ((struct window *));
908 static int display_count_lines P_ ((int, int, int, int, int *));
909 static int display_string P_ ((unsigned char *, Lisp_Object, Lisp_Object,
910 int, int, struct it *, int, int, int, int));
911 static void compute_line_metrics P_ ((struct it *));
912 static void run_redisplay_end_trigger_hook P_ ((struct it *));
913 static int get_overlay_strings P_ ((struct it *, int));
914 static void next_overlay_string P_ ((struct it *));
915 static void reseat P_ ((struct it *, struct text_pos, int));
916 static void reseat_1 P_ ((struct it *, struct text_pos, int));
917 static void back_to_previous_visible_line_start P_ ((struct it *));
918 void reseat_at_previous_visible_line_start P_ ((struct it *));
919 static void reseat_at_next_visible_line_start P_ ((struct it *, int));
920 static int next_element_from_ellipsis P_ ((struct it *));
921 static int next_element_from_display_vector P_ ((struct it *));
922 static int next_element_from_string P_ ((struct it *));
923 static int next_element_from_c_string P_ ((struct it *));
924 static int next_element_from_buffer P_ ((struct it *));
925 static int next_element_from_composition P_ ((struct it *));
926 static int next_element_from_image P_ ((struct it *));
927 static int next_element_from_stretch P_ ((struct it *));
928 static void load_overlay_strings P_ ((struct it *, int));
929 static int init_from_display_pos P_ ((struct it *, struct window *,
930 struct display_pos *));
931 static void reseat_to_string P_ ((struct it *, unsigned char *,
932 Lisp_Object, int, int, int, int));
933 static enum move_it_result move_it_in_display_line_to P_ ((struct it *,
934 int, int, int));
935 void move_it_vertically_backward P_ ((struct it *, int));
936 static void init_to_row_start P_ ((struct it *, struct window *,
937 struct glyph_row *));
938 static int init_to_row_end P_ ((struct it *, struct window *,
939 struct glyph_row *));
940 static void back_to_previous_line_start P_ ((struct it *));
941 static int forward_to_next_line_start P_ ((struct it *, int *));
942 static struct text_pos string_pos_nchars_ahead P_ ((struct text_pos,
943 Lisp_Object, int));
944 static struct text_pos string_pos P_ ((int, Lisp_Object));
945 static struct text_pos c_string_pos P_ ((int, unsigned char *, int));
946 static int number_of_chars P_ ((unsigned char *, int));
947 static void compute_stop_pos P_ ((struct it *));
948 static void compute_string_pos P_ ((struct text_pos *, struct text_pos,
949 Lisp_Object));
950 static int face_before_or_after_it_pos P_ ((struct it *, int));
951 static int next_overlay_change P_ ((int));
952 static int handle_single_display_spec P_ ((struct it *, Lisp_Object,
953 Lisp_Object, struct text_pos *,
954 int));
955 static int underlying_face_id P_ ((struct it *));
956 static int in_ellipses_for_invisible_text_p P_ ((struct display_pos *,
957 struct window *));
958
959 #define face_before_it_pos(IT) face_before_or_after_it_pos ((IT), 1)
960 #define face_after_it_pos(IT) face_before_or_after_it_pos ((IT), 0)
961
962 #ifdef HAVE_WINDOW_SYSTEM
963
964 static void update_tool_bar P_ ((struct frame *, int));
965 static void build_desired_tool_bar_string P_ ((struct frame *f));
966 static int redisplay_tool_bar P_ ((struct frame *));
967 static void display_tool_bar_line P_ ((struct it *));
968 static void notice_overwritten_cursor P_ ((struct window *,
969 enum glyph_row_area,
970 int, int, int, int));
971
972
973
974 #endif /* HAVE_WINDOW_SYSTEM */
975
976 \f
977 /***********************************************************************
978 Window display dimensions
979 ***********************************************************************/
980
981 /* Return the bottom boundary y-position for text lines in window W.
982 This is the first y position at which a line cannot start.
983 It is relative to the top of the window.
984
985 This is the height of W minus the height of a mode line, if any. */
986
987 INLINE int
988 window_text_bottom_y (w)
989 struct window *w;
990 {
991 int height = WINDOW_TOTAL_HEIGHT (w);
992
993 if (WINDOW_WANTS_MODELINE_P (w))
994 height -= CURRENT_MODE_LINE_HEIGHT (w);
995 return height;
996 }
997
998 /* Return the pixel width of display area AREA of window W. AREA < 0
999 means return the total width of W, not including fringes to
1000 the left and right of the window. */
1001
1002 INLINE int
1003 window_box_width (w, area)
1004 struct window *w;
1005 int area;
1006 {
1007 int cols = XFASTINT (w->total_cols);
1008 int pixels = 0;
1009
1010 if (!w->pseudo_window_p)
1011 {
1012 cols -= WINDOW_SCROLL_BAR_COLS (w);
1013
1014 if (area == TEXT_AREA)
1015 {
1016 if (INTEGERP (w->left_margin_cols))
1017 cols -= XFASTINT (w->left_margin_cols);
1018 if (INTEGERP (w->right_margin_cols))
1019 cols -= XFASTINT (w->right_margin_cols);
1020 pixels = -WINDOW_TOTAL_FRINGE_WIDTH (w);
1021 }
1022 else if (area == LEFT_MARGIN_AREA)
1023 {
1024 cols = (INTEGERP (w->left_margin_cols)
1025 ? XFASTINT (w->left_margin_cols) : 0);
1026 pixels = 0;
1027 }
1028 else if (area == RIGHT_MARGIN_AREA)
1029 {
1030 cols = (INTEGERP (w->right_margin_cols)
1031 ? XFASTINT (w->right_margin_cols) : 0);
1032 pixels = 0;
1033 }
1034 }
1035
1036 return cols * WINDOW_FRAME_COLUMN_WIDTH (w) + pixels;
1037 }
1038
1039
1040 /* Return the pixel height of the display area of window W, not
1041 including mode lines of W, if any. */
1042
1043 INLINE int
1044 window_box_height (w)
1045 struct window *w;
1046 {
1047 struct frame *f = XFRAME (w->frame);
1048 int height = WINDOW_TOTAL_HEIGHT (w);
1049
1050 xassert (height >= 0);
1051
1052 /* Note: the code below that determines the mode-line/header-line
1053 height is essentially the same as that contained in the macro
1054 CURRENT_{MODE,HEADER}_LINE_HEIGHT, except that it checks whether
1055 the appropriate glyph row has its `mode_line_p' flag set,
1056 and if it doesn't, uses estimate_mode_line_height instead. */
1057
1058 if (WINDOW_WANTS_MODELINE_P (w))
1059 {
1060 struct glyph_row *ml_row
1061 = (w->current_matrix && w->current_matrix->rows
1062 ? MATRIX_MODE_LINE_ROW (w->current_matrix)
1063 : 0);
1064 if (ml_row && ml_row->mode_line_p)
1065 height -= ml_row->height;
1066 else
1067 height -= estimate_mode_line_height (f, CURRENT_MODE_LINE_FACE_ID (w));
1068 }
1069
1070 if (WINDOW_WANTS_HEADER_LINE_P (w))
1071 {
1072 struct glyph_row *hl_row
1073 = (w->current_matrix && w->current_matrix->rows
1074 ? MATRIX_HEADER_LINE_ROW (w->current_matrix)
1075 : 0);
1076 if (hl_row && hl_row->mode_line_p)
1077 height -= hl_row->height;
1078 else
1079 height -= estimate_mode_line_height (f, HEADER_LINE_FACE_ID);
1080 }
1081
1082 /* With a very small font and a mode-line that's taller than
1083 default, we might end up with a negative height. */
1084 return max (0, height);
1085 }
1086
1087 /* Return the window-relative coordinate of the left edge of display
1088 area AREA of window W. AREA < 0 means return the left edge of the
1089 whole window, to the right of the left fringe of W. */
1090
1091 INLINE int
1092 window_box_left_offset (w, area)
1093 struct window *w;
1094 int area;
1095 {
1096 int x;
1097
1098 if (w->pseudo_window_p)
1099 return 0;
1100
1101 x = WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
1102
1103 if (area == TEXT_AREA)
1104 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1105 + window_box_width (w, LEFT_MARGIN_AREA));
1106 else if (area == RIGHT_MARGIN_AREA)
1107 x += (WINDOW_LEFT_FRINGE_WIDTH (w)
1108 + window_box_width (w, LEFT_MARGIN_AREA)
1109 + window_box_width (w, TEXT_AREA)
1110 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
1111 ? 0
1112 : WINDOW_RIGHT_FRINGE_WIDTH (w)));
1113 else if (area == LEFT_MARGIN_AREA
1114 && WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w))
1115 x += WINDOW_LEFT_FRINGE_WIDTH (w);
1116
1117 return x;
1118 }
1119
1120
1121 /* Return the window-relative coordinate of the right edge of display
1122 area AREA of window W. AREA < 0 means return the left edge of the
1123 whole window, to the left of the right fringe of W. */
1124
1125 INLINE int
1126 window_box_right_offset (w, area)
1127 struct window *w;
1128 int area;
1129 {
1130 return window_box_left_offset (w, area) + window_box_width (w, area);
1131 }
1132
1133 /* Return the frame-relative coordinate of the left edge of display
1134 area AREA of window W. AREA < 0 means return the left edge of the
1135 whole window, to the right of the left fringe of W. */
1136
1137 INLINE int
1138 window_box_left (w, area)
1139 struct window *w;
1140 int area;
1141 {
1142 struct frame *f = XFRAME (w->frame);
1143 int x;
1144
1145 if (w->pseudo_window_p)
1146 return FRAME_INTERNAL_BORDER_WIDTH (f);
1147
1148 x = (WINDOW_LEFT_EDGE_X (w)
1149 + window_box_left_offset (w, area));
1150
1151 return x;
1152 }
1153
1154
1155 /* Return the frame-relative coordinate of the right edge of display
1156 area AREA of window W. AREA < 0 means return the left edge of the
1157 whole window, to the left of the right fringe of W. */
1158
1159 INLINE int
1160 window_box_right (w, area)
1161 struct window *w;
1162 int area;
1163 {
1164 return window_box_left (w, area) + window_box_width (w, area);
1165 }
1166
1167 /* Get the bounding box of the display area AREA of window W, without
1168 mode lines, in frame-relative coordinates. AREA < 0 means the
1169 whole window, not including the left and right fringes of
1170 the window. Return in *BOX_X and *BOX_Y the frame-relative pixel
1171 coordinates of the upper-left corner of the box. Return in
1172 *BOX_WIDTH, and *BOX_HEIGHT the pixel width and height of the box. */
1173
1174 INLINE void
1175 window_box (w, area, box_x, box_y, box_width, box_height)
1176 struct window *w;
1177 int area;
1178 int *box_x, *box_y, *box_width, *box_height;
1179 {
1180 if (box_width)
1181 *box_width = window_box_width (w, area);
1182 if (box_height)
1183 *box_height = window_box_height (w);
1184 if (box_x)
1185 *box_x = window_box_left (w, area);
1186 if (box_y)
1187 {
1188 *box_y = WINDOW_TOP_EDGE_Y (w);
1189 if (WINDOW_WANTS_HEADER_LINE_P (w))
1190 *box_y += CURRENT_HEADER_LINE_HEIGHT (w);
1191 }
1192 }
1193
1194
1195 /* Get the bounding box of the display area AREA of window W, without
1196 mode lines. AREA < 0 means the whole window, not including the
1197 left and right fringe of the window. Return in *TOP_LEFT_X
1198 and TOP_LEFT_Y the frame-relative pixel coordinates of the
1199 upper-left corner of the box. Return in *BOTTOM_RIGHT_X, and
1200 *BOTTOM_RIGHT_Y the coordinates of the bottom-right corner of the
1201 box. */
1202
1203 INLINE void
1204 window_box_edges (w, area, top_left_x, top_left_y,
1205 bottom_right_x, bottom_right_y)
1206 struct window *w;
1207 int area;
1208 int *top_left_x, *top_left_y, *bottom_right_x, *bottom_right_y;
1209 {
1210 window_box (w, area, top_left_x, top_left_y, bottom_right_x,
1211 bottom_right_y);
1212 *bottom_right_x += *top_left_x;
1213 *bottom_right_y += *top_left_y;
1214 }
1215
1216
1217 \f
1218 /***********************************************************************
1219 Utilities
1220 ***********************************************************************/
1221
1222 /* Return the bottom y-position of the line the iterator IT is in.
1223 This can modify IT's settings. */
1224
1225 int
1226 line_bottom_y (it)
1227 struct it *it;
1228 {
1229 int line_height = it->max_ascent + it->max_descent;
1230 int line_top_y = it->current_y;
1231
1232 if (line_height == 0)
1233 {
1234 if (last_height)
1235 line_height = last_height;
1236 else if (IT_CHARPOS (*it) < ZV)
1237 {
1238 move_it_by_lines (it, 1, 1);
1239 line_height = (it->max_ascent || it->max_descent
1240 ? it->max_ascent + it->max_descent
1241 : last_height);
1242 }
1243 else
1244 {
1245 struct glyph_row *row = it->glyph_row;
1246
1247 /* Use the default character height. */
1248 it->glyph_row = NULL;
1249 it->what = IT_CHARACTER;
1250 it->c = ' ';
1251 it->len = 1;
1252 PRODUCE_GLYPHS (it);
1253 line_height = it->ascent + it->descent;
1254 it->glyph_row = row;
1255 }
1256 }
1257
1258 return line_top_y + line_height;
1259 }
1260
1261
1262 /* Return 1 if position CHARPOS is visible in window W.
1263 If visible, set *X and *Y to pixel coordinates of top left corner.
1264 Set *RTOP and *RBOT to pixel height of an invisible area of glyph at POS.
1265 EXACT_MODE_LINE_HEIGHTS_P non-zero means compute exact mode-line
1266 and header-lines heights. */
1267
1268 int
1269 pos_visible_p (w, charpos, x, y, rtop, rbot, exact_mode_line_heights_p)
1270 struct window *w;
1271 int charpos, *x, *y, *rtop, *rbot, exact_mode_line_heights_p;
1272 {
1273 struct it it;
1274 struct text_pos top;
1275 int visible_p = 0;
1276 struct buffer *old_buffer = NULL;
1277
1278 if (noninteractive)
1279 return visible_p;
1280
1281 if (XBUFFER (w->buffer) != current_buffer)
1282 {
1283 old_buffer = current_buffer;
1284 set_buffer_internal_1 (XBUFFER (w->buffer));
1285 }
1286
1287 SET_TEXT_POS_FROM_MARKER (top, w->start);
1288
1289 /* Compute exact mode line heights, if requested. */
1290 if (exact_mode_line_heights_p)
1291 {
1292 if (WINDOW_WANTS_MODELINE_P (w))
1293 current_mode_line_height
1294 = display_mode_line (w, CURRENT_MODE_LINE_FACE_ID (w),
1295 current_buffer->mode_line_format);
1296
1297 if (WINDOW_WANTS_HEADER_LINE_P (w))
1298 current_header_line_height
1299 = display_mode_line (w, HEADER_LINE_FACE_ID,
1300 current_buffer->header_line_format);
1301 }
1302
1303 start_display (&it, w, top);
1304 move_it_to (&it, charpos, -1, it.last_visible_y, -1,
1305 MOVE_TO_POS | MOVE_TO_Y);
1306
1307 /* Note that we may overshoot because of invisible text. */
1308 if (IT_CHARPOS (it) >= charpos)
1309 {
1310 int top_x = it.current_x;
1311 int top_y = it.current_y;
1312 int bottom_y = (last_height = 0, line_bottom_y (&it));
1313 int window_top_y = WINDOW_HEADER_LINE_HEIGHT (w);
1314
1315 if (top_y < window_top_y)
1316 visible_p = bottom_y > window_top_y;
1317 else if (top_y < it.last_visible_y)
1318 visible_p = 1;
1319 if (visible_p)
1320 {
1321 *x = top_x;
1322 *y = max (top_y + max (0, it.max_ascent - it.ascent), window_top_y);
1323 *rtop = max (0, window_top_y - top_y);
1324 *rbot = max (0, bottom_y - it.last_visible_y);
1325 }
1326 }
1327 else
1328 {
1329 struct it it2;
1330
1331 it2 = it;
1332 if (IT_CHARPOS (it) < ZV && FETCH_BYTE (IT_BYTEPOS (it)) != '\n')
1333 move_it_by_lines (&it, 1, 0);
1334 if (charpos < IT_CHARPOS (it))
1335 {
1336 visible_p = 1;
1337 move_it_to (&it2, charpos, -1, -1, -1, MOVE_TO_POS);
1338 *x = it2.current_x;
1339 *y = it2.current_y + it2.max_ascent - it2.ascent;
1340 *rtop = max (0, -it2.current_y);
1341 *rbot = max (0, ((it2.current_y + it2.max_ascent + it2.max_descent)
1342 - it.last_visible_y));
1343 }
1344 }
1345
1346 if (old_buffer)
1347 set_buffer_internal_1 (old_buffer);
1348
1349 current_header_line_height = current_mode_line_height = -1;
1350
1351 return visible_p;
1352 }
1353
1354
1355 /* Return the next character from STR which is MAXLEN bytes long.
1356 Return in *LEN the length of the character. This is like
1357 STRING_CHAR_AND_LENGTH but never returns an invalid character. If
1358 we find one, we return a `?', but with the length of the invalid
1359 character. */
1360
1361 static INLINE int
1362 string_char_and_length (str, maxlen, len)
1363 const unsigned char *str;
1364 int maxlen, *len;
1365 {
1366 int c;
1367
1368 c = STRING_CHAR_AND_LENGTH (str, maxlen, *len);
1369 if (!CHAR_VALID_P (c, 1))
1370 /* We may not change the length here because other places in Emacs
1371 don't use this function, i.e. they silently accept invalid
1372 characters. */
1373 c = '?';
1374
1375 return c;
1376 }
1377
1378
1379
1380 /* Given a position POS containing a valid character and byte position
1381 in STRING, return the position NCHARS ahead (NCHARS >= 0). */
1382
1383 static struct text_pos
1384 string_pos_nchars_ahead (pos, string, nchars)
1385 struct text_pos pos;
1386 Lisp_Object string;
1387 int nchars;
1388 {
1389 xassert (STRINGP (string) && nchars >= 0);
1390
1391 if (STRING_MULTIBYTE (string))
1392 {
1393 int rest = SBYTES (string) - BYTEPOS (pos);
1394 const unsigned char *p = SDATA (string) + BYTEPOS (pos);
1395 int len;
1396
1397 while (nchars--)
1398 {
1399 string_char_and_length (p, rest, &len);
1400 p += len, rest -= len;
1401 xassert (rest >= 0);
1402 CHARPOS (pos) += 1;
1403 BYTEPOS (pos) += len;
1404 }
1405 }
1406 else
1407 SET_TEXT_POS (pos, CHARPOS (pos) + nchars, BYTEPOS (pos) + nchars);
1408
1409 return pos;
1410 }
1411
1412
1413 /* Value is the text position, i.e. character and byte position,
1414 for character position CHARPOS in STRING. */
1415
1416 static INLINE struct text_pos
1417 string_pos (charpos, string)
1418 int charpos;
1419 Lisp_Object string;
1420 {
1421 struct text_pos pos;
1422 xassert (STRINGP (string));
1423 xassert (charpos >= 0);
1424 SET_TEXT_POS (pos, charpos, string_char_to_byte (string, charpos));
1425 return pos;
1426 }
1427
1428
1429 /* Value is a text position, i.e. character and byte position, for
1430 character position CHARPOS in C string S. MULTIBYTE_P non-zero
1431 means recognize multibyte characters. */
1432
1433 static struct text_pos
1434 c_string_pos (charpos, s, multibyte_p)
1435 int charpos;
1436 unsigned char *s;
1437 int multibyte_p;
1438 {
1439 struct text_pos pos;
1440
1441 xassert (s != NULL);
1442 xassert (charpos >= 0);
1443
1444 if (multibyte_p)
1445 {
1446 int rest = strlen (s), len;
1447
1448 SET_TEXT_POS (pos, 0, 0);
1449 while (charpos--)
1450 {
1451 string_char_and_length (s, rest, &len);
1452 s += len, rest -= len;
1453 xassert (rest >= 0);
1454 CHARPOS (pos) += 1;
1455 BYTEPOS (pos) += len;
1456 }
1457 }
1458 else
1459 SET_TEXT_POS (pos, charpos, charpos);
1460
1461 return pos;
1462 }
1463
1464
1465 /* Value is the number of characters in C string S. MULTIBYTE_P
1466 non-zero means recognize multibyte characters. */
1467
1468 static int
1469 number_of_chars (s, multibyte_p)
1470 unsigned char *s;
1471 int multibyte_p;
1472 {
1473 int nchars;
1474
1475 if (multibyte_p)
1476 {
1477 int rest = strlen (s), len;
1478 unsigned char *p = (unsigned char *) s;
1479
1480 for (nchars = 0; rest > 0; ++nchars)
1481 {
1482 string_char_and_length (p, rest, &len);
1483 rest -= len, p += len;
1484 }
1485 }
1486 else
1487 nchars = strlen (s);
1488
1489 return nchars;
1490 }
1491
1492
1493 /* Compute byte position NEWPOS->bytepos corresponding to
1494 NEWPOS->charpos. POS is a known position in string STRING.
1495 NEWPOS->charpos must be >= POS.charpos. */
1496
1497 static void
1498 compute_string_pos (newpos, pos, string)
1499 struct text_pos *newpos, pos;
1500 Lisp_Object string;
1501 {
1502 xassert (STRINGP (string));
1503 xassert (CHARPOS (*newpos) >= CHARPOS (pos));
1504
1505 if (STRING_MULTIBYTE (string))
1506 *newpos = string_pos_nchars_ahead (pos, string,
1507 CHARPOS (*newpos) - CHARPOS (pos));
1508 else
1509 BYTEPOS (*newpos) = CHARPOS (*newpos);
1510 }
1511
1512 /* EXPORT:
1513 Return an estimation of the pixel height of mode or top lines on
1514 frame F. FACE_ID specifies what line's height to estimate. */
1515
1516 int
1517 estimate_mode_line_height (f, face_id)
1518 struct frame *f;
1519 enum face_id face_id;
1520 {
1521 #ifdef HAVE_WINDOW_SYSTEM
1522 if (FRAME_WINDOW_P (f))
1523 {
1524 int height = FONT_HEIGHT (FRAME_FONT (f));
1525
1526 /* This function is called so early when Emacs starts that the face
1527 cache and mode line face are not yet initialized. */
1528 if (FRAME_FACE_CACHE (f))
1529 {
1530 struct face *face = FACE_FROM_ID (f, face_id);
1531 if (face)
1532 {
1533 if (face->font)
1534 height = FONT_HEIGHT (face->font);
1535 if (face->box_line_width > 0)
1536 height += 2 * face->box_line_width;
1537 }
1538 }
1539
1540 return height;
1541 }
1542 #endif
1543
1544 return 1;
1545 }
1546
1547 /* Given a pixel position (PIX_X, PIX_Y) on frame F, return glyph
1548 co-ordinates in (*X, *Y). Set *BOUNDS to the rectangle that the
1549 glyph at X, Y occupies, if BOUNDS != 0. If NOCLIP is non-zero, do
1550 not force the value into range. */
1551
1552 void
1553 pixel_to_glyph_coords (f, pix_x, pix_y, x, y, bounds, noclip)
1554 FRAME_PTR f;
1555 register int pix_x, pix_y;
1556 int *x, *y;
1557 NativeRectangle *bounds;
1558 int noclip;
1559 {
1560
1561 #ifdef HAVE_WINDOW_SYSTEM
1562 if (FRAME_WINDOW_P (f))
1563 {
1564 /* Arrange for the division in FRAME_PIXEL_X_TO_COL etc. to round down
1565 even for negative values. */
1566 if (pix_x < 0)
1567 pix_x -= FRAME_COLUMN_WIDTH (f) - 1;
1568 if (pix_y < 0)
1569 pix_y -= FRAME_LINE_HEIGHT (f) - 1;
1570
1571 pix_x = FRAME_PIXEL_X_TO_COL (f, pix_x);
1572 pix_y = FRAME_PIXEL_Y_TO_LINE (f, pix_y);
1573
1574 if (bounds)
1575 STORE_NATIVE_RECT (*bounds,
1576 FRAME_COL_TO_PIXEL_X (f, pix_x),
1577 FRAME_LINE_TO_PIXEL_Y (f, pix_y),
1578 FRAME_COLUMN_WIDTH (f) - 1,
1579 FRAME_LINE_HEIGHT (f) - 1);
1580
1581 if (!noclip)
1582 {
1583 if (pix_x < 0)
1584 pix_x = 0;
1585 else if (pix_x > FRAME_TOTAL_COLS (f))
1586 pix_x = FRAME_TOTAL_COLS (f);
1587
1588 if (pix_y < 0)
1589 pix_y = 0;
1590 else if (pix_y > FRAME_LINES (f))
1591 pix_y = FRAME_LINES (f);
1592 }
1593 }
1594 #endif
1595
1596 *x = pix_x;
1597 *y = pix_y;
1598 }
1599
1600
1601 /* Given HPOS/VPOS in the current matrix of W, return corresponding
1602 frame-relative pixel positions in *FRAME_X and *FRAME_Y. If we
1603 can't tell the positions because W's display is not up to date,
1604 return 0. */
1605
1606 int
1607 glyph_to_pixel_coords (w, hpos, vpos, frame_x, frame_y)
1608 struct window *w;
1609 int hpos, vpos;
1610 int *frame_x, *frame_y;
1611 {
1612 #ifdef HAVE_WINDOW_SYSTEM
1613 if (FRAME_WINDOW_P (XFRAME (WINDOW_FRAME (w))))
1614 {
1615 int success_p;
1616
1617 xassert (hpos >= 0 && hpos < w->current_matrix->matrix_w);
1618 xassert (vpos >= 0 && vpos < w->current_matrix->matrix_h);
1619
1620 if (display_completed)
1621 {
1622 struct glyph_row *row = MATRIX_ROW (w->current_matrix, vpos);
1623 struct glyph *glyph = row->glyphs[TEXT_AREA];
1624 struct glyph *end = glyph + min (hpos, row->used[TEXT_AREA]);
1625
1626 hpos = row->x;
1627 vpos = row->y;
1628 while (glyph < end)
1629 {
1630 hpos += glyph->pixel_width;
1631 ++glyph;
1632 }
1633
1634 /* If first glyph is partially visible, its first visible position is still 0. */
1635 if (hpos < 0)
1636 hpos = 0;
1637
1638 success_p = 1;
1639 }
1640 else
1641 {
1642 hpos = vpos = 0;
1643 success_p = 0;
1644 }
1645
1646 *frame_x = WINDOW_TO_FRAME_PIXEL_X (w, hpos);
1647 *frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, vpos);
1648 return success_p;
1649 }
1650 #endif
1651
1652 *frame_x = hpos;
1653 *frame_y = vpos;
1654 return 1;
1655 }
1656
1657
1658 #ifdef HAVE_WINDOW_SYSTEM
1659
1660 /* Find the glyph under window-relative coordinates X/Y in window W.
1661 Consider only glyphs from buffer text, i.e. no glyphs from overlay
1662 strings. Return in *HPOS and *VPOS the row and column number of
1663 the glyph found. Return in *AREA the glyph area containing X.
1664 Value is a pointer to the glyph found or null if X/Y is not on
1665 text, or we can't tell because W's current matrix is not up to
1666 date. */
1667
1668 static struct glyph *
1669 x_y_to_hpos_vpos (w, x, y, hpos, vpos, dx, dy, area)
1670 struct window *w;
1671 int x, y;
1672 int *hpos, *vpos, *dx, *dy, *area;
1673 {
1674 struct glyph *glyph, *end;
1675 struct glyph_row *row = NULL;
1676 int x0, i;
1677
1678 /* Find row containing Y. Give up if some row is not enabled. */
1679 for (i = 0; i < w->current_matrix->nrows; ++i)
1680 {
1681 row = MATRIX_ROW (w->current_matrix, i);
1682 if (!row->enabled_p)
1683 return NULL;
1684 if (y >= row->y && y < MATRIX_ROW_BOTTOM_Y (row))
1685 break;
1686 }
1687
1688 *vpos = i;
1689 *hpos = 0;
1690
1691 /* Give up if Y is not in the window. */
1692 if (i == w->current_matrix->nrows)
1693 return NULL;
1694
1695 /* Get the glyph area containing X. */
1696 if (w->pseudo_window_p)
1697 {
1698 *area = TEXT_AREA;
1699 x0 = 0;
1700 }
1701 else
1702 {
1703 if (x < window_box_left_offset (w, TEXT_AREA))
1704 {
1705 *area = LEFT_MARGIN_AREA;
1706 x0 = window_box_left_offset (w, LEFT_MARGIN_AREA);
1707 }
1708 else if (x < window_box_right_offset (w, TEXT_AREA))
1709 {
1710 *area = TEXT_AREA;
1711 x0 = window_box_left_offset (w, TEXT_AREA) + min (row->x, 0);
1712 }
1713 else
1714 {
1715 *area = RIGHT_MARGIN_AREA;
1716 x0 = window_box_left_offset (w, RIGHT_MARGIN_AREA);
1717 }
1718 }
1719
1720 /* Find glyph containing X. */
1721 glyph = row->glyphs[*area];
1722 end = glyph + row->used[*area];
1723 x -= x0;
1724 while (glyph < end && x >= glyph->pixel_width)
1725 {
1726 x -= glyph->pixel_width;
1727 ++glyph;
1728 }
1729
1730 if (glyph == end)
1731 return NULL;
1732
1733 if (dx)
1734 {
1735 *dx = x;
1736 *dy = y - (row->y + row->ascent - glyph->ascent);
1737 }
1738
1739 *hpos = glyph - row->glyphs[*area];
1740 return glyph;
1741 }
1742
1743
1744 /* EXPORT:
1745 Convert frame-relative x/y to coordinates relative to window W.
1746 Takes pseudo-windows into account. */
1747
1748 void
1749 frame_to_window_pixel_xy (w, x, y)
1750 struct window *w;
1751 int *x, *y;
1752 {
1753 if (w->pseudo_window_p)
1754 {
1755 /* A pseudo-window is always full-width, and starts at the
1756 left edge of the frame, plus a frame border. */
1757 struct frame *f = XFRAME (w->frame);
1758 *x -= FRAME_INTERNAL_BORDER_WIDTH (f);
1759 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1760 }
1761 else
1762 {
1763 *x -= WINDOW_LEFT_EDGE_X (w);
1764 *y = FRAME_TO_WINDOW_PIXEL_Y (w, *y);
1765 }
1766 }
1767
1768 /* EXPORT:
1769 Return in *R the clipping rectangle for glyph string S. */
1770
1771 void
1772 get_glyph_string_clip_rect (s, nr)
1773 struct glyph_string *s;
1774 NativeRectangle *nr;
1775 {
1776 XRectangle r;
1777
1778 if (s->row->full_width_p)
1779 {
1780 /* Draw full-width. X coordinates are relative to S->w->left_col. */
1781 r.x = WINDOW_LEFT_EDGE_X (s->w);
1782 r.width = WINDOW_TOTAL_WIDTH (s->w);
1783
1784 /* Unless displaying a mode or menu bar line, which are always
1785 fully visible, clip to the visible part of the row. */
1786 if (s->w->pseudo_window_p)
1787 r.height = s->row->visible_height;
1788 else
1789 r.height = s->height;
1790 }
1791 else
1792 {
1793 /* This is a text line that may be partially visible. */
1794 r.x = window_box_left (s->w, s->area);
1795 r.width = window_box_width (s->w, s->area);
1796 r.height = s->row->visible_height;
1797 }
1798
1799 if (s->clip_head)
1800 if (r.x < s->clip_head->x)
1801 {
1802 if (r.width >= s->clip_head->x - r.x)
1803 r.width -= s->clip_head->x - r.x;
1804 else
1805 r.width = 0;
1806 r.x = s->clip_head->x;
1807 }
1808 if (s->clip_tail)
1809 if (r.x + r.width > s->clip_tail->x + s->clip_tail->background_width)
1810 {
1811 if (s->clip_tail->x + s->clip_tail->background_width >= r.x)
1812 r.width = s->clip_tail->x + s->clip_tail->background_width - r.x;
1813 else
1814 r.width = 0;
1815 }
1816
1817 /* If S draws overlapping rows, it's sufficient to use the top and
1818 bottom of the window for clipping because this glyph string
1819 intentionally draws over other lines. */
1820 if (s->for_overlaps_p)
1821 {
1822 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1823 r.height = window_text_bottom_y (s->w) - r.y;
1824 }
1825 else
1826 {
1827 /* Don't use S->y for clipping because it doesn't take partially
1828 visible lines into account. For example, it can be negative for
1829 partially visible lines at the top of a window. */
1830 if (!s->row->full_width_p
1831 && MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (s->w, s->row))
1832 r.y = WINDOW_HEADER_LINE_HEIGHT (s->w);
1833 else
1834 r.y = max (0, s->row->y);
1835
1836 /* If drawing a tool-bar window, draw it over the internal border
1837 at the top of the window. */
1838 if (WINDOWP (s->f->tool_bar_window)
1839 && s->w == XWINDOW (s->f->tool_bar_window))
1840 r.y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
1841 }
1842
1843 r.y = WINDOW_TO_FRAME_PIXEL_Y (s->w, r.y);
1844
1845 /* If drawing the cursor, don't let glyph draw outside its
1846 advertised boundaries. Cleartype does this under some circumstances. */
1847 if (s->hl == DRAW_CURSOR)
1848 {
1849 struct glyph *glyph = s->first_glyph;
1850 int height, max_y;
1851
1852 if (s->x > r.x)
1853 {
1854 r.width -= s->x - r.x;
1855 r.x = s->x;
1856 }
1857 r.width = min (r.width, glyph->pixel_width);
1858
1859 /* If r.y is below window bottom, ensure that we still see a cursor. */
1860 height = min (glyph->ascent + glyph->descent,
1861 min (FRAME_LINE_HEIGHT (s->f), s->row->visible_height));
1862 max_y = window_text_bottom_y (s->w) - height;
1863 max_y = WINDOW_TO_FRAME_PIXEL_Y (s->w, max_y);
1864 if (s->ybase - glyph->ascent > max_y)
1865 {
1866 r.y = max_y;
1867 r.height = height;
1868 }
1869 else
1870 {
1871 /* Don't draw cursor glyph taller than our actual glyph. */
1872 height = max (FRAME_LINE_HEIGHT (s->f), glyph->ascent + glyph->descent);
1873 if (height < r.height)
1874 {
1875 max_y = r.y + r.height;
1876 r.y = min (max_y, max (r.y, s->ybase + glyph->descent - height));
1877 r.height = min (max_y - r.y, height);
1878 }
1879 }
1880 }
1881
1882 #ifdef CONVERT_FROM_XRECT
1883 CONVERT_FROM_XRECT (r, *nr);
1884 #else
1885 *nr = r;
1886 #endif
1887 }
1888
1889
1890 /* EXPORT:
1891 Return the position and height of the phys cursor in window W.
1892 Set w->phys_cursor_width to width of phys cursor.
1893 */
1894
1895 int
1896 get_phys_cursor_geometry (w, row, glyph, heightp)
1897 struct window *w;
1898 struct glyph_row *row;
1899 struct glyph *glyph;
1900 int *heightp;
1901 {
1902 struct frame *f = XFRAME (WINDOW_FRAME (w));
1903 int x, y, wd, h, h0, y0;
1904
1905 /* Compute the width of the rectangle to draw. If on a stretch
1906 glyph, and `x-stretch-block-cursor' is nil, don't draw a
1907 rectangle as wide as the glyph, but use a canonical character
1908 width instead. */
1909 wd = glyph->pixel_width - 1;
1910 #ifdef HAVE_NTGUI
1911 wd++; /* Why? */
1912 #endif
1913 if (glyph->type == STRETCH_GLYPH
1914 && !x_stretch_cursor_p)
1915 wd = min (FRAME_COLUMN_WIDTH (f), wd);
1916 w->phys_cursor_width = wd;
1917
1918 y = w->phys_cursor.y + row->ascent - glyph->ascent;
1919
1920 /* If y is below window bottom, ensure that we still see a cursor. */
1921 h0 = min (FRAME_LINE_HEIGHT (f), row->visible_height);
1922
1923 h = max (h0, glyph->ascent + glyph->descent);
1924 h0 = min (h0, glyph->ascent + glyph->descent);
1925
1926 y0 = WINDOW_HEADER_LINE_HEIGHT (w);
1927 if (y < y0)
1928 {
1929 h = max (h - (y0 - y) + 1, h0);
1930 y = y0 - 1;
1931 }
1932 else
1933 {
1934 y0 = window_text_bottom_y (w) - h0;
1935 if (y > y0)
1936 {
1937 h += y - y0;
1938 y = y0;
1939 }
1940 }
1941
1942 *heightp = h - 1;
1943 return WINDOW_TO_FRAME_PIXEL_Y (w, y);
1944 }
1945
1946
1947 #endif /* HAVE_WINDOW_SYSTEM */
1948
1949 \f
1950 /***********************************************************************
1951 Lisp form evaluation
1952 ***********************************************************************/
1953
1954 /* Error handler for safe_eval and safe_call. */
1955
1956 static Lisp_Object
1957 safe_eval_handler (arg)
1958 Lisp_Object arg;
1959 {
1960 add_to_log ("Error during redisplay: %s", arg, Qnil);
1961 return Qnil;
1962 }
1963
1964
1965 /* Evaluate SEXPR and return the result, or nil if something went
1966 wrong. Prevent redisplay during the evaluation. */
1967
1968 Lisp_Object
1969 safe_eval (sexpr)
1970 Lisp_Object sexpr;
1971 {
1972 Lisp_Object val;
1973
1974 if (inhibit_eval_during_redisplay)
1975 val = Qnil;
1976 else
1977 {
1978 int count = SPECPDL_INDEX ();
1979 struct gcpro gcpro1;
1980
1981 GCPRO1 (sexpr);
1982 specbind (Qinhibit_redisplay, Qt);
1983 /* Use Qt to ensure debugger does not run,
1984 so there is no possibility of wanting to redisplay. */
1985 val = internal_condition_case_1 (Feval, sexpr, Qt,
1986 safe_eval_handler);
1987 UNGCPRO;
1988 val = unbind_to (count, val);
1989 }
1990
1991 return val;
1992 }
1993
1994
1995 /* Call function ARGS[0] with arguments ARGS[1] to ARGS[NARGS - 1].
1996 Return the result, or nil if something went wrong. Prevent
1997 redisplay during the evaluation. */
1998
1999 Lisp_Object
2000 safe_call (nargs, args)
2001 int nargs;
2002 Lisp_Object *args;
2003 {
2004 Lisp_Object val;
2005
2006 if (inhibit_eval_during_redisplay)
2007 val = Qnil;
2008 else
2009 {
2010 int count = SPECPDL_INDEX ();
2011 struct gcpro gcpro1;
2012
2013 GCPRO1 (args[0]);
2014 gcpro1.nvars = nargs;
2015 specbind (Qinhibit_redisplay, Qt);
2016 /* Use Qt to ensure debugger does not run,
2017 so there is no possibility of wanting to redisplay. */
2018 val = internal_condition_case_2 (Ffuncall, nargs, args, Qt,
2019 safe_eval_handler);
2020 UNGCPRO;
2021 val = unbind_to (count, val);
2022 }
2023
2024 return val;
2025 }
2026
2027
2028 /* Call function FN with one argument ARG.
2029 Return the result, or nil if something went wrong. */
2030
2031 Lisp_Object
2032 safe_call1 (fn, arg)
2033 Lisp_Object fn, arg;
2034 {
2035 Lisp_Object args[2];
2036 args[0] = fn;
2037 args[1] = arg;
2038 return safe_call (2, args);
2039 }
2040
2041
2042 \f
2043 /***********************************************************************
2044 Debugging
2045 ***********************************************************************/
2046
2047 #if 0
2048
2049 /* Define CHECK_IT to perform sanity checks on iterators.
2050 This is for debugging. It is too slow to do unconditionally. */
2051
2052 static void
2053 check_it (it)
2054 struct it *it;
2055 {
2056 if (it->method == GET_FROM_STRING)
2057 {
2058 xassert (STRINGP (it->string));
2059 xassert (IT_STRING_CHARPOS (*it) >= 0);
2060 }
2061 else
2062 {
2063 xassert (IT_STRING_CHARPOS (*it) < 0);
2064 if (it->method == GET_FROM_BUFFER)
2065 {
2066 /* Check that character and byte positions agree. */
2067 xassert (IT_CHARPOS (*it) == BYTE_TO_CHAR (IT_BYTEPOS (*it)));
2068 }
2069 }
2070
2071 if (it->dpvec)
2072 xassert (it->current.dpvec_index >= 0);
2073 else
2074 xassert (it->current.dpvec_index < 0);
2075 }
2076
2077 #define CHECK_IT(IT) check_it ((IT))
2078
2079 #else /* not 0 */
2080
2081 #define CHECK_IT(IT) (void) 0
2082
2083 #endif /* not 0 */
2084
2085
2086 #if GLYPH_DEBUG
2087
2088 /* Check that the window end of window W is what we expect it
2089 to be---the last row in the current matrix displaying text. */
2090
2091 static void
2092 check_window_end (w)
2093 struct window *w;
2094 {
2095 if (!MINI_WINDOW_P (w)
2096 && !NILP (w->window_end_valid))
2097 {
2098 struct glyph_row *row;
2099 xassert ((row = MATRIX_ROW (w->current_matrix,
2100 XFASTINT (w->window_end_vpos)),
2101 !row->enabled_p
2102 || MATRIX_ROW_DISPLAYS_TEXT_P (row)
2103 || MATRIX_ROW_VPOS (row, w->current_matrix) == 0));
2104 }
2105 }
2106
2107 #define CHECK_WINDOW_END(W) check_window_end ((W))
2108
2109 #else /* not GLYPH_DEBUG */
2110
2111 #define CHECK_WINDOW_END(W) (void) 0
2112
2113 #endif /* not GLYPH_DEBUG */
2114
2115
2116 \f
2117 /***********************************************************************
2118 Iterator initialization
2119 ***********************************************************************/
2120
2121 /* Initialize IT for displaying current_buffer in window W, starting
2122 at character position CHARPOS. CHARPOS < 0 means that no buffer
2123 position is specified which is useful when the iterator is assigned
2124 a position later. BYTEPOS is the byte position corresponding to
2125 CHARPOS. BYTEPOS < 0 means compute it from CHARPOS.
2126
2127 If ROW is not null, calls to produce_glyphs with IT as parameter
2128 will produce glyphs in that row.
2129
2130 BASE_FACE_ID is the id of a base face to use. It must be one of
2131 DEFAULT_FACE_ID for normal text, MODE_LINE_FACE_ID,
2132 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID for displaying
2133 mode lines, or TOOL_BAR_FACE_ID for displaying the tool-bar.
2134
2135 If ROW is null and BASE_FACE_ID is equal to MODE_LINE_FACE_ID,
2136 MODE_LINE_INACTIVE_FACE_ID, or HEADER_LINE_FACE_ID, the iterator
2137 will be initialized to use the corresponding mode line glyph row of
2138 the desired matrix of W. */
2139
2140 void
2141 init_iterator (it, w, charpos, bytepos, row, base_face_id)
2142 struct it *it;
2143 struct window *w;
2144 int charpos, bytepos;
2145 struct glyph_row *row;
2146 enum face_id base_face_id;
2147 {
2148 int highlight_region_p;
2149
2150 /* Some precondition checks. */
2151 xassert (w != NULL && it != NULL);
2152 xassert (charpos < 0 || (charpos >= BUF_BEG (current_buffer)
2153 && charpos <= ZV));
2154
2155 /* If face attributes have been changed since the last redisplay,
2156 free realized faces now because they depend on face definitions
2157 that might have changed. Don't free faces while there might be
2158 desired matrices pending which reference these faces. */
2159 if (face_change_count && !inhibit_free_realized_faces)
2160 {
2161 face_change_count = 0;
2162 free_all_realized_faces (Qnil);
2163 }
2164
2165 /* Use one of the mode line rows of W's desired matrix if
2166 appropriate. */
2167 if (row == NULL)
2168 {
2169 if (base_face_id == MODE_LINE_FACE_ID
2170 || base_face_id == MODE_LINE_INACTIVE_FACE_ID)
2171 row = MATRIX_MODE_LINE_ROW (w->desired_matrix);
2172 else if (base_face_id == HEADER_LINE_FACE_ID)
2173 row = MATRIX_HEADER_LINE_ROW (w->desired_matrix);
2174 }
2175
2176 /* Clear IT. */
2177 bzero (it, sizeof *it);
2178 it->current.overlay_string_index = -1;
2179 it->current.dpvec_index = -1;
2180 it->base_face_id = base_face_id;
2181 it->string = Qnil;
2182 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
2183
2184 /* The window in which we iterate over current_buffer: */
2185 XSETWINDOW (it->window, w);
2186 it->w = w;
2187 it->f = XFRAME (w->frame);
2188
2189 /* Extra space between lines (on window systems only). */
2190 if (base_face_id == DEFAULT_FACE_ID
2191 && FRAME_WINDOW_P (it->f))
2192 {
2193 if (NATNUMP (current_buffer->extra_line_spacing))
2194 it->extra_line_spacing = XFASTINT (current_buffer->extra_line_spacing);
2195 else if (FLOATP (current_buffer->extra_line_spacing))
2196 it->extra_line_spacing = (XFLOAT_DATA (current_buffer->extra_line_spacing)
2197 * FRAME_LINE_HEIGHT (it->f));
2198 else if (it->f->extra_line_spacing > 0)
2199 it->extra_line_spacing = it->f->extra_line_spacing;
2200 it->max_extra_line_spacing = 0;
2201 }
2202
2203 /* If realized faces have been removed, e.g. because of face
2204 attribute changes of named faces, recompute them. When running
2205 in batch mode, the face cache of Vterminal_frame is null. If
2206 we happen to get called, make a dummy face cache. */
2207 if (noninteractive && FRAME_FACE_CACHE (it->f) == NULL)
2208 init_frame_faces (it->f);
2209 if (FRAME_FACE_CACHE (it->f)->used == 0)
2210 recompute_basic_faces (it->f);
2211
2212 /* Current value of the `slice', `space-width', and 'height' properties. */
2213 it->slice.x = it->slice.y = it->slice.width = it->slice.height = Qnil;
2214 it->space_width = Qnil;
2215 it->font_height = Qnil;
2216 it->override_ascent = -1;
2217
2218 /* Are control characters displayed as `^C'? */
2219 it->ctl_arrow_p = !NILP (current_buffer->ctl_arrow);
2220
2221 /* -1 means everything between a CR and the following line end
2222 is invisible. >0 means lines indented more than this value are
2223 invisible. */
2224 it->selective = (INTEGERP (current_buffer->selective_display)
2225 ? XFASTINT (current_buffer->selective_display)
2226 : (!NILP (current_buffer->selective_display)
2227 ? -1 : 0));
2228 it->selective_display_ellipsis_p
2229 = !NILP (current_buffer->selective_display_ellipses);
2230
2231 /* Display table to use. */
2232 it->dp = window_display_table (w);
2233
2234 /* Are multibyte characters enabled in current_buffer? */
2235 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
2236
2237 /* Non-zero if we should highlight the region. */
2238 highlight_region_p
2239 = (!NILP (Vtransient_mark_mode)
2240 && !NILP (current_buffer->mark_active)
2241 && XMARKER (current_buffer->mark)->buffer != 0);
2242
2243 /* Set IT->region_beg_charpos and IT->region_end_charpos to the
2244 start and end of a visible region in window IT->w. Set both to
2245 -1 to indicate no region. */
2246 if (highlight_region_p
2247 /* Maybe highlight only in selected window. */
2248 && (/* Either show region everywhere. */
2249 highlight_nonselected_windows
2250 /* Or show region in the selected window. */
2251 || w == XWINDOW (selected_window)
2252 /* Or show the region if we are in the mini-buffer and W is
2253 the window the mini-buffer refers to. */
2254 || (MINI_WINDOW_P (XWINDOW (selected_window))
2255 && WINDOWP (minibuf_selected_window)
2256 && w == XWINDOW (minibuf_selected_window))))
2257 {
2258 int charpos = marker_position (current_buffer->mark);
2259 it->region_beg_charpos = min (PT, charpos);
2260 it->region_end_charpos = max (PT, charpos);
2261 }
2262 else
2263 it->region_beg_charpos = it->region_end_charpos = -1;
2264
2265 /* Get the position at which the redisplay_end_trigger hook should
2266 be run, if it is to be run at all. */
2267 if (MARKERP (w->redisplay_end_trigger)
2268 && XMARKER (w->redisplay_end_trigger)->buffer != 0)
2269 it->redisplay_end_trigger_charpos
2270 = marker_position (w->redisplay_end_trigger);
2271 else if (INTEGERP (w->redisplay_end_trigger))
2272 it->redisplay_end_trigger_charpos = XINT (w->redisplay_end_trigger);
2273
2274 /* Correct bogus values of tab_width. */
2275 it->tab_width = XINT (current_buffer->tab_width);
2276 if (it->tab_width <= 0 || it->tab_width > 1000)
2277 it->tab_width = 8;
2278
2279 /* Are lines in the display truncated? */
2280 it->truncate_lines_p
2281 = (base_face_id != DEFAULT_FACE_ID
2282 || XINT (it->w->hscroll)
2283 || (truncate_partial_width_windows
2284 && !WINDOW_FULL_WIDTH_P (it->w))
2285 || !NILP (current_buffer->truncate_lines));
2286
2287 /* Get dimensions of truncation and continuation glyphs. These are
2288 displayed as fringe bitmaps under X, so we don't need them for such
2289 frames. */
2290 if (!FRAME_WINDOW_P (it->f))
2291 {
2292 if (it->truncate_lines_p)
2293 {
2294 /* We will need the truncation glyph. */
2295 xassert (it->glyph_row == NULL);
2296 produce_special_glyphs (it, IT_TRUNCATION);
2297 it->truncation_pixel_width = it->pixel_width;
2298 }
2299 else
2300 {
2301 /* We will need the continuation glyph. */
2302 xassert (it->glyph_row == NULL);
2303 produce_special_glyphs (it, IT_CONTINUATION);
2304 it->continuation_pixel_width = it->pixel_width;
2305 }
2306
2307 /* Reset these values to zero because the produce_special_glyphs
2308 above has changed them. */
2309 it->pixel_width = it->ascent = it->descent = 0;
2310 it->phys_ascent = it->phys_descent = 0;
2311 }
2312
2313 /* Set this after getting the dimensions of truncation and
2314 continuation glyphs, so that we don't produce glyphs when calling
2315 produce_special_glyphs, above. */
2316 it->glyph_row = row;
2317 it->area = TEXT_AREA;
2318
2319 /* Get the dimensions of the display area. The display area
2320 consists of the visible window area plus a horizontally scrolled
2321 part to the left of the window. All x-values are relative to the
2322 start of this total display area. */
2323 if (base_face_id != DEFAULT_FACE_ID)
2324 {
2325 /* Mode lines, menu bar in terminal frames. */
2326 it->first_visible_x = 0;
2327 it->last_visible_x = WINDOW_TOTAL_WIDTH (w);
2328 }
2329 else
2330 {
2331 it->first_visible_x
2332 = XFASTINT (it->w->hscroll) * FRAME_COLUMN_WIDTH (it->f);
2333 it->last_visible_x = (it->first_visible_x
2334 + window_box_width (w, TEXT_AREA));
2335
2336 /* If we truncate lines, leave room for the truncator glyph(s) at
2337 the right margin. Otherwise, leave room for the continuation
2338 glyph(s). Truncation and continuation glyphs are not inserted
2339 for window-based redisplay. */
2340 if (!FRAME_WINDOW_P (it->f))
2341 {
2342 if (it->truncate_lines_p)
2343 it->last_visible_x -= it->truncation_pixel_width;
2344 else
2345 it->last_visible_x -= it->continuation_pixel_width;
2346 }
2347
2348 it->header_line_p = WINDOW_WANTS_HEADER_LINE_P (w);
2349 it->current_y = WINDOW_HEADER_LINE_HEIGHT (w) + w->vscroll;
2350 }
2351
2352 /* Leave room for a border glyph. */
2353 if (!FRAME_WINDOW_P (it->f)
2354 && !WINDOW_RIGHTMOST_P (it->w))
2355 it->last_visible_x -= 1;
2356
2357 it->last_visible_y = window_text_bottom_y (w);
2358
2359 /* For mode lines and alike, arrange for the first glyph having a
2360 left box line if the face specifies a box. */
2361 if (base_face_id != DEFAULT_FACE_ID)
2362 {
2363 struct face *face;
2364
2365 it->face_id = base_face_id;
2366
2367 /* If we have a boxed mode line, make the first character appear
2368 with a left box line. */
2369 face = FACE_FROM_ID (it->f, base_face_id);
2370 if (face->box != FACE_NO_BOX)
2371 it->start_of_box_run_p = 1;
2372 }
2373
2374 /* If a buffer position was specified, set the iterator there,
2375 getting overlays and face properties from that position. */
2376 if (charpos >= BUF_BEG (current_buffer))
2377 {
2378 it->end_charpos = ZV;
2379 it->face_id = -1;
2380 IT_CHARPOS (*it) = charpos;
2381
2382 /* Compute byte position if not specified. */
2383 if (bytepos < charpos)
2384 IT_BYTEPOS (*it) = CHAR_TO_BYTE (charpos);
2385 else
2386 IT_BYTEPOS (*it) = bytepos;
2387
2388 it->start = it->current;
2389
2390 /* Compute faces etc. */
2391 reseat (it, it->current.pos, 1);
2392 }
2393
2394 CHECK_IT (it);
2395 }
2396
2397
2398 /* Initialize IT for the display of window W with window start POS. */
2399
2400 void
2401 start_display (it, w, pos)
2402 struct it *it;
2403 struct window *w;
2404 struct text_pos pos;
2405 {
2406 struct glyph_row *row;
2407 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
2408
2409 row = w->desired_matrix->rows + first_vpos;
2410 init_iterator (it, w, CHARPOS (pos), BYTEPOS (pos), row, DEFAULT_FACE_ID);
2411 it->first_vpos = first_vpos;
2412
2413 if (!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 if (handle_single_display_spec (it, prop, object, position, 0))
3481 display_replaced_p = 1;
3482 }
3483
3484 return display_replaced_p ? HANDLED_RETURN : HANDLED_NORMALLY;
3485 }
3486
3487
3488 /* Value is the position of the end of the `display' property starting
3489 at START_POS in OBJECT. */
3490
3491 static struct text_pos
3492 display_prop_end (it, object, start_pos)
3493 struct it *it;
3494 Lisp_Object object;
3495 struct text_pos start_pos;
3496 {
3497 Lisp_Object end;
3498 struct text_pos end_pos;
3499
3500 end = Fnext_single_char_property_change (make_number (CHARPOS (start_pos)),
3501 Qdisplay, object, Qnil);
3502 CHARPOS (end_pos) = XFASTINT (end);
3503 if (STRINGP (object))
3504 compute_string_pos (&end_pos, start_pos, it->string);
3505 else
3506 BYTEPOS (end_pos) = CHAR_TO_BYTE (XFASTINT (end));
3507
3508 return end_pos;
3509 }
3510
3511
3512 /* Set up IT from a single `display' specification PROP. OBJECT
3513 is the object in which the `display' property was found. *POSITION
3514 is the position at which it was found. DISPLAY_REPLACED_P non-zero
3515 means that we previously saw a display specification which already
3516 replaced text display with something else, for example an image;
3517 we ignore such properties after the first one has been processed.
3518
3519 If PROP is a `space' or `image' specification, and in some other
3520 cases too, set *POSITION to the position where the `display'
3521 property ends.
3522
3523 Value is non-zero if something was found which replaces the display
3524 of buffer or string text. */
3525
3526 static int
3527 handle_single_display_spec (it, spec, object, position,
3528 display_replaced_before_p)
3529 struct it *it;
3530 Lisp_Object spec;
3531 Lisp_Object object;
3532 struct text_pos *position;
3533 int display_replaced_before_p;
3534 {
3535 Lisp_Object form;
3536 Lisp_Object location, value;
3537 struct text_pos start_pos;
3538 int valid_p;
3539
3540 /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
3541 If the result is non-nil, use VALUE instead of SPEC. */
3542 form = Qt;
3543 if (CONSP (spec) && EQ (XCAR (spec), Qwhen))
3544 {
3545 spec = XCDR (spec);
3546 if (!CONSP (spec))
3547 return 0;
3548 form = XCAR (spec);
3549 spec = XCDR (spec);
3550 }
3551
3552 if (!NILP (form) && !EQ (form, Qt))
3553 {
3554 int count = SPECPDL_INDEX ();
3555 struct gcpro gcpro1;
3556
3557 /* Bind `object' to the object having the `display' property, a
3558 buffer or string. Bind `position' to the position in the
3559 object where the property was found, and `buffer-position'
3560 to the current position in the buffer. */
3561 specbind (Qobject, object);
3562 specbind (Qposition, make_number (CHARPOS (*position)));
3563 specbind (Qbuffer_position,
3564 make_number (STRINGP (object)
3565 ? IT_CHARPOS (*it) : CHARPOS (*position)));
3566 GCPRO1 (form);
3567 form = safe_eval (form);
3568 UNGCPRO;
3569 unbind_to (count, Qnil);
3570 }
3571
3572 if (NILP (form))
3573 return 0;
3574
3575 /* Handle `(height HEIGHT)' specifications. */
3576 if (CONSP (spec)
3577 && EQ (XCAR (spec), Qheight)
3578 && CONSP (XCDR (spec)))
3579 {
3580 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3581 return 0;
3582
3583 it->font_height = XCAR (XCDR (spec));
3584 if (!NILP (it->font_height))
3585 {
3586 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3587 int new_height = -1;
3588
3589 if (CONSP (it->font_height)
3590 && (EQ (XCAR (it->font_height), Qplus)
3591 || EQ (XCAR (it->font_height), Qminus))
3592 && CONSP (XCDR (it->font_height))
3593 && INTEGERP (XCAR (XCDR (it->font_height))))
3594 {
3595 /* `(+ N)' or `(- N)' where N is an integer. */
3596 int steps = XINT (XCAR (XCDR (it->font_height)));
3597 if (EQ (XCAR (it->font_height), Qplus))
3598 steps = - steps;
3599 it->face_id = smaller_face (it->f, it->face_id, steps);
3600 }
3601 else if (FUNCTIONP (it->font_height))
3602 {
3603 /* Call function with current height as argument.
3604 Value is the new height. */
3605 Lisp_Object height;
3606 height = safe_call1 (it->font_height,
3607 face->lface[LFACE_HEIGHT_INDEX]);
3608 if (NUMBERP (height))
3609 new_height = XFLOATINT (height);
3610 }
3611 else if (NUMBERP (it->font_height))
3612 {
3613 /* Value is a multiple of the canonical char height. */
3614 struct face *face;
3615
3616 face = FACE_FROM_ID (it->f, DEFAULT_FACE_ID);
3617 new_height = (XFLOATINT (it->font_height)
3618 * XINT (face->lface[LFACE_HEIGHT_INDEX]));
3619 }
3620 else
3621 {
3622 /* Evaluate IT->font_height with `height' bound to the
3623 current specified height to get the new height. */
3624 int count = SPECPDL_INDEX ();
3625
3626 specbind (Qheight, face->lface[LFACE_HEIGHT_INDEX]);
3627 value = safe_eval (it->font_height);
3628 unbind_to (count, Qnil);
3629
3630 if (NUMBERP (value))
3631 new_height = XFLOATINT (value);
3632 }
3633
3634 if (new_height > 0)
3635 it->face_id = face_with_height (it->f, it->face_id, new_height);
3636 }
3637
3638 return 0;
3639 }
3640
3641 /* Handle `(space_width WIDTH)'. */
3642 if (CONSP (spec)
3643 && EQ (XCAR (spec), Qspace_width)
3644 && CONSP (XCDR (spec)))
3645 {
3646 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3647 return 0;
3648
3649 value = XCAR (XCDR (spec));
3650 if (NUMBERP (value) && XFLOATINT (value) > 0)
3651 it->space_width = value;
3652
3653 return 0;
3654 }
3655
3656 /* Handle `(slice X Y WIDTH HEIGHT)'. */
3657 if (CONSP (spec)
3658 && EQ (XCAR (spec), Qslice))
3659 {
3660 Lisp_Object tem;
3661
3662 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3663 return 0;
3664
3665 if (tem = XCDR (spec), CONSP (tem))
3666 {
3667 it->slice.x = XCAR (tem);
3668 if (tem = XCDR (tem), CONSP (tem))
3669 {
3670 it->slice.y = XCAR (tem);
3671 if (tem = XCDR (tem), CONSP (tem))
3672 {
3673 it->slice.width = XCAR (tem);
3674 if (tem = XCDR (tem), CONSP (tem))
3675 it->slice.height = XCAR (tem);
3676 }
3677 }
3678 }
3679
3680 return 0;
3681 }
3682
3683 /* Handle `(raise FACTOR)'. */
3684 if (CONSP (spec)
3685 && EQ (XCAR (spec), Qraise)
3686 && CONSP (XCDR (spec)))
3687 {
3688 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3689 return 0;
3690
3691 #ifdef HAVE_WINDOW_SYSTEM
3692 value = XCAR (XCDR (spec));
3693 if (NUMBERP (value))
3694 {
3695 struct face *face = FACE_FROM_ID (it->f, it->face_id);
3696 it->voffset = - (XFLOATINT (value)
3697 * (FONT_HEIGHT (face->font)));
3698 }
3699 #endif /* HAVE_WINDOW_SYSTEM */
3700
3701 return 0;
3702 }
3703
3704 /* Don't handle the other kinds of display specifications
3705 inside a string that we got from a `display' property. */
3706 if (it->string_from_display_prop_p)
3707 return 0;
3708
3709 /* Characters having this form of property are not displayed, so
3710 we have to find the end of the property. */
3711 start_pos = *position;
3712 *position = display_prop_end (it, object, start_pos);
3713 value = Qnil;
3714
3715 /* Stop the scan at that end position--we assume that all
3716 text properties change there. */
3717 it->stop_charpos = position->charpos;
3718
3719 /* Handle `(left-fringe BITMAP [FACE])'
3720 and `(right-fringe BITMAP [FACE])'. */
3721 if (CONSP (spec)
3722 && (EQ (XCAR (spec), Qleft_fringe)
3723 || EQ (XCAR (spec), Qright_fringe))
3724 && CONSP (XCDR (spec)))
3725 {
3726 int face_id = DEFAULT_FACE_ID;
3727 int fringe_bitmap;
3728
3729 if (FRAME_TERMCAP_P (it->f) || FRAME_MSDOS_P (it->f))
3730 /* If we return here, POSITION has been advanced
3731 across the text with this property. */
3732 return 0;
3733
3734 #ifdef HAVE_WINDOW_SYSTEM
3735 value = XCAR (XCDR (spec));
3736 if (!SYMBOLP (value)
3737 || !(fringe_bitmap = lookup_fringe_bitmap (value)))
3738 /* If we return here, POSITION has been advanced
3739 across the text with this property. */
3740 return 0;
3741
3742 if (CONSP (XCDR (XCDR (spec))))
3743 {
3744 Lisp_Object face_name = XCAR (XCDR (XCDR (spec)));
3745 int face_id2 = lookup_derived_face (it->f, face_name,
3746 'A', FRINGE_FACE_ID, 0);
3747 if (face_id2 >= 0)
3748 face_id = face_id2;
3749 }
3750
3751 /* Save current settings of IT so that we can restore them
3752 when we are finished with the glyph property value. */
3753
3754 push_it (it);
3755
3756 it->area = TEXT_AREA;
3757 it->what = IT_IMAGE;
3758 it->image_id = -1; /* no image */
3759 it->position = start_pos;
3760 it->object = NILP (object) ? it->w->buffer : object;
3761 it->method = GET_FROM_IMAGE;
3762 it->face_id = face_id;
3763
3764 /* Say that we haven't consumed the characters with
3765 `display' property yet. The call to pop_it in
3766 set_iterator_to_next will clean this up. */
3767 *position = start_pos;
3768
3769 if (EQ (XCAR (spec), Qleft_fringe))
3770 {
3771 it->left_user_fringe_bitmap = fringe_bitmap;
3772 it->left_user_fringe_face_id = face_id;
3773 }
3774 else
3775 {
3776 it->right_user_fringe_bitmap = fringe_bitmap;
3777 it->right_user_fringe_face_id = face_id;
3778 }
3779 #endif /* HAVE_WINDOW_SYSTEM */
3780 return 1;
3781 }
3782
3783 /* Prepare to handle `((margin left-margin) ...)',
3784 `((margin right-margin) ...)' and `((margin nil) ...)'
3785 prefixes for display specifications. */
3786 location = Qunbound;
3787 if (CONSP (spec) && CONSP (XCAR (spec)))
3788 {
3789 Lisp_Object tem;
3790
3791 value = XCDR (spec);
3792 if (CONSP (value))
3793 value = XCAR (value);
3794
3795 tem = XCAR (spec);
3796 if (EQ (XCAR (tem), Qmargin)
3797 && (tem = XCDR (tem),
3798 tem = CONSP (tem) ? XCAR (tem) : Qnil,
3799 (NILP (tem)
3800 || EQ (tem, Qleft_margin)
3801 || EQ (tem, Qright_margin))))
3802 location = tem;
3803 }
3804
3805 if (EQ (location, Qunbound))
3806 {
3807 location = Qnil;
3808 value = spec;
3809 }
3810
3811 /* After this point, VALUE is the property after any
3812 margin prefix has been stripped. It must be a string,
3813 an image specification, or `(space ...)'.
3814
3815 LOCATION specifies where to display: `left-margin',
3816 `right-margin' or nil. */
3817
3818 valid_p = (STRINGP (value)
3819 #ifdef HAVE_WINDOW_SYSTEM
3820 || (!FRAME_TERMCAP_P (it->f) && valid_image_p (value))
3821 #endif /* not HAVE_WINDOW_SYSTEM */
3822 || (CONSP (value) && EQ (XCAR (value), Qspace)));
3823
3824 if (valid_p && !display_replaced_before_p)
3825 {
3826 /* Save current settings of IT so that we can restore them
3827 when we are finished with the glyph property value. */
3828 push_it (it);
3829
3830 if (NILP (location))
3831 it->area = TEXT_AREA;
3832 else if (EQ (location, Qleft_margin))
3833 it->area = LEFT_MARGIN_AREA;
3834 else
3835 it->area = RIGHT_MARGIN_AREA;
3836
3837 if (STRINGP (value))
3838 {
3839 it->string = value;
3840 it->multibyte_p = STRING_MULTIBYTE (it->string);
3841 it->current.overlay_string_index = -1;
3842 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
3843 it->end_charpos = it->string_nchars = SCHARS (it->string);
3844 it->method = GET_FROM_STRING;
3845 it->stop_charpos = 0;
3846 it->string_from_display_prop_p = 1;
3847 /* Say that we haven't consumed the characters with
3848 `display' property yet. The call to pop_it in
3849 set_iterator_to_next will clean this up. */
3850 *position = start_pos;
3851 }
3852 else if (CONSP (value) && EQ (XCAR (value), Qspace))
3853 {
3854 it->method = GET_FROM_STRETCH;
3855 it->object = value;
3856 it->current.pos = it->position = start_pos;
3857 }
3858 #ifdef HAVE_WINDOW_SYSTEM
3859 else
3860 {
3861 it->what = IT_IMAGE;
3862 it->image_id = lookup_image (it->f, value);
3863 it->position = start_pos;
3864 it->object = NILP (object) ? it->w->buffer : object;
3865 it->method = GET_FROM_IMAGE;
3866
3867 /* Say that we haven't consumed the characters with
3868 `display' property yet. The call to pop_it in
3869 set_iterator_to_next will clean this up. */
3870 *position = start_pos;
3871 }
3872 #endif /* HAVE_WINDOW_SYSTEM */
3873
3874 return 1;
3875 }
3876
3877 /* Invalid property or property not supported. Restore
3878 POSITION to what it was before. */
3879 *position = start_pos;
3880 return 0;
3881 }
3882
3883
3884 /* Check if SPEC is a display specification value whose text should be
3885 treated as intangible. */
3886
3887 static int
3888 single_display_spec_intangible_p (prop)
3889 Lisp_Object prop;
3890 {
3891 /* Skip over `when FORM'. */
3892 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3893 {
3894 prop = XCDR (prop);
3895 if (!CONSP (prop))
3896 return 0;
3897 prop = XCDR (prop);
3898 }
3899
3900 if (STRINGP (prop))
3901 return 1;
3902
3903 if (!CONSP (prop))
3904 return 0;
3905
3906 /* Skip over `margin LOCATION'. If LOCATION is in the margins,
3907 we don't need to treat text as intangible. */
3908 if (EQ (XCAR (prop), Qmargin))
3909 {
3910 prop = XCDR (prop);
3911 if (!CONSP (prop))
3912 return 0;
3913
3914 prop = XCDR (prop);
3915 if (!CONSP (prop)
3916 || EQ (XCAR (prop), Qleft_margin)
3917 || EQ (XCAR (prop), Qright_margin))
3918 return 0;
3919 }
3920
3921 return (CONSP (prop)
3922 && (EQ (XCAR (prop), Qimage)
3923 || EQ (XCAR (prop), Qspace)));
3924 }
3925
3926
3927 /* Check if PROP is a display property value whose text should be
3928 treated as intangible. */
3929
3930 int
3931 display_prop_intangible_p (prop)
3932 Lisp_Object prop;
3933 {
3934 if (CONSP (prop)
3935 && CONSP (XCAR (prop))
3936 && !EQ (Qmargin, XCAR (XCAR (prop))))
3937 {
3938 /* A list of sub-properties. */
3939 while (CONSP (prop))
3940 {
3941 if (single_display_spec_intangible_p (XCAR (prop)))
3942 return 1;
3943 prop = XCDR (prop);
3944 }
3945 }
3946 else if (VECTORP (prop))
3947 {
3948 /* A vector of sub-properties. */
3949 int i;
3950 for (i = 0; i < ASIZE (prop); ++i)
3951 if (single_display_spec_intangible_p (AREF (prop, i)))
3952 return 1;
3953 }
3954 else
3955 return single_display_spec_intangible_p (prop);
3956
3957 return 0;
3958 }
3959
3960
3961 /* Return 1 if PROP is a display sub-property value containing STRING. */
3962
3963 static int
3964 single_display_spec_string_p (prop, string)
3965 Lisp_Object prop, string;
3966 {
3967 if (EQ (string, prop))
3968 return 1;
3969
3970 /* Skip over `when FORM'. */
3971 if (CONSP (prop) && EQ (XCAR (prop), Qwhen))
3972 {
3973 prop = XCDR (prop);
3974 if (!CONSP (prop))
3975 return 0;
3976 prop = XCDR (prop);
3977 }
3978
3979 if (CONSP (prop))
3980 /* Skip over `margin LOCATION'. */
3981 if (EQ (XCAR (prop), Qmargin))
3982 {
3983 prop = XCDR (prop);
3984 if (!CONSP (prop))
3985 return 0;
3986
3987 prop = XCDR (prop);
3988 if (!CONSP (prop))
3989 return 0;
3990 }
3991
3992 return CONSP (prop) && EQ (XCAR (prop), string);
3993 }
3994
3995
3996 /* Return 1 if STRING appears in the `display' property PROP. */
3997
3998 static int
3999 display_prop_string_p (prop, string)
4000 Lisp_Object prop, string;
4001 {
4002 if (CONSP (prop)
4003 && CONSP (XCAR (prop))
4004 && !EQ (Qmargin, XCAR (XCAR (prop))))
4005 {
4006 /* A list of sub-properties. */
4007 while (CONSP (prop))
4008 {
4009 if (single_display_spec_string_p (XCAR (prop), string))
4010 return 1;
4011 prop = XCDR (prop);
4012 }
4013 }
4014 else if (VECTORP (prop))
4015 {
4016 /* A vector of sub-properties. */
4017 int i;
4018 for (i = 0; i < ASIZE (prop); ++i)
4019 if (single_display_spec_string_p (AREF (prop, i), string))
4020 return 1;
4021 }
4022 else
4023 return single_display_spec_string_p (prop, string);
4024
4025 return 0;
4026 }
4027
4028
4029 /* Determine from which buffer position in W's buffer STRING comes
4030 from. AROUND_CHARPOS is an approximate position where it could
4031 be from. Value is the buffer position or 0 if it couldn't be
4032 determined.
4033
4034 W's buffer must be current.
4035
4036 This function is necessary because we don't record buffer positions
4037 in glyphs generated from strings (to keep struct glyph small).
4038 This function may only use code that doesn't eval because it is
4039 called asynchronously from note_mouse_highlight. */
4040
4041 int
4042 string_buffer_position (w, string, around_charpos)
4043 struct window *w;
4044 Lisp_Object string;
4045 int around_charpos;
4046 {
4047 Lisp_Object limit, prop, pos;
4048 const int MAX_DISTANCE = 1000;
4049 int found = 0;
4050
4051 pos = make_number (around_charpos);
4052 limit = make_number (min (XINT (pos) + MAX_DISTANCE, ZV));
4053 while (!found && !EQ (pos, limit))
4054 {
4055 prop = Fget_char_property (pos, Qdisplay, Qnil);
4056 if (!NILP (prop) && display_prop_string_p (prop, string))
4057 found = 1;
4058 else
4059 pos = Fnext_single_char_property_change (pos, Qdisplay, Qnil, limit);
4060 }
4061
4062 if (!found)
4063 {
4064 pos = make_number (around_charpos);
4065 limit = make_number (max (XINT (pos) - MAX_DISTANCE, BEGV));
4066 while (!found && !EQ (pos, limit))
4067 {
4068 prop = Fget_char_property (pos, Qdisplay, Qnil);
4069 if (!NILP (prop) && display_prop_string_p (prop, string))
4070 found = 1;
4071 else
4072 pos = Fprevious_single_char_property_change (pos, Qdisplay, Qnil,
4073 limit);
4074 }
4075 }
4076
4077 return found ? XINT (pos) : 0;
4078 }
4079
4080
4081 \f
4082 /***********************************************************************
4083 `composition' property
4084 ***********************************************************************/
4085
4086 /* Set up iterator IT from `composition' property at its current
4087 position. Called from handle_stop. */
4088
4089 static enum prop_handled
4090 handle_composition_prop (it)
4091 struct it *it;
4092 {
4093 Lisp_Object prop, string;
4094 int pos, pos_byte, end;
4095 enum prop_handled handled = HANDLED_NORMALLY;
4096
4097 if (STRINGP (it->string))
4098 {
4099 pos = IT_STRING_CHARPOS (*it);
4100 pos_byte = IT_STRING_BYTEPOS (*it);
4101 string = it->string;
4102 }
4103 else
4104 {
4105 pos = IT_CHARPOS (*it);
4106 pos_byte = IT_BYTEPOS (*it);
4107 string = Qnil;
4108 }
4109
4110 /* If there's a valid composition and point is not inside of the
4111 composition (in the case that the composition is from the current
4112 buffer), draw a glyph composed from the composition components. */
4113 if (find_composition (pos, -1, &pos, &end, &prop, string)
4114 && COMPOSITION_VALID_P (pos, end, prop)
4115 && (STRINGP (it->string) || (PT <= pos || PT >= end)))
4116 {
4117 int id = get_composition_id (pos, pos_byte, end - pos, prop, string);
4118
4119 if (id >= 0)
4120 {
4121 it->method = GET_FROM_COMPOSITION;
4122 it->cmp_id = id;
4123 it->cmp_len = COMPOSITION_LENGTH (prop);
4124 /* For a terminal, draw only the first character of the
4125 components. */
4126 it->c = COMPOSITION_GLYPH (composition_table[id], 0);
4127 it->len = (STRINGP (it->string)
4128 ? string_char_to_byte (it->string, end)
4129 : CHAR_TO_BYTE (end)) - pos_byte;
4130 it->stop_charpos = end;
4131 handled = HANDLED_RETURN;
4132 }
4133 }
4134
4135 return handled;
4136 }
4137
4138
4139 \f
4140 /***********************************************************************
4141 Overlay strings
4142 ***********************************************************************/
4143
4144 /* The following structure is used to record overlay strings for
4145 later sorting in load_overlay_strings. */
4146
4147 struct overlay_entry
4148 {
4149 Lisp_Object overlay;
4150 Lisp_Object string;
4151 int priority;
4152 int after_string_p;
4153 };
4154
4155
4156 /* Set up iterator IT from overlay strings at its current position.
4157 Called from handle_stop. */
4158
4159 static enum prop_handled
4160 handle_overlay_change (it)
4161 struct it *it;
4162 {
4163 if (!STRINGP (it->string) && get_overlay_strings (it, 0))
4164 return HANDLED_RECOMPUTE_PROPS;
4165 else
4166 return HANDLED_NORMALLY;
4167 }
4168
4169
4170 /* Set up the next overlay string for delivery by IT, if there is an
4171 overlay string to deliver. Called by set_iterator_to_next when the
4172 end of the current overlay string is reached. If there are more
4173 overlay strings to display, IT->string and
4174 IT->current.overlay_string_index are set appropriately here.
4175 Otherwise IT->string is set to nil. */
4176
4177 static void
4178 next_overlay_string (it)
4179 struct it *it;
4180 {
4181 ++it->current.overlay_string_index;
4182 if (it->current.overlay_string_index == it->n_overlay_strings)
4183 {
4184 /* No more overlay strings. Restore IT's settings to what
4185 they were before overlay strings were processed, and
4186 continue to deliver from current_buffer. */
4187 int display_ellipsis_p = it->stack[it->sp - 1].display_ellipsis_p;
4188
4189 pop_it (it);
4190 xassert (it->stop_charpos >= BEGV
4191 && it->stop_charpos <= it->end_charpos);
4192 it->string = Qnil;
4193 it->current.overlay_string_index = -1;
4194 SET_TEXT_POS (it->current.string_pos, -1, -1);
4195 it->n_overlay_strings = 0;
4196 it->method = GET_FROM_BUFFER;
4197
4198 /* If we're at the end of the buffer, record that we have
4199 processed the overlay strings there already, so that
4200 next_element_from_buffer doesn't try it again. */
4201 if (IT_CHARPOS (*it) >= it->end_charpos)
4202 it->overlay_strings_at_end_processed_p = 1;
4203
4204 /* If we have to display `...' for invisible text, set
4205 the iterator up for that. */
4206 if (display_ellipsis_p)
4207 setup_for_ellipsis (it, 0);
4208 }
4209 else
4210 {
4211 /* There are more overlay strings to process. If
4212 IT->current.overlay_string_index has advanced to a position
4213 where we must load IT->overlay_strings with more strings, do
4214 it. */
4215 int i = it->current.overlay_string_index % OVERLAY_STRING_CHUNK_SIZE;
4216
4217 if (it->current.overlay_string_index && i == 0)
4218 load_overlay_strings (it, 0);
4219
4220 /* Initialize IT to deliver display elements from the overlay
4221 string. */
4222 it->string = it->overlay_strings[i];
4223 it->multibyte_p = STRING_MULTIBYTE (it->string);
4224 SET_TEXT_POS (it->current.string_pos, 0, 0);
4225 it->method = GET_FROM_STRING;
4226 it->stop_charpos = 0;
4227 }
4228
4229 CHECK_IT (it);
4230 }
4231
4232
4233 /* Compare two overlay_entry structures E1 and E2. Used as a
4234 comparison function for qsort in load_overlay_strings. Overlay
4235 strings for the same position are sorted so that
4236
4237 1. All after-strings come in front of before-strings, except
4238 when they come from the same overlay.
4239
4240 2. Within after-strings, strings are sorted so that overlay strings
4241 from overlays with higher priorities come first.
4242
4243 2. Within before-strings, strings are sorted so that overlay
4244 strings from overlays with higher priorities come last.
4245
4246 Value is analogous to strcmp. */
4247
4248
4249 static int
4250 compare_overlay_entries (e1, e2)
4251 void *e1, *e2;
4252 {
4253 struct overlay_entry *entry1 = (struct overlay_entry *) e1;
4254 struct overlay_entry *entry2 = (struct overlay_entry *) e2;
4255 int result;
4256
4257 if (entry1->after_string_p != entry2->after_string_p)
4258 {
4259 /* Let after-strings appear in front of before-strings if
4260 they come from different overlays. */
4261 if (EQ (entry1->overlay, entry2->overlay))
4262 result = entry1->after_string_p ? 1 : -1;
4263 else
4264 result = entry1->after_string_p ? -1 : 1;
4265 }
4266 else if (entry1->after_string_p)
4267 /* After-strings sorted in order of decreasing priority. */
4268 result = entry2->priority - entry1->priority;
4269 else
4270 /* Before-strings sorted in order of increasing priority. */
4271 result = entry1->priority - entry2->priority;
4272
4273 return result;
4274 }
4275
4276
4277 /* Load the vector IT->overlay_strings with overlay strings from IT's
4278 current buffer position, or from CHARPOS if that is > 0. Set
4279 IT->n_overlays to the total number of overlay strings found.
4280
4281 Overlay strings are processed OVERLAY_STRING_CHUNK_SIZE strings at
4282 a time. On entry into load_overlay_strings,
4283 IT->current.overlay_string_index gives the number of overlay
4284 strings that have already been loaded by previous calls to this
4285 function.
4286
4287 IT->add_overlay_start contains an additional overlay start
4288 position to consider for taking overlay strings from, if non-zero.
4289 This position comes into play when the overlay has an `invisible'
4290 property, and both before and after-strings. When we've skipped to
4291 the end of the overlay, because of its `invisible' property, we
4292 nevertheless want its before-string to appear.
4293 IT->add_overlay_start will contain the overlay start position
4294 in this case.
4295
4296 Overlay strings are sorted so that after-string strings come in
4297 front of before-string strings. Within before and after-strings,
4298 strings are sorted by overlay priority. See also function
4299 compare_overlay_entries. */
4300
4301 static void
4302 load_overlay_strings (it, charpos)
4303 struct it *it;
4304 int charpos;
4305 {
4306 extern Lisp_Object Qafter_string, Qbefore_string, Qwindow, Qpriority;
4307 Lisp_Object overlay, window, str, invisible;
4308 struct Lisp_Overlay *ov;
4309 int start, end;
4310 int size = 20;
4311 int n = 0, i, j, invis_p;
4312 struct overlay_entry *entries
4313 = (struct overlay_entry *) alloca (size * sizeof *entries);
4314
4315 if (charpos <= 0)
4316 charpos = IT_CHARPOS (*it);
4317
4318 /* Append the overlay string STRING of overlay OVERLAY to vector
4319 `entries' which has size `size' and currently contains `n'
4320 elements. AFTER_P non-zero means STRING is an after-string of
4321 OVERLAY. */
4322 #define RECORD_OVERLAY_STRING(OVERLAY, STRING, AFTER_P) \
4323 do \
4324 { \
4325 Lisp_Object priority; \
4326 \
4327 if (n == size) \
4328 { \
4329 int new_size = 2 * size; \
4330 struct overlay_entry *old = entries; \
4331 entries = \
4332 (struct overlay_entry *) alloca (new_size \
4333 * sizeof *entries); \
4334 bcopy (old, entries, size * sizeof *entries); \
4335 size = new_size; \
4336 } \
4337 \
4338 entries[n].string = (STRING); \
4339 entries[n].overlay = (OVERLAY); \
4340 priority = Foverlay_get ((OVERLAY), Qpriority); \
4341 entries[n].priority = INTEGERP (priority) ? XINT (priority) : 0; \
4342 entries[n].after_string_p = (AFTER_P); \
4343 ++n; \
4344 } \
4345 while (0)
4346
4347 /* Process overlay before the overlay center. */
4348 for (ov = current_buffer->overlays_before; ov; ov = ov->next)
4349 {
4350 XSETMISC (overlay, ov);
4351 xassert (OVERLAYP (overlay));
4352 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4353 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4354
4355 if (end < charpos)
4356 break;
4357
4358 /* Skip this overlay if it doesn't start or end at IT's current
4359 position. */
4360 if (end != charpos && start != charpos)
4361 continue;
4362
4363 /* Skip this overlay if it doesn't apply to IT->w. */
4364 window = Foverlay_get (overlay, Qwindow);
4365 if (WINDOWP (window) && XWINDOW (window) != it->w)
4366 continue;
4367
4368 /* If the text ``under'' the overlay is invisible, both before-
4369 and after-strings from this overlay are visible; start and
4370 end position are indistinguishable. */
4371 invisible = Foverlay_get (overlay, Qinvisible);
4372 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4373
4374 /* If overlay has a non-empty before-string, record it. */
4375 if ((start == charpos || (end == charpos && invis_p))
4376 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4377 && SCHARS (str))
4378 RECORD_OVERLAY_STRING (overlay, str, 0);
4379
4380 /* If overlay has a non-empty after-string, record it. */
4381 if ((end == charpos || (start == charpos && invis_p))
4382 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4383 && SCHARS (str))
4384 RECORD_OVERLAY_STRING (overlay, str, 1);
4385 }
4386
4387 /* Process overlays after the overlay center. */
4388 for (ov = current_buffer->overlays_after; ov; ov = ov->next)
4389 {
4390 XSETMISC (overlay, ov);
4391 xassert (OVERLAYP (overlay));
4392 start = OVERLAY_POSITION (OVERLAY_START (overlay));
4393 end = OVERLAY_POSITION (OVERLAY_END (overlay));
4394
4395 if (start > charpos)
4396 break;
4397
4398 /* Skip this overlay if it doesn't start or end at IT's current
4399 position. */
4400 if (end != charpos && start != charpos)
4401 continue;
4402
4403 /* Skip this overlay if it doesn't apply to IT->w. */
4404 window = Foverlay_get (overlay, Qwindow);
4405 if (WINDOWP (window) && XWINDOW (window) != it->w)
4406 continue;
4407
4408 /* If the text ``under'' the overlay is invisible, it has a zero
4409 dimension, and both before- and after-strings apply. */
4410 invisible = Foverlay_get (overlay, Qinvisible);
4411 invis_p = TEXT_PROP_MEANS_INVISIBLE (invisible);
4412
4413 /* If overlay has a non-empty before-string, record it. */
4414 if ((start == charpos || (end == charpos && invis_p))
4415 && (str = Foverlay_get (overlay, Qbefore_string), STRINGP (str))
4416 && SCHARS (str))
4417 RECORD_OVERLAY_STRING (overlay, str, 0);
4418
4419 /* If overlay has a non-empty after-string, record it. */
4420 if ((end == charpos || (start == charpos && invis_p))
4421 && (str = Foverlay_get (overlay, Qafter_string), STRINGP (str))
4422 && SCHARS (str))
4423 RECORD_OVERLAY_STRING (overlay, str, 1);
4424 }
4425
4426 #undef RECORD_OVERLAY_STRING
4427
4428 /* Sort entries. */
4429 if (n > 1)
4430 qsort (entries, n, sizeof *entries, compare_overlay_entries);
4431
4432 /* Record the total number of strings to process. */
4433 it->n_overlay_strings = n;
4434
4435 /* IT->current.overlay_string_index is the number of overlay strings
4436 that have already been consumed by IT. Copy some of the
4437 remaining overlay strings to IT->overlay_strings. */
4438 i = 0;
4439 j = it->current.overlay_string_index;
4440 while (i < OVERLAY_STRING_CHUNK_SIZE && j < n)
4441 it->overlay_strings[i++] = entries[j++].string;
4442
4443 CHECK_IT (it);
4444 }
4445
4446
4447 /* Get the first chunk of overlay strings at IT's current buffer
4448 position, or at CHARPOS if that is > 0. Value is non-zero if at
4449 least one overlay string was found. */
4450
4451 static int
4452 get_overlay_strings (it, charpos)
4453 struct it *it;
4454 int charpos;
4455 {
4456 /* Get the first OVERLAY_STRING_CHUNK_SIZE overlay strings to
4457 process. This fills IT->overlay_strings with strings, and sets
4458 IT->n_overlay_strings to the total number of strings to process.
4459 IT->pos.overlay_string_index has to be set temporarily to zero
4460 because load_overlay_strings needs this; it must be set to -1
4461 when no overlay strings are found because a zero value would
4462 indicate a position in the first overlay string. */
4463 it->current.overlay_string_index = 0;
4464 load_overlay_strings (it, charpos);
4465
4466 /* If we found overlay strings, set up IT to deliver display
4467 elements from the first one. Otherwise set up IT to deliver
4468 from current_buffer. */
4469 if (it->n_overlay_strings)
4470 {
4471 /* Make sure we know settings in current_buffer, so that we can
4472 restore meaningful values when we're done with the overlay
4473 strings. */
4474 compute_stop_pos (it);
4475 xassert (it->face_id >= 0);
4476
4477 /* Save IT's settings. They are restored after all overlay
4478 strings have been processed. */
4479 xassert (it->sp == 0);
4480 push_it (it);
4481
4482 /* Set up IT to deliver display elements from the first overlay
4483 string. */
4484 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = 0;
4485 it->string = it->overlay_strings[0];
4486 it->stop_charpos = 0;
4487 xassert (STRINGP (it->string));
4488 it->end_charpos = SCHARS (it->string);
4489 it->multibyte_p = STRING_MULTIBYTE (it->string);
4490 it->method = GET_FROM_STRING;
4491 }
4492 else
4493 {
4494 it->string = Qnil;
4495 it->current.overlay_string_index = -1;
4496 it->method = GET_FROM_BUFFER;
4497 }
4498
4499 CHECK_IT (it);
4500
4501 /* Value is non-zero if we found at least one overlay string. */
4502 return STRINGP (it->string);
4503 }
4504
4505
4506 \f
4507 /***********************************************************************
4508 Saving and restoring state
4509 ***********************************************************************/
4510
4511 /* Save current settings of IT on IT->stack. Called, for example,
4512 before setting up IT for an overlay string, to be able to restore
4513 IT's settings to what they were after the overlay string has been
4514 processed. */
4515
4516 static void
4517 push_it (it)
4518 struct it *it;
4519 {
4520 struct iterator_stack_entry *p;
4521
4522 xassert (it->sp < 2);
4523 p = it->stack + it->sp;
4524
4525 p->stop_charpos = it->stop_charpos;
4526 xassert (it->face_id >= 0);
4527 p->face_id = it->face_id;
4528 p->string = it->string;
4529 p->pos = it->current;
4530 p->end_charpos = it->end_charpos;
4531 p->string_nchars = it->string_nchars;
4532 p->area = it->area;
4533 p->multibyte_p = it->multibyte_p;
4534 p->slice = it->slice;
4535 p->space_width = it->space_width;
4536 p->font_height = it->font_height;
4537 p->voffset = it->voffset;
4538 p->string_from_display_prop_p = it->string_from_display_prop_p;
4539 p->display_ellipsis_p = 0;
4540 ++it->sp;
4541 }
4542
4543
4544 /* Restore IT's settings from IT->stack. Called, for example, when no
4545 more overlay strings must be processed, and we return to delivering
4546 display elements from a buffer, or when the end of a string from a
4547 `display' property is reached and we return to delivering display
4548 elements from an overlay string, or from a buffer. */
4549
4550 static void
4551 pop_it (it)
4552 struct it *it;
4553 {
4554 struct iterator_stack_entry *p;
4555
4556 xassert (it->sp > 0);
4557 --it->sp;
4558 p = it->stack + it->sp;
4559 it->stop_charpos = p->stop_charpos;
4560 it->face_id = p->face_id;
4561 it->string = p->string;
4562 it->current = p->pos;
4563 it->end_charpos = p->end_charpos;
4564 it->string_nchars = p->string_nchars;
4565 it->area = p->area;
4566 it->multibyte_p = p->multibyte_p;
4567 it->slice = p->slice;
4568 it->space_width = p->space_width;
4569 it->font_height = p->font_height;
4570 it->voffset = p->voffset;
4571 it->string_from_display_prop_p = p->string_from_display_prop_p;
4572 }
4573
4574
4575 \f
4576 /***********************************************************************
4577 Moving over lines
4578 ***********************************************************************/
4579
4580 /* Set IT's current position to the previous line start. */
4581
4582 static void
4583 back_to_previous_line_start (it)
4584 struct it *it;
4585 {
4586 IT_CHARPOS (*it) = find_next_newline_no_quit (IT_CHARPOS (*it) - 1, -1);
4587 IT_BYTEPOS (*it) = CHAR_TO_BYTE (IT_CHARPOS (*it));
4588 }
4589
4590
4591 /* Move IT to the next line start.
4592
4593 Value is non-zero if a newline was found. Set *SKIPPED_P to 1 if
4594 we skipped over part of the text (as opposed to moving the iterator
4595 continuously over the text). Otherwise, don't change the value
4596 of *SKIPPED_P.
4597
4598 Newlines may come from buffer text, overlay strings, or strings
4599 displayed via the `display' property. That's the reason we can't
4600 simply use find_next_newline_no_quit.
4601
4602 Note that this function may not skip over invisible text that is so
4603 because of text properties and immediately follows a newline. If
4604 it would, function reseat_at_next_visible_line_start, when called
4605 from set_iterator_to_next, would effectively make invisible
4606 characters following a newline part of the wrong glyph row, which
4607 leads to wrong cursor motion. */
4608
4609 static int
4610 forward_to_next_line_start (it, skipped_p)
4611 struct it *it;
4612 int *skipped_p;
4613 {
4614 int old_selective, newline_found_p, n;
4615 const int MAX_NEWLINE_DISTANCE = 500;
4616
4617 /* If already on a newline, just consume it to avoid unintended
4618 skipping over invisible text below. */
4619 if (it->what == IT_CHARACTER
4620 && it->c == '\n'
4621 && CHARPOS (it->position) == IT_CHARPOS (*it))
4622 {
4623 set_iterator_to_next (it, 0);
4624 it->c = 0;
4625 return 1;
4626 }
4627
4628 /* Don't handle selective display in the following. It's (a)
4629 unnecessary because it's done by the caller, and (b) leads to an
4630 infinite recursion because next_element_from_ellipsis indirectly
4631 calls this function. */
4632 old_selective = it->selective;
4633 it->selective = 0;
4634
4635 /* Scan for a newline within MAX_NEWLINE_DISTANCE display elements
4636 from buffer text. */
4637 for (n = newline_found_p = 0;
4638 !newline_found_p && n < MAX_NEWLINE_DISTANCE;
4639 n += STRINGP (it->string) ? 0 : 1)
4640 {
4641 if (!get_next_display_element (it))
4642 return 0;
4643 newline_found_p = it->what == IT_CHARACTER && it->c == '\n';
4644 set_iterator_to_next (it, 0);
4645 }
4646
4647 /* If we didn't find a newline near enough, see if we can use a
4648 short-cut. */
4649 if (!newline_found_p)
4650 {
4651 int start = IT_CHARPOS (*it);
4652 int limit = find_next_newline_no_quit (start, 1);
4653 Lisp_Object pos;
4654
4655 xassert (!STRINGP (it->string));
4656
4657 /* If there isn't any `display' property in sight, and no
4658 overlays, we can just use the position of the newline in
4659 buffer text. */
4660 if (it->stop_charpos >= limit
4661 || ((pos = Fnext_single_property_change (make_number (start),
4662 Qdisplay,
4663 Qnil, make_number (limit)),
4664 NILP (pos))
4665 && next_overlay_change (start) == ZV))
4666 {
4667 IT_CHARPOS (*it) = limit;
4668 IT_BYTEPOS (*it) = CHAR_TO_BYTE (limit);
4669 *skipped_p = newline_found_p = 1;
4670 }
4671 else
4672 {
4673 while (get_next_display_element (it)
4674 && !newline_found_p)
4675 {
4676 newline_found_p = ITERATOR_AT_END_OF_LINE_P (it);
4677 set_iterator_to_next (it, 0);
4678 }
4679 }
4680 }
4681
4682 it->selective = old_selective;
4683 return newline_found_p;
4684 }
4685
4686
4687 /* Set IT's current position to the previous visible line start. Skip
4688 invisible text that is so either due to text properties or due to
4689 selective display. Caution: this does not change IT->current_x and
4690 IT->hpos. */
4691
4692 static void
4693 back_to_previous_visible_line_start (it)
4694 struct it *it;
4695 {
4696 while (IT_CHARPOS (*it) > BEGV)
4697 {
4698 back_to_previous_line_start (it);
4699 if (IT_CHARPOS (*it) <= BEGV)
4700 break;
4701
4702 /* If selective > 0, then lines indented more than that values
4703 are invisible. */
4704 if (it->selective > 0
4705 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4706 (double) it->selective)) /* iftc */
4707 continue;
4708
4709 /* Check the newline before point for invisibility. */
4710 {
4711 Lisp_Object prop;
4712 prop = Fget_char_property (make_number (IT_CHARPOS (*it) - 1),
4713 Qinvisible, it->window);
4714 if (TEXT_PROP_MEANS_INVISIBLE (prop))
4715 continue;
4716 }
4717
4718 /* If newline has a display property that replaces the newline with something
4719 else (image or text), find start of overlay or interval and continue search
4720 from that point. */
4721 if (IT_CHARPOS (*it) > BEGV)
4722 {
4723 struct it it2 = *it;
4724 int pos;
4725 int beg, end;
4726 Lisp_Object val, overlay;
4727
4728 pos = --IT_CHARPOS (it2);
4729 --IT_BYTEPOS (it2);
4730 it2.sp = 0;
4731 if (handle_display_prop (&it2) == HANDLED_RETURN
4732 && !NILP (val = get_char_property_and_overlay
4733 (make_number (pos), Qdisplay, Qnil, &overlay))
4734 && (OVERLAYP (overlay)
4735 ? (beg = OVERLAY_POSITION (OVERLAY_START (overlay)))
4736 : get_property_and_range (pos, Qdisplay, &val, &beg, &end, Qnil)))
4737 {
4738 if (beg < BEGV)
4739 beg = BEGV;
4740 IT_CHARPOS (*it) = beg;
4741 IT_BYTEPOS (*it) = buf_charpos_to_bytepos (current_buffer, beg);
4742 continue;
4743 }
4744 }
4745
4746 break;
4747 }
4748
4749 xassert (IT_CHARPOS (*it) >= BEGV);
4750 xassert (IT_CHARPOS (*it) == BEGV
4751 || FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4752 CHECK_IT (it);
4753 }
4754
4755
4756 /* Reseat iterator IT at the previous visible line start. Skip
4757 invisible text that is so either due to text properties or due to
4758 selective display. At the end, update IT's overlay information,
4759 face information etc. */
4760
4761 void
4762 reseat_at_previous_visible_line_start (it)
4763 struct it *it;
4764 {
4765 back_to_previous_visible_line_start (it);
4766 reseat (it, it->current.pos, 1);
4767 CHECK_IT (it);
4768 }
4769
4770
4771 /* Reseat iterator IT on the next visible line start in the current
4772 buffer. ON_NEWLINE_P non-zero means position IT on the newline
4773 preceding the line start. Skip over invisible text that is so
4774 because of selective display. Compute faces, overlays etc at the
4775 new position. Note that this function does not skip over text that
4776 is invisible because of text properties. */
4777
4778 static void
4779 reseat_at_next_visible_line_start (it, on_newline_p)
4780 struct it *it;
4781 int on_newline_p;
4782 {
4783 int newline_found_p, skipped_p = 0;
4784
4785 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4786
4787 /* Skip over lines that are invisible because they are indented
4788 more than the value of IT->selective. */
4789 if (it->selective > 0)
4790 while (IT_CHARPOS (*it) < ZV
4791 && indented_beyond_p (IT_CHARPOS (*it), IT_BYTEPOS (*it),
4792 (double) it->selective)) /* iftc */
4793 {
4794 xassert (FETCH_BYTE (IT_BYTEPOS (*it) - 1) == '\n');
4795 newline_found_p = forward_to_next_line_start (it, &skipped_p);
4796 }
4797
4798 /* Position on the newline if that's what's requested. */
4799 if (on_newline_p && newline_found_p)
4800 {
4801 if (STRINGP (it->string))
4802 {
4803 if (IT_STRING_CHARPOS (*it) > 0)
4804 {
4805 --IT_STRING_CHARPOS (*it);
4806 --IT_STRING_BYTEPOS (*it);
4807 }
4808 }
4809 else if (IT_CHARPOS (*it) > BEGV)
4810 {
4811 --IT_CHARPOS (*it);
4812 --IT_BYTEPOS (*it);
4813 reseat (it, it->current.pos, 0);
4814 }
4815 }
4816 else if (skipped_p)
4817 reseat (it, it->current.pos, 0);
4818
4819 CHECK_IT (it);
4820 }
4821
4822
4823 \f
4824 /***********************************************************************
4825 Changing an iterator's position
4826 ***********************************************************************/
4827
4828 /* Change IT's current position to POS in current_buffer. If FORCE_P
4829 is non-zero, always check for text properties at the new position.
4830 Otherwise, text properties are only looked up if POS >=
4831 IT->check_charpos of a property. */
4832
4833 static void
4834 reseat (it, pos, force_p)
4835 struct it *it;
4836 struct text_pos pos;
4837 int force_p;
4838 {
4839 int original_pos = IT_CHARPOS (*it);
4840
4841 reseat_1 (it, pos, 0);
4842
4843 /* Determine where to check text properties. Avoid doing it
4844 where possible because text property lookup is very expensive. */
4845 if (force_p
4846 || CHARPOS (pos) > it->stop_charpos
4847 || CHARPOS (pos) < original_pos)
4848 handle_stop (it);
4849
4850 CHECK_IT (it);
4851 }
4852
4853
4854 /* Change IT's buffer position to POS. SET_STOP_P non-zero means set
4855 IT->stop_pos to POS, also. */
4856
4857 static void
4858 reseat_1 (it, pos, set_stop_p)
4859 struct it *it;
4860 struct text_pos pos;
4861 int set_stop_p;
4862 {
4863 /* Don't call this function when scanning a C string. */
4864 xassert (it->s == NULL);
4865
4866 /* POS must be a reasonable value. */
4867 xassert (CHARPOS (pos) >= BEGV && CHARPOS (pos) <= ZV);
4868
4869 it->current.pos = it->position = pos;
4870 XSETBUFFER (it->object, current_buffer);
4871 it->end_charpos = ZV;
4872 it->dpvec = NULL;
4873 it->current.dpvec_index = -1;
4874 it->current.overlay_string_index = -1;
4875 IT_STRING_CHARPOS (*it) = -1;
4876 IT_STRING_BYTEPOS (*it) = -1;
4877 it->string = Qnil;
4878 it->method = GET_FROM_BUFFER;
4879 /* RMS: I added this to fix a bug in move_it_vertically_backward
4880 where it->area continued to relate to the starting point
4881 for the backward motion. Bug report from
4882 Nick Roberts <nick@nick.uklinux.net> on 19 May 2003.
4883 However, I am not sure whether reseat still does the right thing
4884 in general after this change. */
4885 it->area = TEXT_AREA;
4886 it->multibyte_p = !NILP (current_buffer->enable_multibyte_characters);
4887 it->sp = 0;
4888 it->face_before_selective_p = 0;
4889
4890 if (set_stop_p)
4891 it->stop_charpos = CHARPOS (pos);
4892 }
4893
4894
4895 /* Set up IT for displaying a string, starting at CHARPOS in window W.
4896 If S is non-null, it is a C string to iterate over. Otherwise,
4897 STRING gives a Lisp string to iterate over.
4898
4899 If PRECISION > 0, don't return more then PRECISION number of
4900 characters from the string.
4901
4902 If FIELD_WIDTH > 0, return padding spaces until FIELD_WIDTH
4903 characters have been returned. FIELD_WIDTH < 0 means an infinite
4904 field width.
4905
4906 MULTIBYTE = 0 means disable processing of multibyte characters,
4907 MULTIBYTE > 0 means enable it,
4908 MULTIBYTE < 0 means use IT->multibyte_p.
4909
4910 IT must be initialized via a prior call to init_iterator before
4911 calling this function. */
4912
4913 static void
4914 reseat_to_string (it, s, string, charpos, precision, field_width, multibyte)
4915 struct it *it;
4916 unsigned char *s;
4917 Lisp_Object string;
4918 int charpos;
4919 int precision, field_width, multibyte;
4920 {
4921 /* No region in strings. */
4922 it->region_beg_charpos = it->region_end_charpos = -1;
4923
4924 /* No text property checks performed by default, but see below. */
4925 it->stop_charpos = -1;
4926
4927 /* Set iterator position and end position. */
4928 bzero (&it->current, sizeof it->current);
4929 it->current.overlay_string_index = -1;
4930 it->current.dpvec_index = -1;
4931 xassert (charpos >= 0);
4932
4933 /* If STRING is specified, use its multibyteness, otherwise use the
4934 setting of MULTIBYTE, if specified. */
4935 if (multibyte >= 0)
4936 it->multibyte_p = multibyte > 0;
4937
4938 if (s == NULL)
4939 {
4940 xassert (STRINGP (string));
4941 it->string = string;
4942 it->s = NULL;
4943 it->end_charpos = it->string_nchars = SCHARS (string);
4944 it->method = GET_FROM_STRING;
4945 it->current.string_pos = string_pos (charpos, string);
4946 }
4947 else
4948 {
4949 it->s = s;
4950 it->string = Qnil;
4951
4952 /* Note that we use IT->current.pos, not it->current.string_pos,
4953 for displaying C strings. */
4954 IT_STRING_CHARPOS (*it) = IT_STRING_BYTEPOS (*it) = -1;
4955 if (it->multibyte_p)
4956 {
4957 it->current.pos = c_string_pos (charpos, s, 1);
4958 it->end_charpos = it->string_nchars = number_of_chars (s, 1);
4959 }
4960 else
4961 {
4962 IT_CHARPOS (*it) = IT_BYTEPOS (*it) = charpos;
4963 it->end_charpos = it->string_nchars = strlen (s);
4964 }
4965
4966 it->method = GET_FROM_C_STRING;
4967 }
4968
4969 /* PRECISION > 0 means don't return more than PRECISION characters
4970 from the string. */
4971 if (precision > 0 && it->end_charpos - charpos > precision)
4972 it->end_charpos = it->string_nchars = charpos + precision;
4973
4974 /* FIELD_WIDTH > 0 means pad with spaces until FIELD_WIDTH
4975 characters have been returned. FIELD_WIDTH == 0 means don't pad,
4976 FIELD_WIDTH < 0 means infinite field width. This is useful for
4977 padding with `-' at the end of a mode line. */
4978 if (field_width < 0)
4979 field_width = INFINITY;
4980 if (field_width > it->end_charpos - charpos)
4981 it->end_charpos = charpos + field_width;
4982
4983 /* Use the standard display table for displaying strings. */
4984 if (DISP_TABLE_P (Vstandard_display_table))
4985 it->dp = XCHAR_TABLE (Vstandard_display_table);
4986
4987 it->stop_charpos = charpos;
4988 CHECK_IT (it);
4989 }
4990
4991
4992 \f
4993 /***********************************************************************
4994 Iteration
4995 ***********************************************************************/
4996
4997 /* Map enum it_method value to corresponding next_element_from_* function. */
4998
4999 static int (* get_next_element[NUM_IT_METHODS]) P_ ((struct it *it)) =
5000 {
5001 next_element_from_buffer,
5002 next_element_from_display_vector,
5003 next_element_from_composition,
5004 next_element_from_string,
5005 next_element_from_c_string,
5006 next_element_from_image,
5007 next_element_from_stretch
5008 };
5009
5010
5011 /* Load IT's display element fields with information about the next
5012 display element from the current position of IT. Value is zero if
5013 end of buffer (or C string) is reached. */
5014
5015 int
5016 get_next_display_element (it)
5017 struct it *it;
5018 {
5019 /* Non-zero means that we found a display element. Zero means that
5020 we hit the end of what we iterate over. Performance note: the
5021 function pointer `method' used here turns out to be faster than
5022 using a sequence of if-statements. */
5023 int success_p;
5024
5025 get_next:
5026 success_p = (*get_next_element[it->method]) (it);
5027
5028 if (it->what == IT_CHARACTER)
5029 {
5030 /* Map via display table or translate control characters.
5031 IT->c, IT->len etc. have been set to the next character by
5032 the function call above. If we have a display table, and it
5033 contains an entry for IT->c, translate it. Don't do this if
5034 IT->c itself comes from a display table, otherwise we could
5035 end up in an infinite recursion. (An alternative could be to
5036 count the recursion depth of this function and signal an
5037 error when a certain maximum depth is reached.) Is it worth
5038 it? */
5039 if (success_p && it->dpvec == NULL)
5040 {
5041 Lisp_Object dv;
5042
5043 if (it->dp
5044 && (dv = DISP_CHAR_VECTOR (it->dp, it->c),
5045 VECTORP (dv)))
5046 {
5047 struct Lisp_Vector *v = XVECTOR (dv);
5048
5049 /* Return the first character from the display table
5050 entry, if not empty. If empty, don't display the
5051 current character. */
5052 if (v->size)
5053 {
5054 it->dpvec_char_len = it->len;
5055 it->dpvec = v->contents;
5056 it->dpend = v->contents + v->size;
5057 it->current.dpvec_index = 0;
5058 it->dpvec_face_id = -1;
5059 it->saved_face_id = it->face_id;
5060 it->method = GET_FROM_DISPLAY_VECTOR;
5061 it->ellipsis_p = 0;
5062 }
5063 else
5064 {
5065 set_iterator_to_next (it, 0);
5066 }
5067 goto get_next;
5068 }
5069
5070 /* Translate control characters into `\003' or `^C' form.
5071 Control characters coming from a display table entry are
5072 currently not translated because we use IT->dpvec to hold
5073 the translation. This could easily be changed but I
5074 don't believe that it is worth doing.
5075
5076 If it->multibyte_p is nonzero, eight-bit characters and
5077 non-printable multibyte characters are also translated to
5078 octal form.
5079
5080 If it->multibyte_p is zero, eight-bit characters that
5081 don't have corresponding multibyte char code are also
5082 translated to octal form. */
5083 else if ((it->c < ' '
5084 && (it->area != TEXT_AREA
5085 /* In mode line, treat \n like other crl chars. */
5086 || (it->c != '\t'
5087 && it->glyph_row && it->glyph_row->mode_line_p)
5088 || (it->c != '\n' && it->c != '\t')))
5089 || (it->multibyte_p
5090 ? ((it->c >= 127
5091 && it->len == 1)
5092 || !CHAR_PRINTABLE_P (it->c)
5093 || (!NILP (Vshow_nonbreak_escape)
5094 && (it->c == 0x8ad || it->c == 0x8a0
5095 || it->c == 0xf2d || it->c == 0xf20)))
5096 : (it->c >= 127
5097 && (!unibyte_display_via_language_environment
5098 || it->c == unibyte_char_to_multibyte (it->c)))))
5099 {
5100 /* IT->c is a control character which must be displayed
5101 either as '\003' or as `^C' where the '\\' and '^'
5102 can be defined in the display table. Fill
5103 IT->ctl_chars with glyphs for what we have to
5104 display. Then, set IT->dpvec to these glyphs. */
5105 GLYPH g;
5106 int ctl_len;
5107 int face_id, lface_id = 0 ;
5108 GLYPH escape_glyph;
5109
5110 if (it->c < 128 && it->ctl_arrow_p)
5111 {
5112 g = '^'; /* default glyph for Control */
5113 /* Set IT->ctl_chars[0] to the glyph for `^'. */
5114 if (it->dp
5115 && INTEGERP (DISP_CTRL_GLYPH (it->dp))
5116 && GLYPH_CHAR_VALID_P (XINT (DISP_CTRL_GLYPH (it->dp))))
5117 {
5118 g = XINT (DISP_CTRL_GLYPH (it->dp));
5119 lface_id = FAST_GLYPH_FACE (g);
5120 }
5121 if (lface_id)
5122 {
5123 g = FAST_GLYPH_CHAR (g);
5124 face_id = merge_faces (it->f, Qt, lface_id,
5125 it->face_id);
5126 }
5127 else
5128 {
5129 /* Merge the escape-glyph face into the current face. */
5130 face_id = merge_faces (it->f, Qescape_glyph, 0,
5131 it->face_id);
5132 }
5133
5134 XSETINT (it->ctl_chars[0], g);
5135 g = it->c ^ 0100;
5136 XSETINT (it->ctl_chars[1], g);
5137 ctl_len = 2;
5138 goto display_control;
5139 }
5140
5141 escape_glyph = '\\'; /* default for Octal display */
5142 if (it->dp
5143 && INTEGERP (DISP_ESCAPE_GLYPH (it->dp))
5144 && GLYPH_CHAR_VALID_P (XFASTINT (DISP_ESCAPE_GLYPH (it->dp))))
5145 {
5146 escape_glyph = XFASTINT (DISP_ESCAPE_GLYPH (it->dp));
5147 lface_id = FAST_GLYPH_FACE (escape_glyph);
5148 }
5149 if (lface_id)
5150 {
5151 escape_glyph = FAST_GLYPH_CHAR (escape_glyph);
5152 face_id = merge_faces (it->f, Qt, lface_id,
5153 it->face_id);
5154 }
5155 else
5156 {
5157 /* Merge the escape-glyph face into the current face. */
5158 face_id = merge_faces (it->f, Qescape_glyph, 0,
5159 it->face_id);
5160 }
5161
5162 if (it->c == 0x8a0 || it->c == 0x8ad
5163 || it->c == 0xf20 || it->c == 0xf2d)
5164 {
5165 XSETINT (it->ctl_chars[0], escape_glyph);
5166 g = it->c;
5167 XSETINT (it->ctl_chars[1], g);
5168 ctl_len = 2;
5169 goto display_control;
5170 }
5171
5172 {
5173 unsigned char str[MAX_MULTIBYTE_LENGTH];
5174 int len;
5175 int i;
5176
5177 /* Set IT->ctl_chars[0] to the glyph for `\\'. */
5178 if (SINGLE_BYTE_CHAR_P (it->c))
5179 str[0] = it->c, len = 1;
5180 else
5181 {
5182 len = CHAR_STRING_NO_SIGNAL (it->c, str);
5183 if (len < 0)
5184 {
5185 /* It's an invalid character, which shouldn't
5186 happen actually, but due to bugs it may
5187 happen. Let's print the char as is, there's
5188 not much meaningful we can do with it. */
5189 str[0] = it->c;
5190 str[1] = it->c >> 8;
5191 str[2] = it->c >> 16;
5192 str[3] = it->c >> 24;
5193 len = 4;
5194 }
5195 }
5196
5197 for (i = 0; i < len; i++)
5198 {
5199 XSETINT (it->ctl_chars[i * 4], escape_glyph);
5200 /* Insert three more glyphs into IT->ctl_chars for
5201 the octal display of the character. */
5202 g = ((str[i] >> 6) & 7) + '0';
5203 XSETINT (it->ctl_chars[i * 4 + 1], g);
5204 g = ((str[i] >> 3) & 7) + '0';
5205 XSETINT (it->ctl_chars[i * 4 + 2], g);
5206 g = (str[i] & 7) + '0';
5207 XSETINT (it->ctl_chars[i * 4 + 3], g);
5208 }
5209 ctl_len = len * 4;
5210 }
5211
5212 display_control:
5213 /* Set up IT->dpvec and return first character from it. */
5214 it->dpvec_char_len = it->len;
5215 it->dpvec = it->ctl_chars;
5216 it->dpend = it->dpvec + ctl_len;
5217 it->current.dpvec_index = 0;
5218 it->dpvec_face_id = face_id;
5219 it->saved_face_id = it->face_id;
5220 it->method = GET_FROM_DISPLAY_VECTOR;
5221 it->ellipsis_p = 0;
5222 goto get_next;
5223 }
5224 }
5225
5226 /* Adjust face id for a multibyte character. There are no
5227 multibyte character in unibyte text. */
5228 if (it->multibyte_p
5229 && success_p
5230 && FRAME_WINDOW_P (it->f))
5231 {
5232 struct face *face = FACE_FROM_ID (it->f, it->face_id);
5233 it->face_id = FACE_FOR_CHAR (it->f, face, it->c);
5234 }
5235 }
5236
5237 /* Is this character the last one of a run of characters with
5238 box? If yes, set IT->end_of_box_run_p to 1. */
5239 if (it->face_box_p
5240 && it->s == NULL)
5241 {
5242 int face_id;
5243 struct face *face;
5244
5245 it->end_of_box_run_p
5246 = ((face_id = face_after_it_pos (it),
5247 face_id != it->face_id)
5248 && (face = FACE_FROM_ID (it->f, face_id),
5249 face->box == FACE_NO_BOX));
5250 }
5251
5252 /* Value is 0 if end of buffer or string reached. */
5253 return success_p;
5254 }
5255
5256
5257 /* Move IT to the next display element.
5258
5259 RESEAT_P non-zero means if called on a newline in buffer text,
5260 skip to the next visible line start.
5261
5262 Functions get_next_display_element and set_iterator_to_next are
5263 separate because I find this arrangement easier to handle than a
5264 get_next_display_element function that also increments IT's
5265 position. The way it is we can first look at an iterator's current
5266 display element, decide whether it fits on a line, and if it does,
5267 increment the iterator position. The other way around we probably
5268 would either need a flag indicating whether the iterator has to be
5269 incremented the next time, or we would have to implement a
5270 decrement position function which would not be easy to write. */
5271
5272 void
5273 set_iterator_to_next (it, reseat_p)
5274 struct it *it;
5275 int reseat_p;
5276 {
5277 /* Reset flags indicating start and end of a sequence of characters
5278 with box. Reset them at the start of this function because
5279 moving the iterator to a new position might set them. */
5280 it->start_of_box_run_p = it->end_of_box_run_p = 0;
5281
5282 switch (it->method)
5283 {
5284 case GET_FROM_BUFFER:
5285 /* The current display element of IT is a character from
5286 current_buffer. Advance in the buffer, and maybe skip over
5287 invisible lines that are so because of selective display. */
5288 if (ITERATOR_AT_END_OF_LINE_P (it) && reseat_p)
5289 reseat_at_next_visible_line_start (it, 0);
5290 else
5291 {
5292 xassert (it->len != 0);
5293 IT_BYTEPOS (*it) += it->len;
5294 IT_CHARPOS (*it) += 1;
5295 xassert (IT_BYTEPOS (*it) == CHAR_TO_BYTE (IT_CHARPOS (*it)));
5296 }
5297 break;
5298
5299 case GET_FROM_COMPOSITION:
5300 xassert (it->cmp_id >= 0 && it->cmp_id < n_compositions);
5301 if (STRINGP (it->string))
5302 {
5303 IT_STRING_BYTEPOS (*it) += it->len;
5304 IT_STRING_CHARPOS (*it) += it->cmp_len;
5305 it->method = GET_FROM_STRING;
5306 goto consider_string_end;
5307 }
5308 else
5309 {
5310 IT_BYTEPOS (*it) += it->len;
5311 IT_CHARPOS (*it) += it->cmp_len;
5312 it->method = GET_FROM_BUFFER;
5313 }
5314 break;
5315
5316 case GET_FROM_C_STRING:
5317 /* Current display element of IT is from a C string. */
5318 IT_BYTEPOS (*it) += it->len;
5319 IT_CHARPOS (*it) += 1;
5320 break;
5321
5322 case GET_FROM_DISPLAY_VECTOR:
5323 /* Current display element of IT is from a display table entry.
5324 Advance in the display table definition. Reset it to null if
5325 end reached, and continue with characters from buffers/
5326 strings. */
5327 ++it->current.dpvec_index;
5328
5329 /* Restore face of the iterator to what they were before the
5330 display vector entry (these entries may contain faces). */
5331 it->face_id = it->saved_face_id;
5332
5333 if (it->dpvec + it->current.dpvec_index == it->dpend)
5334 {
5335 if (it->s)
5336 it->method = GET_FROM_C_STRING;
5337 else if (STRINGP (it->string))
5338 it->method = GET_FROM_STRING;
5339 else
5340 it->method = GET_FROM_BUFFER;
5341
5342 it->dpvec = NULL;
5343 it->current.dpvec_index = -1;
5344
5345 /* Skip over characters which were displayed via IT->dpvec. */
5346 if (it->dpvec_char_len < 0)
5347 reseat_at_next_visible_line_start (it, 1);
5348 else if (it->dpvec_char_len > 0)
5349 {
5350 it->len = it->dpvec_char_len;
5351 set_iterator_to_next (it, reseat_p);
5352 }
5353
5354 /* Recheck faces after display vector */
5355 it->stop_charpos = IT_CHARPOS (*it);
5356 }
5357 break;
5358
5359 case GET_FROM_STRING:
5360 /* Current display element is a character from a Lisp string. */
5361 xassert (it->s == NULL && STRINGP (it->string));
5362 IT_STRING_BYTEPOS (*it) += it->len;
5363 IT_STRING_CHARPOS (*it) += 1;
5364
5365 consider_string_end:
5366
5367 if (it->current.overlay_string_index >= 0)
5368 {
5369 /* IT->string is an overlay string. Advance to the
5370 next, if there is one. */
5371 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5372 next_overlay_string (it);
5373 }
5374 else
5375 {
5376 /* IT->string is not an overlay string. If we reached
5377 its end, and there is something on IT->stack, proceed
5378 with what is on the stack. This can be either another
5379 string, this time an overlay string, or a buffer. */
5380 if (IT_STRING_CHARPOS (*it) == SCHARS (it->string)
5381 && it->sp > 0)
5382 {
5383 pop_it (it);
5384 if (STRINGP (it->string))
5385 goto consider_string_end;
5386 it->method = GET_FROM_BUFFER;
5387 }
5388 }
5389 break;
5390
5391 case GET_FROM_IMAGE:
5392 case GET_FROM_STRETCH:
5393 /* The position etc with which we have to proceed are on
5394 the stack. The position may be at the end of a string,
5395 if the `display' property takes up the whole string. */
5396 xassert (it->sp > 0);
5397 pop_it (it);
5398 it->image_id = 0;
5399 if (STRINGP (it->string))
5400 {
5401 it->method = GET_FROM_STRING;
5402 goto consider_string_end;
5403 }
5404 it->method = GET_FROM_BUFFER;
5405 break;
5406
5407 default:
5408 /* There are no other methods defined, so this should be a bug. */
5409 abort ();
5410 }
5411
5412 xassert (it->method != GET_FROM_STRING
5413 || (STRINGP (it->string)
5414 && IT_STRING_CHARPOS (*it) >= 0));
5415 }
5416
5417 /* Load IT's display element fields with information about the next
5418 display element which comes from a display table entry or from the
5419 result of translating a control character to one of the forms `^C'
5420 or `\003'.
5421
5422 IT->dpvec holds the glyphs to return as characters.
5423 IT->saved_face_id holds the face id before the display vector--
5424 it is restored into IT->face_idin set_iterator_to_next. */
5425
5426 static int
5427 next_element_from_display_vector (it)
5428 struct it *it;
5429 {
5430 /* Precondition. */
5431 xassert (it->dpvec && it->current.dpvec_index >= 0);
5432
5433 it->face_id = it->saved_face_id;
5434
5435 if (INTEGERP (*it->dpvec)
5436 && GLYPH_CHAR_VALID_P (XFASTINT (*it->dpvec)))
5437 {
5438 GLYPH g;
5439
5440 g = XFASTINT (it->dpvec[it->current.dpvec_index]);
5441 it->c = FAST_GLYPH_CHAR (g);
5442 it->len = CHAR_BYTES (it->c);
5443
5444 /* The entry may contain a face id to use. Such a face id is
5445 the id of a Lisp face, not a realized face. A face id of
5446 zero means no face is specified. */
5447 if (it->dpvec_face_id >= 0)
5448 it->face_id = it->dpvec_face_id;
5449 else
5450 {
5451 int lface_id = FAST_GLYPH_FACE (g);
5452 if (lface_id > 0)
5453 it->face_id = merge_faces (it->f, Qt, lface_id,
5454 it->saved_face_id);
5455 }
5456 }
5457 else
5458 /* Display table entry is invalid. Return a space. */
5459 it->c = ' ', it->len = 1;
5460
5461 /* Don't change position and object of the iterator here. They are
5462 still the values of the character that had this display table
5463 entry or was translated, and that's what we want. */
5464 it->what = IT_CHARACTER;
5465 return 1;
5466 }
5467
5468
5469 /* Load IT with the next display element from Lisp string IT->string.
5470 IT->current.string_pos is the current position within the string.
5471 If IT->current.overlay_string_index >= 0, the Lisp string is an
5472 overlay string. */
5473
5474 static int
5475 next_element_from_string (it)
5476 struct it *it;
5477 {
5478 struct text_pos position;
5479
5480 xassert (STRINGP (it->string));
5481 xassert (IT_STRING_CHARPOS (*it) >= 0);
5482 position = it->current.string_pos;
5483
5484 /* Time to check for invisible text? */
5485 if (IT_STRING_CHARPOS (*it) < it->end_charpos
5486 && IT_STRING_CHARPOS (*it) == it->stop_charpos)
5487 {
5488 handle_stop (it);
5489
5490 /* Since a handler may have changed IT->method, we must
5491 recurse here. */
5492 return get_next_display_element (it);
5493 }
5494
5495 if (it->current.overlay_string_index >= 0)
5496 {
5497 /* Get the next character from an overlay string. In overlay
5498 strings, There is no field width or padding with spaces to
5499 do. */
5500 if (IT_STRING_CHARPOS (*it) >= SCHARS (it->string))
5501 {
5502 it->what = IT_EOB;
5503 return 0;
5504 }
5505 else if (STRING_MULTIBYTE (it->string))
5506 {
5507 int remaining = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5508 const unsigned char *s = (SDATA (it->string)
5509 + IT_STRING_BYTEPOS (*it));
5510 it->c = string_char_and_length (s, remaining, &it->len);
5511 }
5512 else
5513 {
5514 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5515 it->len = 1;
5516 }
5517 }
5518 else
5519 {
5520 /* Get the next character from a Lisp string that is not an
5521 overlay string. Such strings come from the mode line, for
5522 example. We may have to pad with spaces, or truncate the
5523 string. See also next_element_from_c_string. */
5524 if (IT_STRING_CHARPOS (*it) >= it->end_charpos)
5525 {
5526 it->what = IT_EOB;
5527 return 0;
5528 }
5529 else if (IT_STRING_CHARPOS (*it) >= it->string_nchars)
5530 {
5531 /* Pad with spaces. */
5532 it->c = ' ', it->len = 1;
5533 CHARPOS (position) = BYTEPOS (position) = -1;
5534 }
5535 else if (STRING_MULTIBYTE (it->string))
5536 {
5537 int maxlen = SBYTES (it->string) - IT_STRING_BYTEPOS (*it);
5538 const unsigned char *s = (SDATA (it->string)
5539 + IT_STRING_BYTEPOS (*it));
5540 it->c = string_char_and_length (s, maxlen, &it->len);
5541 }
5542 else
5543 {
5544 it->c = SREF (it->string, IT_STRING_BYTEPOS (*it));
5545 it->len = 1;
5546 }
5547 }
5548
5549 /* Record what we have and where it came from. Note that we store a
5550 buffer position in IT->position although it could arguably be a
5551 string position. */
5552 it->what = IT_CHARACTER;
5553 it->object = it->string;
5554 it->position = position;
5555 return 1;
5556 }
5557
5558
5559 /* Load IT with next display element from C string IT->s.
5560 IT->string_nchars is the maximum number of characters to return
5561 from the string. IT->end_charpos may be greater than
5562 IT->string_nchars when this function is called, in which case we
5563 may have to return padding spaces. Value is zero if end of string
5564 reached, including padding spaces. */
5565
5566 static int
5567 next_element_from_c_string (it)
5568 struct it *it;
5569 {
5570 int success_p = 1;
5571
5572 xassert (it->s);
5573 it->what = IT_CHARACTER;
5574 BYTEPOS (it->position) = CHARPOS (it->position) = 0;
5575 it->object = Qnil;
5576
5577 /* IT's position can be greater IT->string_nchars in case a field
5578 width or precision has been specified when the iterator was
5579 initialized. */
5580 if (IT_CHARPOS (*it) >= it->end_charpos)
5581 {
5582 /* End of the game. */
5583 it->what = IT_EOB;
5584 success_p = 0;
5585 }
5586 else if (IT_CHARPOS (*it) >= it->string_nchars)
5587 {
5588 /* Pad with spaces. */
5589 it->c = ' ', it->len = 1;
5590 BYTEPOS (it->position) = CHARPOS (it->position) = -1;
5591 }
5592 else if (it->multibyte_p)
5593 {
5594 /* Implementation note: The calls to strlen apparently aren't a
5595 performance problem because there is no noticeable performance
5596 difference between Emacs running in unibyte or multibyte mode. */
5597 int maxlen = strlen (it->s) - IT_BYTEPOS (*it);
5598 it->c = string_char_and_length (it->s + IT_BYTEPOS (*it),
5599 maxlen, &it->len);
5600 }
5601 else
5602 it->c = it->s[IT_BYTEPOS (*it)], it->len = 1;
5603
5604 return success_p;
5605 }
5606
5607
5608 /* Set up IT to return characters from an ellipsis, if appropriate.
5609 The definition of the ellipsis glyphs may come from a display table
5610 entry. This function Fills IT with the first glyph from the
5611 ellipsis if an ellipsis is to be displayed. */
5612
5613 static int
5614 next_element_from_ellipsis (it)
5615 struct it *it;
5616 {
5617 if (it->selective_display_ellipsis_p)
5618 setup_for_ellipsis (it, it->len);
5619 else
5620 {
5621 /* The face at the current position may be different from the
5622 face we find after the invisible text. Remember what it
5623 was in IT->saved_face_id, and signal that it's there by
5624 setting face_before_selective_p. */
5625 it->saved_face_id = it->face_id;
5626 it->method = GET_FROM_BUFFER;
5627 reseat_at_next_visible_line_start (it, 1);
5628 it->face_before_selective_p = 1;
5629 }
5630
5631 return get_next_display_element (it);
5632 }
5633
5634
5635 /* Deliver an image display element. The iterator IT is already
5636 filled with image information (done in handle_display_prop). Value
5637 is always 1. */
5638
5639
5640 static int
5641 next_element_from_image (it)
5642 struct it *it;
5643 {
5644 it->what = IT_IMAGE;
5645 return 1;
5646 }
5647
5648
5649 /* Fill iterator IT with next display element from a stretch glyph
5650 property. IT->object is the value of the text property. Value is
5651 always 1. */
5652
5653 static int
5654 next_element_from_stretch (it)
5655 struct it *it;
5656 {
5657 it->what = IT_STRETCH;
5658 return 1;
5659 }
5660
5661
5662 /* Load IT with the next display element from current_buffer. Value
5663 is zero if end of buffer reached. IT->stop_charpos is the next
5664 position at which to stop and check for text properties or buffer
5665 end. */
5666
5667 static int
5668 next_element_from_buffer (it)
5669 struct it *it;
5670 {
5671 int success_p = 1;
5672
5673 /* Check this assumption, otherwise, we would never enter the
5674 if-statement, below. */
5675 xassert (IT_CHARPOS (*it) >= BEGV
5676 && IT_CHARPOS (*it) <= it->stop_charpos);
5677
5678 if (IT_CHARPOS (*it) >= it->stop_charpos)
5679 {
5680 if (IT_CHARPOS (*it) >= it->end_charpos)
5681 {
5682 int overlay_strings_follow_p;
5683
5684 /* End of the game, except when overlay strings follow that
5685 haven't been returned yet. */
5686 if (it->overlay_strings_at_end_processed_p)
5687 overlay_strings_follow_p = 0;
5688 else
5689 {
5690 it->overlay_strings_at_end_processed_p = 1;
5691 overlay_strings_follow_p = get_overlay_strings (it, 0);
5692 }
5693
5694 if (overlay_strings_follow_p)
5695 success_p = get_next_display_element (it);
5696 else
5697 {
5698 it->what = IT_EOB;
5699 it->position = it->current.pos;
5700 success_p = 0;
5701 }
5702 }
5703 else
5704 {
5705 handle_stop (it);
5706 return get_next_display_element (it);
5707 }
5708 }
5709 else
5710 {
5711 /* No face changes, overlays etc. in sight, so just return a
5712 character from current_buffer. */
5713 unsigned char *p;
5714
5715 /* Maybe run the redisplay end trigger hook. Performance note:
5716 This doesn't seem to cost measurable time. */
5717 if (it->redisplay_end_trigger_charpos
5718 && it->glyph_row
5719 && IT_CHARPOS (*it) >= it->redisplay_end_trigger_charpos)
5720 run_redisplay_end_trigger_hook (it);
5721
5722 /* Get the next character, maybe multibyte. */
5723 p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
5724 if (it->multibyte_p && !ASCII_BYTE_P (*p))
5725 {
5726 int maxlen = ((IT_BYTEPOS (*it) >= GPT_BYTE ? ZV_BYTE : GPT_BYTE)
5727 - IT_BYTEPOS (*it));
5728 it->c = string_char_and_length (p, maxlen, &it->len);
5729 }
5730 else
5731 it->c = *p, it->len = 1;
5732
5733 /* Record what we have and where it came from. */
5734 it->what = IT_CHARACTER;;
5735 it->object = it->w->buffer;
5736 it->position = it->current.pos;
5737
5738 /* Normally we return the character found above, except when we
5739 really want to return an ellipsis for selective display. */
5740 if (it->selective)
5741 {
5742 if (it->c == '\n')
5743 {
5744 /* A value of selective > 0 means hide lines indented more
5745 than that number of columns. */
5746 if (it->selective > 0
5747 && IT_CHARPOS (*it) + 1 < ZV
5748 && indented_beyond_p (IT_CHARPOS (*it) + 1,
5749 IT_BYTEPOS (*it) + 1,
5750 (double) it->selective)) /* iftc */
5751 {
5752 success_p = next_element_from_ellipsis (it);
5753 it->dpvec_char_len = -1;
5754 }
5755 }
5756 else if (it->c == '\r' && it->selective == -1)
5757 {
5758 /* A value of selective == -1 means that everything from the
5759 CR to the end of the line is invisible, with maybe an
5760 ellipsis displayed for it. */
5761 success_p = next_element_from_ellipsis (it);
5762 it->dpvec_char_len = -1;
5763 }
5764 }
5765 }
5766
5767 /* Value is zero if end of buffer reached. */
5768 xassert (!success_p || it->what != IT_CHARACTER || it->len > 0);
5769 return success_p;
5770 }
5771
5772
5773 /* Run the redisplay end trigger hook for IT. */
5774
5775 static void
5776 run_redisplay_end_trigger_hook (it)
5777 struct it *it;
5778 {
5779 Lisp_Object args[3];
5780
5781 /* IT->glyph_row should be non-null, i.e. we should be actually
5782 displaying something, or otherwise we should not run the hook. */
5783 xassert (it->glyph_row);
5784
5785 /* Set up hook arguments. */
5786 args[0] = Qredisplay_end_trigger_functions;
5787 args[1] = it->window;
5788 XSETINT (args[2], it->redisplay_end_trigger_charpos);
5789 it->redisplay_end_trigger_charpos = 0;
5790
5791 /* Since we are *trying* to run these functions, don't try to run
5792 them again, even if they get an error. */
5793 it->w->redisplay_end_trigger = Qnil;
5794 Frun_hook_with_args (3, args);
5795
5796 /* Notice if it changed the face of the character we are on. */
5797 handle_face_prop (it);
5798 }
5799
5800
5801 /* Deliver a composition display element. The iterator IT is already
5802 filled with composition information (done in
5803 handle_composition_prop). Value is always 1. */
5804
5805 static int
5806 next_element_from_composition (it)
5807 struct it *it;
5808 {
5809 it->what = IT_COMPOSITION;
5810 it->position = (STRINGP (it->string)
5811 ? it->current.string_pos
5812 : it->current.pos);
5813 return 1;
5814 }
5815
5816
5817 \f
5818 /***********************************************************************
5819 Moving an iterator without producing glyphs
5820 ***********************************************************************/
5821
5822 /* Move iterator IT to a specified buffer or X position within one
5823 line on the display without producing glyphs.
5824
5825 OP should be a bit mask including some or all of these bits:
5826 MOVE_TO_X: Stop on reaching x-position TO_X.
5827 MOVE_TO_POS: Stop on reaching buffer or string position TO_CHARPOS.
5828 Regardless of OP's value, stop in reaching the end of the display line.
5829
5830 TO_X is normally a value 0 <= TO_X <= IT->last_visible_x.
5831 This means, in particular, that TO_X includes window's horizontal
5832 scroll amount.
5833
5834 The return value has several possible values that
5835 say what condition caused the scan to stop:
5836
5837 MOVE_POS_MATCH_OR_ZV
5838 - when TO_POS or ZV was reached.
5839
5840 MOVE_X_REACHED
5841 -when TO_X was reached before TO_POS or ZV were reached.
5842
5843 MOVE_LINE_CONTINUED
5844 - when we reached the end of the display area and the line must
5845 be continued.
5846
5847 MOVE_LINE_TRUNCATED
5848 - when we reached the end of the display area and the line is
5849 truncated.
5850
5851 MOVE_NEWLINE_OR_CR
5852 - when we stopped at a line end, i.e. a newline or a CR and selective
5853 display is on. */
5854
5855 static enum move_it_result
5856 move_it_in_display_line_to (it, to_charpos, to_x, op)
5857 struct it *it;
5858 int to_charpos, to_x, op;
5859 {
5860 enum move_it_result result = MOVE_UNDEFINED;
5861 struct glyph_row *saved_glyph_row;
5862
5863 /* Don't produce glyphs in produce_glyphs. */
5864 saved_glyph_row = it->glyph_row;
5865 it->glyph_row = NULL;
5866
5867 #define BUFFER_POS_REACHED_P() \
5868 ((op & MOVE_TO_POS) != 0 \
5869 && BUFFERP (it->object) \
5870 && IT_CHARPOS (*it) >= to_charpos \
5871 && (it->method == GET_FROM_BUFFER \
5872 || (it->method == GET_FROM_DISPLAY_VECTOR \
5873 && it->dpvec + it->current.dpvec_index + 1 >= it->dpend)))
5874
5875
5876 while (1)
5877 {
5878 int x, i, ascent = 0, descent = 0;
5879
5880 /* Stop when ZV reached.
5881 We used to stop here when TO_CHARPOS reached as well, but that is
5882 too soon if this glyph does not fit on this line. So we handle it
5883 explicitly below. */
5884 if (!get_next_display_element (it)
5885 || (it->truncate_lines_p
5886 && BUFFER_POS_REACHED_P ()))
5887 {
5888 result = MOVE_POS_MATCH_OR_ZV;
5889 break;
5890 }
5891
5892 /* The call to produce_glyphs will get the metrics of the
5893 display element IT is loaded with. We record in x the
5894 x-position before this display element in case it does not
5895 fit on the line. */
5896 x = it->current_x;
5897
5898 /* Remember the line height so far in case the next element doesn't
5899 fit on the line. */
5900 if (!it->truncate_lines_p)
5901 {
5902 ascent = it->max_ascent;
5903 descent = it->max_descent;
5904 }
5905
5906 PRODUCE_GLYPHS (it);
5907
5908 if (it->area != TEXT_AREA)
5909 {
5910 set_iterator_to_next (it, 1);
5911 continue;
5912 }
5913
5914 /* The number of glyphs we get back in IT->nglyphs will normally
5915 be 1 except when IT->c is (i) a TAB, or (ii) a multi-glyph
5916 character on a terminal frame, or (iii) a line end. For the
5917 second case, IT->nglyphs - 1 padding glyphs will be present
5918 (on X frames, there is only one glyph produced for a
5919 composite character.
5920
5921 The behavior implemented below means, for continuation lines,
5922 that as many spaces of a TAB as fit on the current line are
5923 displayed there. For terminal frames, as many glyphs of a
5924 multi-glyph character are displayed in the current line, too.
5925 This is what the old redisplay code did, and we keep it that
5926 way. Under X, the whole shape of a complex character must
5927 fit on the line or it will be completely displayed in the
5928 next line.
5929
5930 Note that both for tabs and padding glyphs, all glyphs have
5931 the same width. */
5932 if (it->nglyphs)
5933 {
5934 /* More than one glyph or glyph doesn't fit on line. All
5935 glyphs have the same width. */
5936 int single_glyph_width = it->pixel_width / it->nglyphs;
5937 int new_x;
5938
5939 for (i = 0; i < it->nglyphs; ++i, x = new_x)
5940 {
5941 new_x = x + single_glyph_width;
5942
5943 /* We want to leave anything reaching TO_X to the caller. */
5944 if ((op & MOVE_TO_X) && new_x > to_x)
5945 {
5946 if (BUFFER_POS_REACHED_P ())
5947 goto buffer_pos_reached;
5948 it->current_x = x;
5949 result = MOVE_X_REACHED;
5950 break;
5951 }
5952 else if (/* Lines are continued. */
5953 !it->truncate_lines_p
5954 && (/* And glyph doesn't fit on the line. */
5955 new_x > it->last_visible_x
5956 /* Or it fits exactly and we're on a window
5957 system frame. */
5958 || (new_x == it->last_visible_x
5959 && FRAME_WINDOW_P (it->f))))
5960 {
5961 if (/* IT->hpos == 0 means the very first glyph
5962 doesn't fit on the line, e.g. a wide image. */
5963 it->hpos == 0
5964 || (new_x == it->last_visible_x
5965 && FRAME_WINDOW_P (it->f)))
5966 {
5967 ++it->hpos;
5968 it->current_x = new_x;
5969 if (i == it->nglyphs - 1)
5970 {
5971 set_iterator_to_next (it, 1);
5972 #ifdef HAVE_WINDOW_SYSTEM
5973 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
5974 {
5975 if (!get_next_display_element (it))
5976 {
5977 result = MOVE_POS_MATCH_OR_ZV;
5978 break;
5979 }
5980 if (BUFFER_POS_REACHED_P ())
5981 {
5982 if (ITERATOR_AT_END_OF_LINE_P (it))
5983 result = MOVE_POS_MATCH_OR_ZV;
5984 else
5985 result = MOVE_LINE_CONTINUED;
5986 break;
5987 }
5988 if (ITERATOR_AT_END_OF_LINE_P (it))
5989 {
5990 result = MOVE_NEWLINE_OR_CR;
5991 break;
5992 }
5993 }
5994 #endif /* HAVE_WINDOW_SYSTEM */
5995 }
5996 }
5997 else
5998 {
5999 it->current_x = x;
6000 it->max_ascent = ascent;
6001 it->max_descent = descent;
6002 }
6003
6004 TRACE_MOVE ((stderr, "move_it_in: continued at %d\n",
6005 IT_CHARPOS (*it)));
6006 result = MOVE_LINE_CONTINUED;
6007 break;
6008 }
6009 else if (BUFFER_POS_REACHED_P ())
6010 goto buffer_pos_reached;
6011 else if (new_x > it->first_visible_x)
6012 {
6013 /* Glyph is visible. Increment number of glyphs that
6014 would be displayed. */
6015 ++it->hpos;
6016 }
6017 else
6018 {
6019 /* Glyph is completely off the left margin of the display
6020 area. Nothing to do. */
6021 }
6022 }
6023
6024 if (result != MOVE_UNDEFINED)
6025 break;
6026 }
6027 else if (BUFFER_POS_REACHED_P ())
6028 {
6029 buffer_pos_reached:
6030 it->current_x = x;
6031 it->max_ascent = ascent;
6032 it->max_descent = descent;
6033 result = MOVE_POS_MATCH_OR_ZV;
6034 break;
6035 }
6036 else if ((op & MOVE_TO_X) && it->current_x >= to_x)
6037 {
6038 /* Stop when TO_X specified and reached. This check is
6039 necessary here because of lines consisting of a line end,
6040 only. The line end will not produce any glyphs and we
6041 would never get MOVE_X_REACHED. */
6042 xassert (it->nglyphs == 0);
6043 result = MOVE_X_REACHED;
6044 break;
6045 }
6046
6047 /* Is this a line end? If yes, we're done. */
6048 if (ITERATOR_AT_END_OF_LINE_P (it))
6049 {
6050 result = MOVE_NEWLINE_OR_CR;
6051 break;
6052 }
6053
6054 /* The current display element has been consumed. Advance
6055 to the next. */
6056 set_iterator_to_next (it, 1);
6057
6058 /* Stop if lines are truncated and IT's current x-position is
6059 past the right edge of the window now. */
6060 if (it->truncate_lines_p
6061 && it->current_x >= it->last_visible_x)
6062 {
6063 #ifdef HAVE_WINDOW_SYSTEM
6064 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
6065 {
6066 if (!get_next_display_element (it)
6067 || BUFFER_POS_REACHED_P ())
6068 {
6069 result = MOVE_POS_MATCH_OR_ZV;
6070 break;
6071 }
6072 if (ITERATOR_AT_END_OF_LINE_P (it))
6073 {
6074 result = MOVE_NEWLINE_OR_CR;
6075 break;
6076 }
6077 }
6078 #endif /* HAVE_WINDOW_SYSTEM */
6079 result = MOVE_LINE_TRUNCATED;
6080 break;
6081 }
6082 }
6083
6084 #undef BUFFER_POS_REACHED_P
6085
6086 /* Restore the iterator settings altered at the beginning of this
6087 function. */
6088 it->glyph_row = saved_glyph_row;
6089 return result;
6090 }
6091
6092
6093 /* Move IT forward until it satisfies one or more of the criteria in
6094 TO_CHARPOS, TO_X, TO_Y, and TO_VPOS.
6095
6096 OP is a bit-mask that specifies where to stop, and in particular,
6097 which of those four position arguments makes a difference. See the
6098 description of enum move_operation_enum.
6099
6100 If TO_CHARPOS is in invisible text, e.g. a truncated part of a
6101 screen line, this function will set IT to the next position >
6102 TO_CHARPOS. */
6103
6104 void
6105 move_it_to (it, to_charpos, to_x, to_y, to_vpos, op)
6106 struct it *it;
6107 int to_charpos, to_x, to_y, to_vpos;
6108 int op;
6109 {
6110 enum move_it_result skip, skip2 = MOVE_X_REACHED;
6111 int line_height;
6112 int reached = 0;
6113
6114 for (;;)
6115 {
6116 if (op & MOVE_TO_VPOS)
6117 {
6118 /* If no TO_CHARPOS and no TO_X specified, stop at the
6119 start of the line TO_VPOS. */
6120 if ((op & (MOVE_TO_X | MOVE_TO_POS)) == 0)
6121 {
6122 if (it->vpos == to_vpos)
6123 {
6124 reached = 1;
6125 break;
6126 }
6127 else
6128 skip = move_it_in_display_line_to (it, -1, -1, 0);
6129 }
6130 else
6131 {
6132 /* TO_VPOS >= 0 means stop at TO_X in the line at
6133 TO_VPOS, or at TO_POS, whichever comes first. */
6134 if (it->vpos == to_vpos)
6135 {
6136 reached = 2;
6137 break;
6138 }
6139
6140 skip = move_it_in_display_line_to (it, to_charpos, to_x, op);
6141
6142 if (skip == MOVE_POS_MATCH_OR_ZV || it->vpos == to_vpos)
6143 {
6144 reached = 3;
6145 break;
6146 }
6147 else if (skip == MOVE_X_REACHED && it->vpos != to_vpos)
6148 {
6149 /* We have reached TO_X but not in the line we want. */
6150 skip = move_it_in_display_line_to (it, to_charpos,
6151 -1, MOVE_TO_POS);
6152 if (skip == MOVE_POS_MATCH_OR_ZV)
6153 {
6154 reached = 4;
6155 break;
6156 }
6157 }
6158 }
6159 }
6160 else if (op & MOVE_TO_Y)
6161 {
6162 struct it it_backup;
6163
6164 /* TO_Y specified means stop at TO_X in the line containing
6165 TO_Y---or at TO_CHARPOS if this is reached first. The
6166 problem is that we can't really tell whether the line
6167 contains TO_Y before we have completely scanned it, and
6168 this may skip past TO_X. What we do is to first scan to
6169 TO_X.
6170
6171 If TO_X is not specified, use a TO_X of zero. The reason
6172 is to make the outcome of this function more predictable.
6173 If we didn't use TO_X == 0, we would stop at the end of
6174 the line which is probably not what a caller would expect
6175 to happen. */
6176 skip = move_it_in_display_line_to (it, to_charpos,
6177 ((op & MOVE_TO_X)
6178 ? to_x : 0),
6179 (MOVE_TO_X
6180 | (op & MOVE_TO_POS)));
6181
6182 /* If TO_CHARPOS is reached or ZV, we don't have to do more. */
6183 if (skip == MOVE_POS_MATCH_OR_ZV)
6184 {
6185 reached = 5;
6186 break;
6187 }
6188
6189 /* If TO_X was reached, we would like to know whether TO_Y
6190 is in the line. This can only be said if we know the
6191 total line height which requires us to scan the rest of
6192 the line. */
6193 if (skip == MOVE_X_REACHED)
6194 {
6195 it_backup = *it;
6196 TRACE_MOVE ((stderr, "move_it: from %d\n", IT_CHARPOS (*it)));
6197 skip2 = move_it_in_display_line_to (it, to_charpos, -1,
6198 op & MOVE_TO_POS);
6199 TRACE_MOVE ((stderr, "move_it: to %d\n", IT_CHARPOS (*it)));
6200 }
6201
6202 /* Now, decide whether TO_Y is in this line. */
6203 line_height = it->max_ascent + it->max_descent;
6204 TRACE_MOVE ((stderr, "move_it: line_height = %d\n", line_height));
6205
6206 if (to_y >= it->current_y
6207 && to_y < it->current_y + line_height)
6208 {
6209 if (skip == MOVE_X_REACHED)
6210 /* If TO_Y is in this line and TO_X was reached above,
6211 we scanned too far. We have to restore IT's settings
6212 to the ones before skipping. */
6213 *it = it_backup;
6214 reached = 6;
6215 }
6216 else if (skip == MOVE_X_REACHED)
6217 {
6218 skip = skip2;
6219 if (skip == MOVE_POS_MATCH_OR_ZV)
6220 reached = 7;
6221 }
6222
6223 if (reached)
6224 break;
6225 }
6226 else
6227 skip = move_it_in_display_line_to (it, to_charpos, -1, MOVE_TO_POS);
6228
6229 switch (skip)
6230 {
6231 case MOVE_POS_MATCH_OR_ZV:
6232 reached = 8;
6233 goto out;
6234
6235 case MOVE_NEWLINE_OR_CR:
6236 set_iterator_to_next (it, 1);
6237 it->continuation_lines_width = 0;
6238 break;
6239
6240 case MOVE_LINE_TRUNCATED:
6241 it->continuation_lines_width = 0;
6242 reseat_at_next_visible_line_start (it, 0);
6243 if ((op & MOVE_TO_POS) != 0
6244 && IT_CHARPOS (*it) > to_charpos)
6245 {
6246 reached = 9;
6247 goto out;
6248 }
6249 break;
6250
6251 case MOVE_LINE_CONTINUED:
6252 it->continuation_lines_width += it->current_x;
6253 break;
6254
6255 default:
6256 abort ();
6257 }
6258
6259 /* Reset/increment for the next run. */
6260 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
6261 it->current_x = it->hpos = 0;
6262 it->current_y += it->max_ascent + it->max_descent;
6263 ++it->vpos;
6264 last_height = it->max_ascent + it->max_descent;
6265 last_max_ascent = it->max_ascent;
6266 it->max_ascent = it->max_descent = 0;
6267 }
6268
6269 out:
6270
6271 TRACE_MOVE ((stderr, "move_it_to: reached %d\n", reached));
6272 }
6273
6274
6275 /* Move iterator IT backward by a specified y-distance DY, DY >= 0.
6276
6277 If DY > 0, move IT backward at least that many pixels. DY = 0
6278 means move IT backward to the preceding line start or BEGV. This
6279 function may move over more than DY pixels if IT->current_y - DY
6280 ends up in the middle of a line; in this case IT->current_y will be
6281 set to the top of the line moved to. */
6282
6283 void
6284 move_it_vertically_backward (it, dy)
6285 struct it *it;
6286 int dy;
6287 {
6288 int nlines, h;
6289 struct it it2, it3;
6290 int start_pos;
6291
6292 move_further_back:
6293 xassert (dy >= 0);
6294
6295 start_pos = IT_CHARPOS (*it);
6296
6297 /* Estimate how many newlines we must move back. */
6298 nlines = max (1, dy / FRAME_LINE_HEIGHT (it->f));
6299
6300 /* Set the iterator's position that many lines back. */
6301 while (nlines-- && IT_CHARPOS (*it) > BEGV)
6302 back_to_previous_visible_line_start (it);
6303
6304 /* Reseat the iterator here. When moving backward, we don't want
6305 reseat to skip forward over invisible text, set up the iterator
6306 to deliver from overlay strings at the new position etc. So,
6307 use reseat_1 here. */
6308 reseat_1 (it, it->current.pos, 1);
6309
6310 /* We are now surely at a line start. */
6311 it->current_x = it->hpos = 0;
6312 it->continuation_lines_width = 0;
6313
6314 /* Move forward and see what y-distance we moved. First move to the
6315 start of the next line so that we get its height. We need this
6316 height to be able to tell whether we reached the specified
6317 y-distance. */
6318 it2 = *it;
6319 it2.max_ascent = it2.max_descent = 0;
6320 move_it_to (&it2, start_pos, -1, -1, it2.vpos + 1,
6321 MOVE_TO_POS | MOVE_TO_VPOS);
6322 xassert (IT_CHARPOS (*it) >= BEGV);
6323 it3 = it2;
6324
6325 move_it_to (&it2, start_pos, -1, -1, -1, MOVE_TO_POS);
6326 xassert (IT_CHARPOS (*it) >= BEGV);
6327 /* H is the actual vertical distance from the position in *IT
6328 and the starting position. */
6329 h = it2.current_y - it->current_y;
6330 /* NLINES is the distance in number of lines. */
6331 nlines = it2.vpos - it->vpos;
6332
6333 /* Correct IT's y and vpos position
6334 so that they are relative to the starting point. */
6335 it->vpos -= nlines;
6336 it->current_y -= h;
6337
6338 if (dy == 0)
6339 {
6340 /* DY == 0 means move to the start of the screen line. The
6341 value of nlines is > 0 if continuation lines were involved. */
6342 if (nlines > 0)
6343 move_it_by_lines (it, nlines, 1);
6344 #if 0
6345 /* I think this assert is bogus if buffer contains
6346 invisible text or images. KFS. */
6347 xassert (IT_CHARPOS (*it) <= start_pos);
6348 #endif
6349 }
6350 else
6351 {
6352 /* The y-position we try to reach, relative to *IT.
6353 Note that H has been subtracted in front of the if-statement. */
6354 int target_y = it->current_y + h - dy;
6355 int y0 = it3.current_y;
6356 int y1 = line_bottom_y (&it3);
6357 int line_height = y1 - y0;
6358
6359 /* If we did not reach target_y, try to move further backward if
6360 we can. If we moved too far backward, try to move forward. */
6361 if (target_y < it->current_y
6362 /* This is heuristic. In a window that's 3 lines high, with
6363 a line height of 13 pixels each, recentering with point
6364 on the bottom line will try to move -39/2 = 19 pixels
6365 backward. Try to avoid moving into the first line. */
6366 && (it->current_y - target_y
6367 > min (window_box_height (it->w), line_height * 2 / 3))
6368 && IT_CHARPOS (*it) > BEGV)
6369 {
6370 TRACE_MOVE ((stderr, " not far enough -> move_vert %d\n",
6371 target_y - it->current_y));
6372 dy = it->current_y - target_y;
6373 goto move_further_back;
6374 }
6375 else if (target_y >= it->current_y + line_height
6376 && IT_CHARPOS (*it) < ZV)
6377 {
6378 /* Should move forward by at least one line, maybe more.
6379
6380 Note: Calling move_it_by_lines can be expensive on
6381 terminal frames, where compute_motion is used (via
6382 vmotion) to do the job, when there are very long lines
6383 and truncate-lines is nil. That's the reason for
6384 treating terminal frames specially here. */
6385
6386 if (!FRAME_WINDOW_P (it->f))
6387 move_it_vertically (it, target_y - (it->current_y + line_height));
6388 else
6389 {
6390 do
6391 {
6392 move_it_by_lines (it, 1, 1);
6393 }
6394 while (target_y >= line_bottom_y (it) && IT_CHARPOS (*it) < ZV);
6395 }
6396
6397 #if 0
6398 /* I think this assert is bogus if buffer contains
6399 invisible text or images. KFS. */
6400 xassert (IT_CHARPOS (*it) >= BEGV);
6401 #endif
6402 }
6403 }
6404 }
6405
6406
6407 /* Move IT by a specified amount of pixel lines DY. DY negative means
6408 move backwards. DY = 0 means move to start of screen line. At the
6409 end, IT will be on the start of a screen line. */
6410
6411 void
6412 move_it_vertically (it, dy)
6413 struct it *it;
6414 int dy;
6415 {
6416 if (dy <= 0)
6417 move_it_vertically_backward (it, -dy);
6418 else
6419 {
6420 TRACE_MOVE ((stderr, "move_it_v: from %d, %d\n", IT_CHARPOS (*it), dy));
6421 move_it_to (it, ZV, -1, it->current_y + dy, -1,
6422 MOVE_TO_POS | MOVE_TO_Y);
6423 TRACE_MOVE ((stderr, "move_it_v: to %d\n", IT_CHARPOS (*it)));
6424
6425 /* If buffer ends in ZV without a newline, move to the start of
6426 the line to satisfy the post-condition. */
6427 if (IT_CHARPOS (*it) == ZV
6428 && FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n')
6429 move_it_by_lines (it, 0, 0);
6430 }
6431 }
6432
6433
6434 /* Move iterator IT past the end of the text line it is in. */
6435
6436 void
6437 move_it_past_eol (it)
6438 struct it *it;
6439 {
6440 enum move_it_result rc;
6441
6442 rc = move_it_in_display_line_to (it, Z, 0, MOVE_TO_POS);
6443 if (rc == MOVE_NEWLINE_OR_CR)
6444 set_iterator_to_next (it, 0);
6445 }
6446
6447
6448 #if 0 /* Currently not used. */
6449
6450 /* Return non-zero if some text between buffer positions START_CHARPOS
6451 and END_CHARPOS is invisible. IT->window is the window for text
6452 property lookup. */
6453
6454 static int
6455 invisible_text_between_p (it, start_charpos, end_charpos)
6456 struct it *it;
6457 int start_charpos, end_charpos;
6458 {
6459 Lisp_Object prop, limit;
6460 int invisible_found_p;
6461
6462 xassert (it != NULL && start_charpos <= end_charpos);
6463
6464 /* Is text at START invisible? */
6465 prop = Fget_char_property (make_number (start_charpos), Qinvisible,
6466 it->window);
6467 if (TEXT_PROP_MEANS_INVISIBLE (prop))
6468 invisible_found_p = 1;
6469 else
6470 {
6471 limit = Fnext_single_char_property_change (make_number (start_charpos),
6472 Qinvisible, Qnil,
6473 make_number (end_charpos));
6474 invisible_found_p = XFASTINT (limit) < end_charpos;
6475 }
6476
6477 return invisible_found_p;
6478 }
6479
6480 #endif /* 0 */
6481
6482
6483 /* Move IT by a specified number DVPOS of screen lines down. DVPOS
6484 negative means move up. DVPOS == 0 means move to the start of the
6485 screen line. NEED_Y_P non-zero means calculate IT->current_y. If
6486 NEED_Y_P is zero, IT->current_y will be left unchanged.
6487
6488 Further optimization ideas: If we would know that IT->f doesn't use
6489 a face with proportional font, we could be faster for
6490 truncate-lines nil. */
6491
6492 void
6493 move_it_by_lines (it, dvpos, need_y_p)
6494 struct it *it;
6495 int dvpos, need_y_p;
6496 {
6497 struct position pos;
6498
6499 if (!FRAME_WINDOW_P (it->f))
6500 {
6501 struct text_pos textpos;
6502
6503 /* We can use vmotion on frames without proportional fonts. */
6504 pos = *vmotion (IT_CHARPOS (*it), dvpos, it->w);
6505 SET_TEXT_POS (textpos, pos.bufpos, pos.bytepos);
6506 reseat (it, textpos, 1);
6507 it->vpos += pos.vpos;
6508 it->current_y += pos.vpos;
6509 }
6510 else if (dvpos == 0)
6511 {
6512 /* DVPOS == 0 means move to the start of the screen line. */
6513 move_it_vertically_backward (it, 0);
6514 xassert (it->current_x == 0 && it->hpos == 0);
6515 /* Let next call to line_bottom_y calculate real line height */
6516 last_height = 0;
6517 }
6518 else if (dvpos > 0)
6519 move_it_to (it, -1, -1, -1, it->vpos + dvpos, MOVE_TO_VPOS);
6520 else
6521 {
6522 struct it it2;
6523 int start_charpos, i;
6524
6525 /* Start at the beginning of the screen line containing IT's
6526 position. */
6527 move_it_vertically_backward (it, 0);
6528
6529 /* Go back -DVPOS visible lines and reseat the iterator there. */
6530 start_charpos = IT_CHARPOS (*it);
6531 for (i = -dvpos; i && IT_CHARPOS (*it) > BEGV; --i)
6532 back_to_previous_visible_line_start (it);
6533 reseat (it, it->current.pos, 1);
6534 it->current_x = it->hpos = 0;
6535
6536 /* Above call may have moved too far if continuation lines
6537 are involved. Scan forward and see if it did. */
6538 it2 = *it;
6539 it2.vpos = it2.current_y = 0;
6540 move_it_to (&it2, start_charpos, -1, -1, -1, MOVE_TO_POS);
6541 it->vpos -= it2.vpos;
6542 it->current_y -= it2.current_y;
6543 it->current_x = it->hpos = 0;
6544
6545 /* If we moved too far back, move IT some lines forward. */
6546 if (it2.vpos > -dvpos)
6547 {
6548 int delta = it2.vpos + dvpos;
6549 it2 = *it;
6550 move_it_to (it, -1, -1, -1, it->vpos + delta, MOVE_TO_VPOS);
6551 /* Move back again if we got too far ahead. */
6552 if (IT_CHARPOS (*it) >= start_charpos)
6553 *it = it2;
6554 }
6555 }
6556 }
6557
6558 /* Return 1 if IT points into the middle of a display vector. */
6559
6560 int
6561 in_display_vector_p (it)
6562 struct it *it;
6563 {
6564 return (it->method == GET_FROM_DISPLAY_VECTOR
6565 && it->current.dpvec_index > 0
6566 && it->dpvec + it->current.dpvec_index != it->dpend);
6567 }
6568
6569 \f
6570 /***********************************************************************
6571 Messages
6572 ***********************************************************************/
6573
6574
6575 /* Add a message with format string FORMAT and arguments ARG1 and ARG2
6576 to *Messages*. */
6577
6578 void
6579 add_to_log (format, arg1, arg2)
6580 char *format;
6581 Lisp_Object arg1, arg2;
6582 {
6583 Lisp_Object args[3];
6584 Lisp_Object msg, fmt;
6585 char *buffer;
6586 int len;
6587 struct gcpro gcpro1, gcpro2, gcpro3, gcpro4;
6588 USE_SAFE_ALLOCA;
6589
6590 /* Do nothing if called asynchronously. Inserting text into
6591 a buffer may call after-change-functions and alike and
6592 that would means running Lisp asynchronously. */
6593 if (handling_signal)
6594 return;
6595
6596 fmt = msg = Qnil;
6597 GCPRO4 (fmt, msg, arg1, arg2);
6598
6599 args[0] = fmt = build_string (format);
6600 args[1] = arg1;
6601 args[2] = arg2;
6602 msg = Fformat (3, args);
6603
6604 len = SBYTES (msg) + 1;
6605 SAFE_ALLOCA (buffer, char *, len);
6606 bcopy (SDATA (msg), buffer, len);
6607
6608 message_dolog (buffer, len - 1, 1, 0);
6609 SAFE_FREE ();
6610
6611 UNGCPRO;
6612 }
6613
6614
6615 /* Output a newline in the *Messages* buffer if "needs" one. */
6616
6617 void
6618 message_log_maybe_newline ()
6619 {
6620 if (message_log_need_newline)
6621 message_dolog ("", 0, 1, 0);
6622 }
6623
6624
6625 /* Add a string M of length NBYTES to the message log, optionally
6626 terminated with a newline when NLFLAG is non-zero. MULTIBYTE, if
6627 nonzero, means interpret the contents of M as multibyte. This
6628 function calls low-level routines in order to bypass text property
6629 hooks, etc. which might not be safe to run. */
6630
6631 void
6632 message_dolog (m, nbytes, nlflag, multibyte)
6633 const char *m;
6634 int nbytes, nlflag, multibyte;
6635 {
6636 if (!NILP (Vmemory_full))
6637 return;
6638
6639 if (!NILP (Vmessage_log_max))
6640 {
6641 struct buffer *oldbuf;
6642 Lisp_Object oldpoint, oldbegv, oldzv;
6643 int old_windows_or_buffers_changed = windows_or_buffers_changed;
6644 int point_at_end = 0;
6645 int zv_at_end = 0;
6646 Lisp_Object old_deactivate_mark, tem;
6647 struct gcpro gcpro1;
6648
6649 old_deactivate_mark = Vdeactivate_mark;
6650 oldbuf = current_buffer;
6651 Fset_buffer (Fget_buffer_create (Vmessages_buffer_name));
6652 current_buffer->undo_list = Qt;
6653
6654 oldpoint = message_dolog_marker1;
6655 set_marker_restricted (oldpoint, make_number (PT), Qnil);
6656 oldbegv = message_dolog_marker2;
6657 set_marker_restricted (oldbegv, make_number (BEGV), Qnil);
6658 oldzv = message_dolog_marker3;
6659 set_marker_restricted (oldzv, make_number (ZV), Qnil);
6660 GCPRO1 (old_deactivate_mark);
6661
6662 if (PT == Z)
6663 point_at_end = 1;
6664 if (ZV == Z)
6665 zv_at_end = 1;
6666
6667 BEGV = BEG;
6668 BEGV_BYTE = BEG_BYTE;
6669 ZV = Z;
6670 ZV_BYTE = Z_BYTE;
6671 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6672
6673 /* Insert the string--maybe converting multibyte to single byte
6674 or vice versa, so that all the text fits the buffer. */
6675 if (multibyte
6676 && NILP (current_buffer->enable_multibyte_characters))
6677 {
6678 int i, c, char_bytes;
6679 unsigned char work[1];
6680
6681 /* Convert a multibyte string to single-byte
6682 for the *Message* buffer. */
6683 for (i = 0; i < nbytes; i += char_bytes)
6684 {
6685 c = string_char_and_length (m + i, nbytes - i, &char_bytes);
6686 work[0] = (SINGLE_BYTE_CHAR_P (c)
6687 ? c
6688 : multibyte_char_to_unibyte (c, Qnil));
6689 insert_1_both (work, 1, 1, 1, 0, 0);
6690 }
6691 }
6692 else if (! multibyte
6693 && ! NILP (current_buffer->enable_multibyte_characters))
6694 {
6695 int i, c, char_bytes;
6696 unsigned char *msg = (unsigned char *) m;
6697 unsigned char str[MAX_MULTIBYTE_LENGTH];
6698 /* Convert a single-byte string to multibyte
6699 for the *Message* buffer. */
6700 for (i = 0; i < nbytes; i++)
6701 {
6702 c = unibyte_char_to_multibyte (msg[i]);
6703 char_bytes = CHAR_STRING (c, str);
6704 insert_1_both (str, 1, char_bytes, 1, 0, 0);
6705 }
6706 }
6707 else if (nbytes)
6708 insert_1 (m, nbytes, 1, 0, 0);
6709
6710 if (nlflag)
6711 {
6712 int this_bol, this_bol_byte, prev_bol, prev_bol_byte, dup;
6713 insert_1 ("\n", 1, 1, 0, 0);
6714
6715 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE, -2, 0);
6716 this_bol = PT;
6717 this_bol_byte = PT_BYTE;
6718
6719 /* See if this line duplicates the previous one.
6720 If so, combine duplicates. */
6721 if (this_bol > BEG)
6722 {
6723 scan_newline (PT, PT_BYTE, BEG, BEG_BYTE, -2, 0);
6724 prev_bol = PT;
6725 prev_bol_byte = PT_BYTE;
6726
6727 dup = message_log_check_duplicate (prev_bol, prev_bol_byte,
6728 this_bol, this_bol_byte);
6729 if (dup)
6730 {
6731 del_range_both (prev_bol, prev_bol_byte,
6732 this_bol, this_bol_byte, 0);
6733 if (dup > 1)
6734 {
6735 char dupstr[40];
6736 int duplen;
6737
6738 /* If you change this format, don't forget to also
6739 change message_log_check_duplicate. */
6740 sprintf (dupstr, " [%d times]", dup);
6741 duplen = strlen (dupstr);
6742 TEMP_SET_PT_BOTH (Z - 1, Z_BYTE - 1);
6743 insert_1 (dupstr, duplen, 1, 0, 1);
6744 }
6745 }
6746 }
6747
6748 /* If we have more than the desired maximum number of lines
6749 in the *Messages* buffer now, delete the oldest ones.
6750 This is safe because we don't have undo in this buffer. */
6751
6752 if (NATNUMP (Vmessage_log_max))
6753 {
6754 scan_newline (Z, Z_BYTE, BEG, BEG_BYTE,
6755 -XFASTINT (Vmessage_log_max) - 1, 0);
6756 del_range_both (BEG, BEG_BYTE, PT, PT_BYTE, 0);
6757 }
6758 }
6759 BEGV = XMARKER (oldbegv)->charpos;
6760 BEGV_BYTE = marker_byte_position (oldbegv);
6761
6762 if (zv_at_end)
6763 {
6764 ZV = Z;
6765 ZV_BYTE = Z_BYTE;
6766 }
6767 else
6768 {
6769 ZV = XMARKER (oldzv)->charpos;
6770 ZV_BYTE = marker_byte_position (oldzv);
6771 }
6772
6773 if (point_at_end)
6774 TEMP_SET_PT_BOTH (Z, Z_BYTE);
6775 else
6776 /* We can't do Fgoto_char (oldpoint) because it will run some
6777 Lisp code. */
6778 TEMP_SET_PT_BOTH (XMARKER (oldpoint)->charpos,
6779 XMARKER (oldpoint)->bytepos);
6780
6781 UNGCPRO;
6782 unchain_marker (XMARKER (oldpoint));
6783 unchain_marker (XMARKER (oldbegv));
6784 unchain_marker (XMARKER (oldzv));
6785
6786 tem = Fget_buffer_window (Fcurrent_buffer (), Qt);
6787 set_buffer_internal (oldbuf);
6788 if (NILP (tem))
6789 windows_or_buffers_changed = old_windows_or_buffers_changed;
6790 message_log_need_newline = !nlflag;
6791 Vdeactivate_mark = old_deactivate_mark;
6792 }
6793 }
6794
6795
6796 /* We are at the end of the buffer after just having inserted a newline.
6797 (Note: We depend on the fact we won't be crossing the gap.)
6798 Check to see if the most recent message looks a lot like the previous one.
6799 Return 0 if different, 1 if the new one should just replace it, or a
6800 value N > 1 if we should also append " [N times]". */
6801
6802 static int
6803 message_log_check_duplicate (prev_bol, prev_bol_byte, this_bol, this_bol_byte)
6804 int prev_bol, this_bol;
6805 int prev_bol_byte, this_bol_byte;
6806 {
6807 int i;
6808 int len = Z_BYTE - 1 - this_bol_byte;
6809 int seen_dots = 0;
6810 unsigned char *p1 = BUF_BYTE_ADDRESS (current_buffer, prev_bol_byte);
6811 unsigned char *p2 = BUF_BYTE_ADDRESS (current_buffer, this_bol_byte);
6812
6813 for (i = 0; i < len; i++)
6814 {
6815 if (i >= 3 && p1[i-3] == '.' && p1[i-2] == '.' && p1[i-1] == '.')
6816 seen_dots = 1;
6817 if (p1[i] != p2[i])
6818 return seen_dots;
6819 }
6820 p1 += len;
6821 if (*p1 == '\n')
6822 return 2;
6823 if (*p1++ == ' ' && *p1++ == '[')
6824 {
6825 int n = 0;
6826 while (*p1 >= '0' && *p1 <= '9')
6827 n = n * 10 + *p1++ - '0';
6828 if (strncmp (p1, " times]\n", 8) == 0)
6829 return n+1;
6830 }
6831 return 0;
6832 }
6833 \f
6834
6835 /* Display an echo area message M with a specified length of NBYTES
6836 bytes. The string may include null characters. If M is 0, clear
6837 out any existing message, and let the mini-buffer text show
6838 through.
6839
6840 The buffer M must continue to exist until after the echo area gets
6841 cleared or some other message gets displayed there. This means do
6842 not pass text that is stored in a Lisp string; do not pass text in
6843 a buffer that was alloca'd. */
6844
6845 void
6846 message2 (m, nbytes, multibyte)
6847 const char *m;
6848 int nbytes;
6849 int multibyte;
6850 {
6851 /* First flush out any partial line written with print. */
6852 message_log_maybe_newline ();
6853 if (m)
6854 message_dolog (m, nbytes, 1, multibyte);
6855 message2_nolog (m, nbytes, multibyte);
6856 }
6857
6858
6859 /* The non-logging counterpart of message2. */
6860
6861 void
6862 message2_nolog (m, nbytes, multibyte)
6863 const char *m;
6864 int nbytes, multibyte;
6865 {
6866 struct frame *sf = SELECTED_FRAME ();
6867 message_enable_multibyte = multibyte;
6868
6869 if (noninteractive)
6870 {
6871 if (noninteractive_need_newline)
6872 putc ('\n', stderr);
6873 noninteractive_need_newline = 0;
6874 if (m)
6875 fwrite (m, nbytes, 1, stderr);
6876 if (cursor_in_echo_area == 0)
6877 fprintf (stderr, "\n");
6878 fflush (stderr);
6879 }
6880 /* A null message buffer means that the frame hasn't really been
6881 initialized yet. Error messages get reported properly by
6882 cmd_error, so this must be just an informative message; toss it. */
6883 else if (INTERACTIVE
6884 && sf->glyphs_initialized_p
6885 && FRAME_MESSAGE_BUF (sf))
6886 {
6887 Lisp_Object mini_window;
6888 struct frame *f;
6889
6890 /* Get the frame containing the mini-buffer
6891 that the selected frame is using. */
6892 mini_window = FRAME_MINIBUF_WINDOW (sf);
6893 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
6894
6895 FRAME_SAMPLE_VISIBILITY (f);
6896 if (FRAME_VISIBLE_P (sf)
6897 && ! FRAME_VISIBLE_P (f))
6898 Fmake_frame_visible (WINDOW_FRAME (XWINDOW (mini_window)));
6899
6900 if (m)
6901 {
6902 set_message (m, Qnil, nbytes, multibyte);
6903 if (minibuffer_auto_raise)
6904 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
6905 }
6906 else
6907 clear_message (1, 1);
6908
6909 do_pending_window_change (0);
6910 echo_area_display (1);
6911 do_pending_window_change (0);
6912 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
6913 (*frame_up_to_date_hook) (f);
6914 }
6915 }
6916
6917
6918 /* Display an echo area message M with a specified length of NBYTES
6919 bytes. The string may include null characters. If M is not a
6920 string, clear out any existing message, and let the mini-buffer
6921 text show through. */
6922
6923 void
6924 message3 (m, nbytes, multibyte)
6925 Lisp_Object m;
6926 int nbytes;
6927 int multibyte;
6928 {
6929 struct gcpro gcpro1;
6930
6931 GCPRO1 (m);
6932 clear_message (1,1);
6933
6934 /* First flush out any partial line written with print. */
6935 message_log_maybe_newline ();
6936 if (STRINGP (m))
6937 message_dolog (SDATA (m), nbytes, 1, multibyte);
6938 message3_nolog (m, nbytes, multibyte);
6939
6940 UNGCPRO;
6941 }
6942
6943
6944 /* The non-logging version of message3. */
6945
6946 void
6947 message3_nolog (m, nbytes, multibyte)
6948 Lisp_Object m;
6949 int nbytes, multibyte;
6950 {
6951 struct frame *sf = SELECTED_FRAME ();
6952 message_enable_multibyte = multibyte;
6953
6954 if (noninteractive)
6955 {
6956 if (noninteractive_need_newline)
6957 putc ('\n', stderr);
6958 noninteractive_need_newline = 0;
6959 if (STRINGP (m))
6960 fwrite (SDATA (m), nbytes, 1, stderr);
6961 if (cursor_in_echo_area == 0)
6962 fprintf (stderr, "\n");
6963 fflush (stderr);
6964 }
6965 /* A null message buffer means that the frame hasn't really been
6966 initialized yet. Error messages get reported properly by
6967 cmd_error, so this must be just an informative message; toss it. */
6968 else if (INTERACTIVE
6969 && sf->glyphs_initialized_p
6970 && FRAME_MESSAGE_BUF (sf))
6971 {
6972 Lisp_Object mini_window;
6973 Lisp_Object frame;
6974 struct frame *f;
6975
6976 /* Get the frame containing the mini-buffer
6977 that the selected frame is using. */
6978 mini_window = FRAME_MINIBUF_WINDOW (sf);
6979 frame = XWINDOW (mini_window)->frame;
6980 f = XFRAME (frame);
6981
6982 FRAME_SAMPLE_VISIBILITY (f);
6983 if (FRAME_VISIBLE_P (sf)
6984 && !FRAME_VISIBLE_P (f))
6985 Fmake_frame_visible (frame);
6986
6987 if (STRINGP (m) && SCHARS (m) > 0)
6988 {
6989 set_message (NULL, m, nbytes, multibyte);
6990 if (minibuffer_auto_raise)
6991 Fraise_frame (frame);
6992 }
6993 else
6994 clear_message (1, 1);
6995
6996 do_pending_window_change (0);
6997 echo_area_display (1);
6998 do_pending_window_change (0);
6999 if (frame_up_to_date_hook != 0 && ! gc_in_progress)
7000 (*frame_up_to_date_hook) (f);
7001 }
7002 }
7003
7004
7005 /* Display a null-terminated echo area message M. If M is 0, clear
7006 out any existing message, and let the mini-buffer text show through.
7007
7008 The buffer M must continue to exist until after the echo area gets
7009 cleared or some other message gets displayed there. Do not pass
7010 text that is stored in a Lisp string. Do not pass text in a buffer
7011 that was alloca'd. */
7012
7013 void
7014 message1 (m)
7015 char *m;
7016 {
7017 message2 (m, (m ? strlen (m) : 0), 0);
7018 }
7019
7020
7021 /* The non-logging counterpart of message1. */
7022
7023 void
7024 message1_nolog (m)
7025 char *m;
7026 {
7027 message2_nolog (m, (m ? strlen (m) : 0), 0);
7028 }
7029
7030 /* Display a message M which contains a single %s
7031 which gets replaced with STRING. */
7032
7033 void
7034 message_with_string (m, string, log)
7035 char *m;
7036 Lisp_Object string;
7037 int log;
7038 {
7039 CHECK_STRING (string);
7040
7041 if (noninteractive)
7042 {
7043 if (m)
7044 {
7045 if (noninteractive_need_newline)
7046 putc ('\n', stderr);
7047 noninteractive_need_newline = 0;
7048 fprintf (stderr, m, SDATA (string));
7049 if (cursor_in_echo_area == 0)
7050 fprintf (stderr, "\n");
7051 fflush (stderr);
7052 }
7053 }
7054 else if (INTERACTIVE)
7055 {
7056 /* The frame whose minibuffer we're going to display the message on.
7057 It may be larger than the selected frame, so we need
7058 to use its buffer, not the selected frame's buffer. */
7059 Lisp_Object mini_window;
7060 struct frame *f, *sf = SELECTED_FRAME ();
7061
7062 /* Get the frame containing the minibuffer
7063 that the selected frame is using. */
7064 mini_window = FRAME_MINIBUF_WINDOW (sf);
7065 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7066
7067 /* A null message buffer means that the frame hasn't really been
7068 initialized yet. Error messages get reported properly by
7069 cmd_error, so this must be just an informative message; toss it. */
7070 if (FRAME_MESSAGE_BUF (f))
7071 {
7072 Lisp_Object args[2], message;
7073 struct gcpro gcpro1, gcpro2;
7074
7075 args[0] = build_string (m);
7076 args[1] = message = string;
7077 GCPRO2 (args[0], message);
7078 gcpro1.nvars = 2;
7079
7080 message = Fformat (2, args);
7081
7082 if (log)
7083 message3 (message, SBYTES (message), STRING_MULTIBYTE (message));
7084 else
7085 message3_nolog (message, SBYTES (message), STRING_MULTIBYTE (message));
7086
7087 UNGCPRO;
7088
7089 /* Print should start at the beginning of the message
7090 buffer next time. */
7091 message_buf_print = 0;
7092 }
7093 }
7094 }
7095
7096
7097 /* Dump an informative message to the minibuf. If M is 0, clear out
7098 any existing message, and let the mini-buffer text show through. */
7099
7100 /* VARARGS 1 */
7101 void
7102 message (m, a1, a2, a3)
7103 char *m;
7104 EMACS_INT a1, a2, a3;
7105 {
7106 if (noninteractive)
7107 {
7108 if (m)
7109 {
7110 if (noninteractive_need_newline)
7111 putc ('\n', stderr);
7112 noninteractive_need_newline = 0;
7113 fprintf (stderr, m, a1, a2, a3);
7114 if (cursor_in_echo_area == 0)
7115 fprintf (stderr, "\n");
7116 fflush (stderr);
7117 }
7118 }
7119 else if (INTERACTIVE)
7120 {
7121 /* The frame whose mini-buffer we're going to display the message
7122 on. It may be larger than the selected frame, so we need to
7123 use its buffer, not the selected frame's buffer. */
7124 Lisp_Object mini_window;
7125 struct frame *f, *sf = SELECTED_FRAME ();
7126
7127 /* Get the frame containing the mini-buffer
7128 that the selected frame is using. */
7129 mini_window = FRAME_MINIBUF_WINDOW (sf);
7130 f = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
7131
7132 /* A null message buffer means that the frame hasn't really been
7133 initialized yet. Error messages get reported properly by
7134 cmd_error, so this must be just an informative message; toss
7135 it. */
7136 if (FRAME_MESSAGE_BUF (f))
7137 {
7138 if (m)
7139 {
7140 int len;
7141 #ifdef NO_ARG_ARRAY
7142 char *a[3];
7143 a[0] = (char *) a1;
7144 a[1] = (char *) a2;
7145 a[2] = (char *) a3;
7146
7147 len = doprnt (FRAME_MESSAGE_BUF (f),
7148 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3, a);
7149 #else
7150 len = doprnt (FRAME_MESSAGE_BUF (f),
7151 FRAME_MESSAGE_BUF_SIZE (f), m, (char *)0, 3,
7152 (char **) &a1);
7153 #endif /* NO_ARG_ARRAY */
7154
7155 message2 (FRAME_MESSAGE_BUF (f), len, 0);
7156 }
7157 else
7158 message1 (0);
7159
7160 /* Print should start at the beginning of the message
7161 buffer next time. */
7162 message_buf_print = 0;
7163 }
7164 }
7165 }
7166
7167
7168 /* The non-logging version of message. */
7169
7170 void
7171 message_nolog (m, a1, a2, a3)
7172 char *m;
7173 EMACS_INT a1, a2, a3;
7174 {
7175 Lisp_Object old_log_max;
7176 old_log_max = Vmessage_log_max;
7177 Vmessage_log_max = Qnil;
7178 message (m, a1, a2, a3);
7179 Vmessage_log_max = old_log_max;
7180 }
7181
7182
7183 /* Display the current message in the current mini-buffer. This is
7184 only called from error handlers in process.c, and is not time
7185 critical. */
7186
7187 void
7188 update_echo_area ()
7189 {
7190 if (!NILP (echo_area_buffer[0]))
7191 {
7192 Lisp_Object string;
7193 string = Fcurrent_message ();
7194 message3 (string, SBYTES (string),
7195 !NILP (current_buffer->enable_multibyte_characters));
7196 }
7197 }
7198
7199
7200 /* Make sure echo area buffers in `echo_buffers' are live.
7201 If they aren't, make new ones. */
7202
7203 static void
7204 ensure_echo_area_buffers ()
7205 {
7206 int i;
7207
7208 for (i = 0; i < 2; ++i)
7209 if (!BUFFERP (echo_buffer[i])
7210 || NILP (XBUFFER (echo_buffer[i])->name))
7211 {
7212 char name[30];
7213 Lisp_Object old_buffer;
7214 int j;
7215
7216 old_buffer = echo_buffer[i];
7217 sprintf (name, " *Echo Area %d*", i);
7218 echo_buffer[i] = Fget_buffer_create (build_string (name));
7219 XBUFFER (echo_buffer[i])->truncate_lines = Qnil;
7220
7221 for (j = 0; j < 2; ++j)
7222 if (EQ (old_buffer, echo_area_buffer[j]))
7223 echo_area_buffer[j] = echo_buffer[i];
7224 }
7225 }
7226
7227
7228 /* Call FN with args A1..A4 with either the current or last displayed
7229 echo_area_buffer as current buffer.
7230
7231 WHICH zero means use the current message buffer
7232 echo_area_buffer[0]. If that is nil, choose a suitable buffer
7233 from echo_buffer[] and clear it.
7234
7235 WHICH > 0 means use echo_area_buffer[1]. If that is nil, choose a
7236 suitable buffer from echo_buffer[] and clear it.
7237
7238 Value is what FN returns. */
7239
7240 static int
7241 with_echo_area_buffer (w, which, fn, a1, a2, a3, a4)
7242 struct window *w;
7243 int which;
7244 int (*fn) P_ ((EMACS_INT, Lisp_Object, EMACS_INT, EMACS_INT));
7245 EMACS_INT a1;
7246 Lisp_Object a2;
7247 EMACS_INT a3, a4;
7248 {
7249 Lisp_Object buffer;
7250 int this_one, the_other, clear_buffer_p, rc;
7251 int count = SPECPDL_INDEX ();
7252
7253 /* If buffers aren't live, make new ones. */
7254 ensure_echo_area_buffers ();
7255
7256 clear_buffer_p = 0;
7257
7258 if (which == 0)
7259 this_one = 0, the_other = 1;
7260 else if (which > 0)
7261 this_one = 1, the_other = 0;
7262
7263 /* Choose a suitable buffer from echo_buffer[] is we don't
7264 have one. */
7265 if (NILP (echo_area_buffer[this_one]))
7266 {
7267 echo_area_buffer[this_one]
7268 = (EQ (echo_area_buffer[the_other], echo_buffer[this_one])
7269 ? echo_buffer[the_other]
7270 : echo_buffer[this_one]);
7271 clear_buffer_p = 1;
7272 }
7273
7274 buffer = echo_area_buffer[this_one];
7275
7276 /* Don't get confused by reusing the buffer used for echoing
7277 for a different purpose. */
7278 if (echo_kboard == NULL && EQ (buffer, echo_message_buffer))
7279 cancel_echoing ();
7280
7281 record_unwind_protect (unwind_with_echo_area_buffer,
7282 with_echo_area_buffer_unwind_data (w));
7283
7284 /* Make the echo area buffer current. Note that for display
7285 purposes, it is not necessary that the displayed window's buffer
7286 == current_buffer, except for text property lookup. So, let's
7287 only set that buffer temporarily here without doing a full
7288 Fset_window_buffer. We must also change w->pointm, though,
7289 because otherwise an assertions in unshow_buffer fails, and Emacs
7290 aborts. */
7291 set_buffer_internal_1 (XBUFFER (buffer));
7292 if (w)
7293 {
7294 w->buffer = buffer;
7295 set_marker_both (w->pointm, buffer, BEG, BEG_BYTE);
7296 }
7297
7298 current_buffer->undo_list = Qt;
7299 current_buffer->read_only = Qnil;
7300 specbind (Qinhibit_read_only, Qt);
7301 specbind (Qinhibit_modification_hooks, Qt);
7302
7303 if (clear_buffer_p && Z > BEG)
7304 del_range (BEG, Z);
7305
7306 xassert (BEGV >= BEG);
7307 xassert (ZV <= Z && ZV >= BEGV);
7308
7309 rc = fn (a1, a2, a3, a4);
7310
7311 xassert (BEGV >= BEG);
7312 xassert (ZV <= Z && ZV >= BEGV);
7313
7314 unbind_to (count, Qnil);
7315 return rc;
7316 }
7317
7318
7319 /* Save state that should be preserved around the call to the function
7320 FN called in with_echo_area_buffer. */
7321
7322 static Lisp_Object
7323 with_echo_area_buffer_unwind_data (w)
7324 struct window *w;
7325 {
7326 int i = 0;
7327 Lisp_Object vector;
7328
7329 /* Reduce consing by keeping one vector in
7330 Vwith_echo_area_save_vector. */
7331 vector = Vwith_echo_area_save_vector;
7332 Vwith_echo_area_save_vector = Qnil;
7333
7334 if (NILP (vector))
7335 vector = Fmake_vector (make_number (7), Qnil);
7336
7337 XSETBUFFER (AREF (vector, i), current_buffer); ++i;
7338 AREF (vector, i) = Vdeactivate_mark, ++i;
7339 AREF (vector, i) = make_number (windows_or_buffers_changed), ++i;
7340
7341 if (w)
7342 {
7343 XSETWINDOW (AREF (vector, i), w); ++i;
7344 AREF (vector, i) = w->buffer; ++i;
7345 AREF (vector, i) = make_number (XMARKER (w->pointm)->charpos); ++i;
7346 AREF (vector, i) = make_number (XMARKER (w->pointm)->bytepos); ++i;
7347 }
7348 else
7349 {
7350 int end = i + 4;
7351 for (; i < end; ++i)
7352 AREF (vector, i) = Qnil;
7353 }
7354
7355 xassert (i == ASIZE (vector));
7356 return vector;
7357 }
7358
7359
7360 /* Restore global state from VECTOR which was created by
7361 with_echo_area_buffer_unwind_data. */
7362
7363 static Lisp_Object
7364 unwind_with_echo_area_buffer (vector)
7365 Lisp_Object vector;
7366 {
7367 set_buffer_internal_1 (XBUFFER (AREF (vector, 0)));
7368 Vdeactivate_mark = AREF (vector, 1);
7369 windows_or_buffers_changed = XFASTINT (AREF (vector, 2));
7370
7371 if (WINDOWP (AREF (vector, 3)))
7372 {
7373 struct window *w;
7374 Lisp_Object buffer, charpos, bytepos;
7375
7376 w = XWINDOW (AREF (vector, 3));
7377 buffer = AREF (vector, 4);
7378 charpos = AREF (vector, 5);
7379 bytepos = AREF (vector, 6);
7380
7381 w->buffer = buffer;
7382 set_marker_both (w->pointm, buffer,
7383 XFASTINT (charpos), XFASTINT (bytepos));
7384 }
7385
7386 Vwith_echo_area_save_vector = vector;
7387 return Qnil;
7388 }
7389
7390
7391 /* Set up the echo area for use by print functions. MULTIBYTE_P
7392 non-zero means we will print multibyte. */
7393
7394 void
7395 setup_echo_area_for_printing (multibyte_p)
7396 int multibyte_p;
7397 {
7398 /* If we can't find an echo area any more, exit. */
7399 if (! FRAME_LIVE_P (XFRAME (selected_frame)))
7400 Fkill_emacs (Qnil);
7401
7402 ensure_echo_area_buffers ();
7403
7404 if (!message_buf_print)
7405 {
7406 /* A message has been output since the last time we printed.
7407 Choose a fresh echo area buffer. */
7408 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7409 echo_area_buffer[0] = echo_buffer[1];
7410 else
7411 echo_area_buffer[0] = echo_buffer[0];
7412
7413 /* Switch to that buffer and clear it. */
7414 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7415 current_buffer->truncate_lines = Qnil;
7416
7417 if (Z > BEG)
7418 {
7419 int count = SPECPDL_INDEX ();
7420 specbind (Qinhibit_read_only, Qt);
7421 /* Note that undo recording is always disabled. */
7422 del_range (BEG, Z);
7423 unbind_to (count, Qnil);
7424 }
7425 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7426
7427 /* Set up the buffer for the multibyteness we need. */
7428 if (multibyte_p
7429 != !NILP (current_buffer->enable_multibyte_characters))
7430 Fset_buffer_multibyte (multibyte_p ? Qt : Qnil);
7431
7432 /* Raise the frame containing the echo area. */
7433 if (minibuffer_auto_raise)
7434 {
7435 struct frame *sf = SELECTED_FRAME ();
7436 Lisp_Object mini_window;
7437 mini_window = FRAME_MINIBUF_WINDOW (sf);
7438 Fraise_frame (WINDOW_FRAME (XWINDOW (mini_window)));
7439 }
7440
7441 message_log_maybe_newline ();
7442 message_buf_print = 1;
7443 }
7444 else
7445 {
7446 if (NILP (echo_area_buffer[0]))
7447 {
7448 if (EQ (echo_area_buffer[1], echo_buffer[0]))
7449 echo_area_buffer[0] = echo_buffer[1];
7450 else
7451 echo_area_buffer[0] = echo_buffer[0];
7452 }
7453
7454 if (current_buffer != XBUFFER (echo_area_buffer[0]))
7455 {
7456 /* Someone switched buffers between print requests. */
7457 set_buffer_internal (XBUFFER (echo_area_buffer[0]));
7458 current_buffer->truncate_lines = Qnil;
7459 }
7460 }
7461 }
7462
7463
7464 /* Display an echo area message in window W. Value is non-zero if W's
7465 height is changed. If display_last_displayed_message_p is
7466 non-zero, display the message that was last displayed, otherwise
7467 display the current message. */
7468
7469 static int
7470 display_echo_area (w)
7471 struct window *w;
7472 {
7473 int i, no_message_p, window_height_changed_p, count;
7474
7475 /* Temporarily disable garbage collections while displaying the echo
7476 area. This is done because a GC can print a message itself.
7477 That message would modify the echo area buffer's contents while a
7478 redisplay of the buffer is going on, and seriously confuse
7479 redisplay. */
7480 count = inhibit_garbage_collection ();
7481
7482 /* If there is no message, we must call display_echo_area_1
7483 nevertheless because it resizes the window. But we will have to
7484 reset the echo_area_buffer in question to nil at the end because
7485 with_echo_area_buffer will sets it to an empty buffer. */
7486 i = display_last_displayed_message_p ? 1 : 0;
7487 no_message_p = NILP (echo_area_buffer[i]);
7488
7489 window_height_changed_p
7490 = with_echo_area_buffer (w, display_last_displayed_message_p,
7491 display_echo_area_1,
7492 (EMACS_INT) w, Qnil, 0, 0);
7493
7494 if (no_message_p)
7495 echo_area_buffer[i] = Qnil;
7496
7497 unbind_to (count, Qnil);
7498 return window_height_changed_p;
7499 }
7500
7501
7502 /* Helper for display_echo_area. Display the current buffer which
7503 contains the current echo area message in window W, a mini-window,
7504 a pointer to which is passed in A1. A2..A4 are currently not used.
7505 Change the height of W so that all of the message is displayed.
7506 Value is non-zero if height of W was changed. */
7507
7508 static int
7509 display_echo_area_1 (a1, a2, a3, a4)
7510 EMACS_INT a1;
7511 Lisp_Object a2;
7512 EMACS_INT a3, a4;
7513 {
7514 struct window *w = (struct window *) a1;
7515 Lisp_Object window;
7516 struct text_pos start;
7517 int window_height_changed_p = 0;
7518
7519 /* Do this before displaying, so that we have a large enough glyph
7520 matrix for the display. */
7521 window_height_changed_p = resize_mini_window (w, 0);
7522
7523 /* Display. */
7524 clear_glyph_matrix (w->desired_matrix);
7525 XSETWINDOW (window, w);
7526 SET_TEXT_POS (start, BEG, BEG_BYTE);
7527 try_window (window, start);
7528
7529 return window_height_changed_p;
7530 }
7531
7532
7533 /* Resize the echo area window to exactly the size needed for the
7534 currently displayed message, if there is one. If a mini-buffer
7535 is active, don't shrink it. */
7536
7537 void
7538 resize_echo_area_exactly ()
7539 {
7540 if (BUFFERP (echo_area_buffer[0])
7541 && WINDOWP (echo_area_window))
7542 {
7543 struct window *w = XWINDOW (echo_area_window);
7544 int resized_p;
7545 Lisp_Object resize_exactly;
7546
7547 if (minibuf_level == 0)
7548 resize_exactly = Qt;
7549 else
7550 resize_exactly = Qnil;
7551
7552 resized_p = with_echo_area_buffer (w, 0, resize_mini_window_1,
7553 (EMACS_INT) w, resize_exactly, 0, 0);
7554 if (resized_p)
7555 {
7556 ++windows_or_buffers_changed;
7557 ++update_mode_lines;
7558 redisplay_internal (0);
7559 }
7560 }
7561 }
7562
7563
7564 /* Callback function for with_echo_area_buffer, when used from
7565 resize_echo_area_exactly. A1 contains a pointer to the window to
7566 resize, EXACTLY non-nil means resize the mini-window exactly to the
7567 size of the text displayed. A3 and A4 are not used. Value is what
7568 resize_mini_window returns. */
7569
7570 static int
7571 resize_mini_window_1 (a1, exactly, a3, a4)
7572 EMACS_INT a1;
7573 Lisp_Object exactly;
7574 EMACS_INT a3, a4;
7575 {
7576 return resize_mini_window ((struct window *) a1, !NILP (exactly));
7577 }
7578
7579
7580 /* Resize mini-window W to fit the size of its contents. EXACT:P
7581 means size the window exactly to the size needed. Otherwise, it's
7582 only enlarged until W's buffer is empty. Value is non-zero if
7583 the window height has been changed. */
7584
7585 int
7586 resize_mini_window (w, exact_p)
7587 struct window *w;
7588 int exact_p;
7589 {
7590 struct frame *f = XFRAME (w->frame);
7591 int window_height_changed_p = 0;
7592
7593 xassert (MINI_WINDOW_P (w));
7594
7595 /* Don't resize windows while redisplaying a window; it would
7596 confuse redisplay functions when the size of the window they are
7597 displaying changes from under them. Such a resizing can happen,
7598 for instance, when which-func prints a long message while
7599 we are running fontification-functions. We're running these
7600 functions with safe_call which binds inhibit-redisplay to t. */
7601 if (!NILP (Vinhibit_redisplay))
7602 return 0;
7603
7604 /* Nil means don't try to resize. */
7605 if (NILP (Vresize_mini_windows)
7606 || (FRAME_X_P (f) && FRAME_X_OUTPUT (f) == NULL))
7607 return 0;
7608
7609 if (!FRAME_MINIBUF_ONLY_P (f))
7610 {
7611 struct it it;
7612 struct window *root = XWINDOW (FRAME_ROOT_WINDOW (f));
7613 int total_height = WINDOW_TOTAL_LINES (root) + WINDOW_TOTAL_LINES (w);
7614 int height, max_height;
7615 int unit = FRAME_LINE_HEIGHT (f);
7616 struct text_pos start;
7617 struct buffer *old_current_buffer = NULL;
7618
7619 if (current_buffer != XBUFFER (w->buffer))
7620 {
7621 old_current_buffer = current_buffer;
7622 set_buffer_internal (XBUFFER (w->buffer));
7623 }
7624
7625 init_iterator (&it, w, BEGV, BEGV_BYTE, NULL, DEFAULT_FACE_ID);
7626
7627 /* Compute the max. number of lines specified by the user. */
7628 if (FLOATP (Vmax_mini_window_height))
7629 max_height = XFLOATINT (Vmax_mini_window_height) * FRAME_LINES (f);
7630 else if (INTEGERP (Vmax_mini_window_height))
7631 max_height = XINT (Vmax_mini_window_height);
7632 else
7633 max_height = total_height / 4;
7634
7635 /* Correct that max. height if it's bogus. */
7636 max_height = max (1, max_height);
7637 max_height = min (total_height, max_height);
7638
7639 /* Find out the height of the text in the window. */
7640 if (it.truncate_lines_p)
7641 height = 1;
7642 else
7643 {
7644 last_height = 0;
7645 move_it_to (&it, ZV, -1, -1, -1, MOVE_TO_POS);
7646 if (it.max_ascent == 0 && it.max_descent == 0)
7647 height = it.current_y + last_height;
7648 else
7649 height = it.current_y + it.max_ascent + it.max_descent;
7650 height -= min (it.extra_line_spacing, it.max_extra_line_spacing);
7651 height = (height + unit - 1) / unit;
7652 }
7653
7654 /* Compute a suitable window start. */
7655 if (height > max_height)
7656 {
7657 height = max_height;
7658 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
7659 move_it_vertically_backward (&it, (height - 1) * unit);
7660 start = it.current.pos;
7661 }
7662 else
7663 SET_TEXT_POS (start, BEGV, BEGV_BYTE);
7664 SET_MARKER_FROM_TEXT_POS (w->start, start);
7665
7666 if (EQ (Vresize_mini_windows, Qgrow_only))
7667 {
7668 /* Let it grow only, until we display an empty message, in which
7669 case the window shrinks again. */
7670 if (height > WINDOW_TOTAL_LINES (w))
7671 {
7672 int old_height = WINDOW_TOTAL_LINES (w);
7673 freeze_window_starts (f, 1);
7674 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7675 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7676 }
7677 else if (height < WINDOW_TOTAL_LINES (w)
7678 && (exact_p || BEGV == ZV))
7679 {
7680 int old_height = WINDOW_TOTAL_LINES (w);
7681 freeze_window_starts (f, 0);
7682 shrink_mini_window (w);
7683 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7684 }
7685 }
7686 else
7687 {
7688 /* Always resize to exact size needed. */
7689 if (height > WINDOW_TOTAL_LINES (w))
7690 {
7691 int old_height = WINDOW_TOTAL_LINES (w);
7692 freeze_window_starts (f, 1);
7693 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7694 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7695 }
7696 else if (height < WINDOW_TOTAL_LINES (w))
7697 {
7698 int old_height = WINDOW_TOTAL_LINES (w);
7699 freeze_window_starts (f, 0);
7700 shrink_mini_window (w);
7701
7702 if (height)
7703 {
7704 freeze_window_starts (f, 1);
7705 grow_mini_window (w, height - WINDOW_TOTAL_LINES (w));
7706 }
7707
7708 window_height_changed_p = WINDOW_TOTAL_LINES (w) != old_height;
7709 }
7710 }
7711
7712 if (old_current_buffer)
7713 set_buffer_internal (old_current_buffer);
7714 }
7715
7716 return window_height_changed_p;
7717 }
7718
7719
7720 /* Value is the current message, a string, or nil if there is no
7721 current message. */
7722
7723 Lisp_Object
7724 current_message ()
7725 {
7726 Lisp_Object msg;
7727
7728 if (NILP (echo_area_buffer[0]))
7729 msg = Qnil;
7730 else
7731 {
7732 with_echo_area_buffer (0, 0, current_message_1,
7733 (EMACS_INT) &msg, Qnil, 0, 0);
7734 if (NILP (msg))
7735 echo_area_buffer[0] = Qnil;
7736 }
7737
7738 return msg;
7739 }
7740
7741
7742 static int
7743 current_message_1 (a1, a2, a3, a4)
7744 EMACS_INT a1;
7745 Lisp_Object a2;
7746 EMACS_INT a3, a4;
7747 {
7748 Lisp_Object *msg = (Lisp_Object *) a1;
7749
7750 if (Z > BEG)
7751 *msg = make_buffer_string (BEG, Z, 1);
7752 else
7753 *msg = Qnil;
7754 return 0;
7755 }
7756
7757
7758 /* Push the current message on Vmessage_stack for later restauration
7759 by restore_message. Value is non-zero if the current message isn't
7760 empty. This is a relatively infrequent operation, so it's not
7761 worth optimizing. */
7762
7763 int
7764 push_message ()
7765 {
7766 Lisp_Object msg;
7767 msg = current_message ();
7768 Vmessage_stack = Fcons (msg, Vmessage_stack);
7769 return STRINGP (msg);
7770 }
7771
7772
7773 /* Restore message display from the top of Vmessage_stack. */
7774
7775 void
7776 restore_message ()
7777 {
7778 Lisp_Object msg;
7779
7780 xassert (CONSP (Vmessage_stack));
7781 msg = XCAR (Vmessage_stack);
7782 if (STRINGP (msg))
7783 message3_nolog (msg, SBYTES (msg), STRING_MULTIBYTE (msg));
7784 else
7785 message3_nolog (msg, 0, 0);
7786 }
7787
7788
7789 /* Handler for record_unwind_protect calling pop_message. */
7790
7791 Lisp_Object
7792 pop_message_unwind (dummy)
7793 Lisp_Object dummy;
7794 {
7795 pop_message ();
7796 return Qnil;
7797 }
7798
7799 /* Pop the top-most entry off Vmessage_stack. */
7800
7801 void
7802 pop_message ()
7803 {
7804 xassert (CONSP (Vmessage_stack));
7805 Vmessage_stack = XCDR (Vmessage_stack);
7806 }
7807
7808
7809 /* Check that Vmessage_stack is nil. Called from emacs.c when Emacs
7810 exits. If the stack is not empty, we have a missing pop_message
7811 somewhere. */
7812
7813 void
7814 check_message_stack ()
7815 {
7816 if (!NILP (Vmessage_stack))
7817 abort ();
7818 }
7819
7820
7821 /* Truncate to NCHARS what will be displayed in the echo area the next
7822 time we display it---but don't redisplay it now. */
7823
7824 void
7825 truncate_echo_area (nchars)
7826 int nchars;
7827 {
7828 if (nchars == 0)
7829 echo_area_buffer[0] = Qnil;
7830 /* A null message buffer means that the frame hasn't really been
7831 initialized yet. Error messages get reported properly by
7832 cmd_error, so this must be just an informative message; toss it. */
7833 else if (!noninteractive
7834 && INTERACTIVE
7835 && !NILP (echo_area_buffer[0]))
7836 {
7837 struct frame *sf = SELECTED_FRAME ();
7838 if (FRAME_MESSAGE_BUF (sf))
7839 with_echo_area_buffer (0, 0, truncate_message_1, nchars, Qnil, 0, 0);
7840 }
7841 }
7842
7843
7844 /* Helper function for truncate_echo_area. Truncate the current
7845 message to at most NCHARS characters. */
7846
7847 static int
7848 truncate_message_1 (nchars, a2, a3, a4)
7849 EMACS_INT nchars;
7850 Lisp_Object a2;
7851 EMACS_INT a3, a4;
7852 {
7853 if (BEG + nchars < Z)
7854 del_range (BEG + nchars, Z);
7855 if (Z == BEG)
7856 echo_area_buffer[0] = Qnil;
7857 return 0;
7858 }
7859
7860
7861 /* Set the current message to a substring of S or STRING.
7862
7863 If STRING is a Lisp string, set the message to the first NBYTES
7864 bytes from STRING. NBYTES zero means use the whole string. If
7865 STRING is multibyte, the message will be displayed multibyte.
7866
7867 If S is not null, set the message to the first LEN bytes of S. LEN
7868 zero means use the whole string. MULTIBYTE_P non-zero means S is
7869 multibyte. Display the message multibyte in that case. */
7870
7871 void
7872 set_message (s, string, nbytes, multibyte_p)
7873 const char *s;
7874 Lisp_Object string;
7875 int nbytes, multibyte_p;
7876 {
7877 message_enable_multibyte
7878 = ((s && multibyte_p)
7879 || (STRINGP (string) && STRING_MULTIBYTE (string)));
7880
7881 with_echo_area_buffer (0, 0, set_message_1,
7882 (EMACS_INT) s, string, nbytes, multibyte_p);
7883 message_buf_print = 0;
7884 help_echo_showing_p = 0;
7885 }
7886
7887
7888 /* Helper function for set_message. Arguments have the same meaning
7889 as there, with A1 corresponding to S and A2 corresponding to STRING
7890 This function is called with the echo area buffer being
7891 current. */
7892
7893 static int
7894 set_message_1 (a1, a2, nbytes, multibyte_p)
7895 EMACS_INT a1;
7896 Lisp_Object a2;
7897 EMACS_INT nbytes, multibyte_p;
7898 {
7899 const char *s = (const char *) a1;
7900 Lisp_Object string = a2;
7901
7902 /* Change multibyteness of the echo buffer appropriately. */
7903 if (message_enable_multibyte
7904 != !NILP (current_buffer->enable_multibyte_characters))
7905 Fset_buffer_multibyte (message_enable_multibyte ? Qt : Qnil);
7906
7907 current_buffer->truncate_lines = message_truncate_lines ? Qt : Qnil;
7908
7909 /* Insert new message at BEG. */
7910 TEMP_SET_PT_BOTH (BEG, BEG_BYTE);
7911 Ferase_buffer ();
7912
7913 if (STRINGP (string))
7914 {
7915 int nchars;
7916
7917 if (nbytes == 0)
7918 nbytes = SBYTES (string);
7919 nchars = string_byte_to_char (string, nbytes);
7920
7921 /* This function takes care of single/multibyte conversion. We
7922 just have to ensure that the echo area buffer has the right
7923 setting of enable_multibyte_characters. */
7924 insert_from_string (string, 0, 0, nchars, nbytes, 1);
7925 }
7926 else if (s)
7927 {
7928 if (nbytes == 0)
7929 nbytes = strlen (s);
7930
7931 if (multibyte_p && NILP (current_buffer->enable_multibyte_characters))
7932 {
7933 /* Convert from multi-byte to single-byte. */
7934 int i, c, n;
7935 unsigned char work[1];
7936
7937 /* Convert a multibyte string to single-byte. */
7938 for (i = 0; i < nbytes; i += n)
7939 {
7940 c = string_char_and_length (s + i, nbytes - i, &n);
7941 work[0] = (SINGLE_BYTE_CHAR_P (c)
7942 ? c
7943 : multibyte_char_to_unibyte (c, Qnil));
7944 insert_1_both (work, 1, 1, 1, 0, 0);
7945 }
7946 }
7947 else if (!multibyte_p
7948 && !NILP (current_buffer->enable_multibyte_characters))
7949 {
7950 /* Convert from single-byte to multi-byte. */
7951 int i, c, n;
7952 const unsigned char *msg = (const unsigned char *) s;
7953 unsigned char str[MAX_MULTIBYTE_LENGTH];
7954
7955 /* Convert a single-byte string to multibyte. */
7956 for (i = 0; i < nbytes; i++)
7957 {
7958 c = unibyte_char_to_multibyte (msg[i]);
7959 n = CHAR_STRING (c, str);
7960 insert_1_both (str, 1, n, 1, 0, 0);
7961 }
7962 }
7963 else
7964 insert_1 (s, nbytes, 1, 0, 0);
7965 }
7966
7967 return 0;
7968 }
7969
7970
7971 /* Clear messages. CURRENT_P non-zero means clear the current
7972 message. LAST_DISPLAYED_P non-zero means clear the message
7973 last displayed. */
7974
7975 void
7976 clear_message (current_p, last_displayed_p)
7977 int current_p, last_displayed_p;
7978 {
7979 if (current_p)
7980 {
7981 echo_area_buffer[0] = Qnil;
7982 message_cleared_p = 1;
7983 }
7984
7985 if (last_displayed_p)
7986 echo_area_buffer[1] = Qnil;
7987
7988 message_buf_print = 0;
7989 }
7990
7991 /* Clear garbaged frames.
7992
7993 This function is used where the old redisplay called
7994 redraw_garbaged_frames which in turn called redraw_frame which in
7995 turn called clear_frame. The call to clear_frame was a source of
7996 flickering. I believe a clear_frame is not necessary. It should
7997 suffice in the new redisplay to invalidate all current matrices,
7998 and ensure a complete redisplay of all windows. */
7999
8000 static void
8001 clear_garbaged_frames ()
8002 {
8003 if (frame_garbaged)
8004 {
8005 Lisp_Object tail, frame;
8006 int changed_count = 0;
8007
8008 FOR_EACH_FRAME (tail, frame)
8009 {
8010 struct frame *f = XFRAME (frame);
8011
8012 if (FRAME_VISIBLE_P (f) && FRAME_GARBAGED_P (f))
8013 {
8014 if (f->resized_p)
8015 {
8016 Fredraw_frame (frame);
8017 f->force_flush_display_p = 1;
8018 }
8019 clear_current_matrices (f);
8020 changed_count++;
8021 f->garbaged = 0;
8022 f->resized_p = 0;
8023 }
8024 }
8025
8026 frame_garbaged = 0;
8027 if (changed_count)
8028 ++windows_or_buffers_changed;
8029 }
8030 }
8031
8032
8033 /* Redisplay the echo area of the selected frame. If UPDATE_FRAME_P
8034 is non-zero update selected_frame. Value is non-zero if the
8035 mini-windows height has been changed. */
8036
8037 static int
8038 echo_area_display (update_frame_p)
8039 int update_frame_p;
8040 {
8041 Lisp_Object mini_window;
8042 struct window *w;
8043 struct frame *f;
8044 int window_height_changed_p = 0;
8045 struct frame *sf = SELECTED_FRAME ();
8046
8047 mini_window = FRAME_MINIBUF_WINDOW (sf);
8048 w = XWINDOW (mini_window);
8049 f = XFRAME (WINDOW_FRAME (w));
8050
8051 /* Don't display if frame is invisible or not yet initialized. */
8052 if (!FRAME_VISIBLE_P (f) || !f->glyphs_initialized_p)
8053 return 0;
8054
8055 /* The terminal frame is used as the first Emacs frame on the Mac OS. */
8056 #ifndef MAC_OS8
8057 #ifdef HAVE_WINDOW_SYSTEM
8058 /* When Emacs starts, selected_frame may be a visible terminal
8059 frame, even if we run under a window system. If we let this
8060 through, a message would be displayed on the terminal. */
8061 if (EQ (selected_frame, Vterminal_frame)
8062 && !NILP (Vwindow_system))
8063 return 0;
8064 #endif /* HAVE_WINDOW_SYSTEM */
8065 #endif
8066
8067 /* Redraw garbaged frames. */
8068 if (frame_garbaged)
8069 clear_garbaged_frames ();
8070
8071 if (!NILP (echo_area_buffer[0]) || minibuf_level == 0)
8072 {
8073 echo_area_window = mini_window;
8074 window_height_changed_p = display_echo_area (w);
8075 w->must_be_updated_p = 1;
8076
8077 /* Update the display, unless called from redisplay_internal.
8078 Also don't update the screen during redisplay itself. The
8079 update will happen at the end of redisplay, and an update
8080 here could cause confusion. */
8081 if (update_frame_p && !redisplaying_p)
8082 {
8083 int n = 0;
8084
8085 /* If the display update has been interrupted by pending
8086 input, update mode lines in the frame. Due to the
8087 pending input, it might have been that redisplay hasn't
8088 been called, so that mode lines above the echo area are
8089 garbaged. This looks odd, so we prevent it here. */
8090 if (!display_completed)
8091 n = redisplay_mode_lines (FRAME_ROOT_WINDOW (f), 0);
8092
8093 if (window_height_changed_p
8094 /* Don't do this if Emacs is shutting down. Redisplay
8095 needs to run hooks. */
8096 && !NILP (Vrun_hooks))
8097 {
8098 /* Must update other windows. Likewise as in other
8099 cases, don't let this update be interrupted by
8100 pending input. */
8101 int count = SPECPDL_INDEX ();
8102 specbind (Qredisplay_dont_pause, Qt);
8103 windows_or_buffers_changed = 1;
8104 redisplay_internal (0);
8105 unbind_to (count, Qnil);
8106 }
8107 else if (FRAME_WINDOW_P (f) && n == 0)
8108 {
8109 /* Window configuration is the same as before.
8110 Can do with a display update of the echo area,
8111 unless we displayed some mode lines. */
8112 update_single_window (w, 1);
8113 rif->flush_display (f);
8114 }
8115 else
8116 update_frame (f, 1, 1);
8117
8118 /* If cursor is in the echo area, make sure that the next
8119 redisplay displays the minibuffer, so that the cursor will
8120 be replaced with what the minibuffer wants. */
8121 if (cursor_in_echo_area)
8122 ++windows_or_buffers_changed;
8123 }
8124 }
8125 else if (!EQ (mini_window, selected_window))
8126 windows_or_buffers_changed++;
8127
8128 /* The current message is now also the last one displayed. */
8129 echo_area_buffer[1] = echo_area_buffer[0];
8130
8131 /* Prevent redisplay optimization in redisplay_internal by resetting
8132 this_line_start_pos. This is done because the mini-buffer now
8133 displays the message instead of its buffer text. */
8134 if (EQ (mini_window, selected_window))
8135 CHARPOS (this_line_start_pos) = 0;
8136
8137 return window_height_changed_p;
8138 }
8139
8140
8141 \f
8142 /***********************************************************************
8143 Frame Titles
8144 ***********************************************************************/
8145
8146
8147 /* The frame title buffering code is also used by Fformat_mode_line.
8148 So it is not conditioned by HAVE_WINDOW_SYSTEM. */
8149
8150 /* A buffer for constructing frame titles in it; allocated from the
8151 heap in init_xdisp and resized as needed in store_frame_title_char. */
8152
8153 static char *frame_title_buf;
8154
8155 /* The buffer's end, and a current output position in it. */
8156
8157 static char *frame_title_buf_end;
8158 static char *frame_title_ptr;
8159
8160
8161 /* Store a single character C for the frame title in frame_title_buf.
8162 Re-allocate frame_title_buf if necessary. */
8163
8164 static void
8165 #ifdef PROTOTYPES
8166 store_frame_title_char (char c)
8167 #else
8168 store_frame_title_char (c)
8169 char c;
8170 #endif
8171 {
8172 /* If output position has reached the end of the allocated buffer,
8173 double the buffer's size. */
8174 if (frame_title_ptr == frame_title_buf_end)
8175 {
8176 int len = frame_title_ptr - frame_title_buf;
8177 int new_size = 2 * len * sizeof *frame_title_buf;
8178 frame_title_buf = (char *) xrealloc (frame_title_buf, new_size);
8179 frame_title_buf_end = frame_title_buf + new_size;
8180 frame_title_ptr = frame_title_buf + len;
8181 }
8182
8183 *frame_title_ptr++ = c;
8184 }
8185
8186
8187 /* Store part of a frame title in frame_title_buf, beginning at
8188 frame_title_ptr. STR is the string to store. Do not copy
8189 characters that yield more columns than PRECISION; PRECISION <= 0
8190 means copy the whole string. Pad with spaces until FIELD_WIDTH
8191 number of characters have been copied; FIELD_WIDTH <= 0 means don't
8192 pad. Called from display_mode_element when it is used to build a
8193 frame title. */
8194
8195 static int
8196 store_frame_title (str, field_width, precision)
8197 const unsigned char *str;
8198 int field_width, precision;
8199 {
8200 int n = 0;
8201 int dummy, nbytes;
8202
8203 /* Copy at most PRECISION chars from STR. */
8204 nbytes = strlen (str);
8205 n += c_string_width (str, nbytes, precision, &dummy, &nbytes);
8206 while (nbytes--)
8207 store_frame_title_char (*str++);
8208
8209 /* Fill up with spaces until FIELD_WIDTH reached. */
8210 while (field_width > 0
8211 && n < field_width)
8212 {
8213 store_frame_title_char (' ');
8214 ++n;
8215 }
8216
8217 return n;
8218 }
8219
8220 #ifdef HAVE_WINDOW_SYSTEM
8221
8222 /* Set the title of FRAME, if it has changed. The title format is
8223 Vicon_title_format if FRAME is iconified, otherwise it is
8224 frame_title_format. */
8225
8226 static void
8227 x_consider_frame_title (frame)
8228 Lisp_Object frame;
8229 {
8230 struct frame *f = XFRAME (frame);
8231
8232 if (FRAME_WINDOW_P (f)
8233 || FRAME_MINIBUF_ONLY_P (f)
8234 || f->explicit_name)
8235 {
8236 /* Do we have more than one visible frame on this X display? */
8237 Lisp_Object tail;
8238 Lisp_Object fmt;
8239 struct buffer *obuf;
8240 int len;
8241 struct it it;
8242
8243 for (tail = Vframe_list; CONSP (tail); tail = XCDR (tail))
8244 {
8245 Lisp_Object other_frame = XCAR (tail);
8246 struct frame *tf = XFRAME (other_frame);
8247
8248 if (tf != f
8249 && FRAME_KBOARD (tf) == FRAME_KBOARD (f)
8250 && !FRAME_MINIBUF_ONLY_P (tf)
8251 && !EQ (other_frame, tip_frame)
8252 && (FRAME_VISIBLE_P (tf) || FRAME_ICONIFIED_P (tf)))
8253 break;
8254 }
8255
8256 /* Set global variable indicating that multiple frames exist. */
8257 multiple_frames = CONSP (tail);
8258
8259 /* Switch to the buffer of selected window of the frame. Set up
8260 frame_title_ptr so that display_mode_element will output into it;
8261 then display the title. */
8262 obuf = current_buffer;
8263 set_buffer_internal_1 (XBUFFER (XWINDOW (f->selected_window)->buffer));
8264 fmt = FRAME_ICONIFIED_P (f) ? Vicon_title_format : Vframe_title_format;
8265 frame_title_ptr = frame_title_buf;
8266 init_iterator (&it, XWINDOW (f->selected_window), -1, -1,
8267 NULL, DEFAULT_FACE_ID);
8268 display_mode_element (&it, 0, -1, -1, fmt, Qnil, 0);
8269 len = frame_title_ptr - frame_title_buf;
8270 frame_title_ptr = NULL;
8271 set_buffer_internal_1 (obuf);
8272
8273 /* Set the title only if it's changed. This avoids consing in
8274 the common case where it hasn't. (If it turns out that we've
8275 already wasted too much time by walking through the list with
8276 display_mode_element, then we might need to optimize at a
8277 higher level than this.) */
8278 if (! STRINGP (f->name)
8279 || SBYTES (f->name) != len
8280 || bcmp (frame_title_buf, SDATA (f->name), len) != 0)
8281 x_implicitly_set_name (f, make_string (frame_title_buf, len), Qnil);
8282 }
8283 }
8284
8285 #endif /* not HAVE_WINDOW_SYSTEM */
8286
8287
8288
8289 \f
8290 /***********************************************************************
8291 Menu Bars
8292 ***********************************************************************/
8293
8294
8295 /* Prepare for redisplay by updating menu-bar item lists when
8296 appropriate. This can call eval. */
8297
8298 void
8299 prepare_menu_bars ()
8300 {
8301 int all_windows;
8302 struct gcpro gcpro1, gcpro2;
8303 struct frame *f;
8304 Lisp_Object tooltip_frame;
8305
8306 #ifdef HAVE_WINDOW_SYSTEM
8307 tooltip_frame = tip_frame;
8308 #else
8309 tooltip_frame = Qnil;
8310 #endif
8311
8312 /* Update all frame titles based on their buffer names, etc. We do
8313 this before the menu bars so that the buffer-menu will show the
8314 up-to-date frame titles. */
8315 #ifdef HAVE_WINDOW_SYSTEM
8316 if (windows_or_buffers_changed || update_mode_lines)
8317 {
8318 Lisp_Object tail, frame;
8319
8320 FOR_EACH_FRAME (tail, frame)
8321 {
8322 f = XFRAME (frame);
8323 if (!EQ (frame, tooltip_frame)
8324 && (FRAME_VISIBLE_P (f) || FRAME_ICONIFIED_P (f)))
8325 x_consider_frame_title (frame);
8326 }
8327 }
8328 #endif /* HAVE_WINDOW_SYSTEM */
8329
8330 /* Update the menu bar item lists, if appropriate. This has to be
8331 done before any actual redisplay or generation of display lines. */
8332 all_windows = (update_mode_lines
8333 || buffer_shared > 1
8334 || windows_or_buffers_changed);
8335 if (all_windows)
8336 {
8337 Lisp_Object tail, frame;
8338 int count = SPECPDL_INDEX ();
8339
8340 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8341
8342 FOR_EACH_FRAME (tail, frame)
8343 {
8344 f = XFRAME (frame);
8345
8346 /* Ignore tooltip frame. */
8347 if (EQ (frame, tooltip_frame))
8348 continue;
8349
8350 /* If a window on this frame changed size, report that to
8351 the user and clear the size-change flag. */
8352 if (FRAME_WINDOW_SIZES_CHANGED (f))
8353 {
8354 Lisp_Object functions;
8355
8356 /* Clear flag first in case we get an error below. */
8357 FRAME_WINDOW_SIZES_CHANGED (f) = 0;
8358 functions = Vwindow_size_change_functions;
8359 GCPRO2 (tail, functions);
8360
8361 while (CONSP (functions))
8362 {
8363 call1 (XCAR (functions), frame);
8364 functions = XCDR (functions);
8365 }
8366 UNGCPRO;
8367 }
8368
8369 GCPRO1 (tail);
8370 update_menu_bar (f, 0);
8371 #ifdef HAVE_WINDOW_SYSTEM
8372 update_tool_bar (f, 0);
8373 #endif
8374 UNGCPRO;
8375 }
8376
8377 unbind_to (count, Qnil);
8378 }
8379 else
8380 {
8381 struct frame *sf = SELECTED_FRAME ();
8382 update_menu_bar (sf, 1);
8383 #ifdef HAVE_WINDOW_SYSTEM
8384 update_tool_bar (sf, 1);
8385 #endif
8386 }
8387
8388 /* Motif needs this. See comment in xmenu.c. Turn it off when
8389 pending_menu_activation is not defined. */
8390 #ifdef USE_X_TOOLKIT
8391 pending_menu_activation = 0;
8392 #endif
8393 }
8394
8395
8396 /* Update the menu bar item list for frame F. This has to be done
8397 before we start to fill in any display lines, because it can call
8398 eval.
8399
8400 If SAVE_MATCH_DATA is non-zero, we must save and restore it here. */
8401
8402 static void
8403 update_menu_bar (f, save_match_data)
8404 struct frame *f;
8405 int save_match_data;
8406 {
8407 Lisp_Object window;
8408 register struct window *w;
8409
8410 /* If called recursively during a menu update, do nothing. This can
8411 happen when, for instance, an activate-menubar-hook causes a
8412 redisplay. */
8413 if (inhibit_menubar_update)
8414 return;
8415
8416 window = FRAME_SELECTED_WINDOW (f);
8417 w = XWINDOW (window);
8418
8419 #if 0 /* The if statement below this if statement used to include the
8420 condition !NILP (w->update_mode_line), rather than using
8421 update_mode_lines directly, and this if statement may have
8422 been added to make that condition work. Now the if
8423 statement below matches its comment, this isn't needed. */
8424 if (update_mode_lines)
8425 w->update_mode_line = Qt;
8426 #endif
8427
8428 if (FRAME_WINDOW_P (f)
8429 ?
8430 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8431 || defined (USE_GTK)
8432 FRAME_EXTERNAL_MENU_BAR (f)
8433 #else
8434 FRAME_MENU_BAR_LINES (f) > 0
8435 #endif
8436 : FRAME_MENU_BAR_LINES (f) > 0)
8437 {
8438 /* If the user has switched buffers or windows, we need to
8439 recompute to reflect the new bindings. But we'll
8440 recompute when update_mode_lines is set too; that means
8441 that people can use force-mode-line-update to request
8442 that the menu bar be recomputed. The adverse effect on
8443 the rest of the redisplay algorithm is about the same as
8444 windows_or_buffers_changed anyway. */
8445 if (windows_or_buffers_changed
8446 /* This used to test w->update_mode_line, but we believe
8447 there is no need to recompute the menu in that case. */
8448 || update_mode_lines
8449 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8450 < BUF_MODIFF (XBUFFER (w->buffer)))
8451 != !NILP (w->last_had_star))
8452 || ((!NILP (Vtransient_mark_mode)
8453 && !NILP (XBUFFER (w->buffer)->mark_active))
8454 != !NILP (w->region_showing)))
8455 {
8456 struct buffer *prev = current_buffer;
8457 int count = SPECPDL_INDEX ();
8458
8459 specbind (Qinhibit_menubar_update, Qt);
8460
8461 set_buffer_internal_1 (XBUFFER (w->buffer));
8462 if (save_match_data)
8463 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8464 if (NILP (Voverriding_local_map_menu_flag))
8465 {
8466 specbind (Qoverriding_terminal_local_map, Qnil);
8467 specbind (Qoverriding_local_map, Qnil);
8468 }
8469
8470 /* Run the Lucid hook. */
8471 safe_run_hooks (Qactivate_menubar_hook);
8472
8473 /* If it has changed current-menubar from previous value,
8474 really recompute the menu-bar from the value. */
8475 if (! NILP (Vlucid_menu_bar_dirty_flag))
8476 call0 (Qrecompute_lucid_menubar);
8477
8478 safe_run_hooks (Qmenu_bar_update_hook);
8479 FRAME_MENU_BAR_ITEMS (f) = menu_bar_items (FRAME_MENU_BAR_ITEMS (f));
8480
8481 /* Redisplay the menu bar in case we changed it. */
8482 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
8483 || defined (USE_GTK)
8484 if (FRAME_WINDOW_P (f)
8485 #if defined (MAC_OS)
8486 /* All frames on Mac OS share the same menubar. So only the
8487 selected frame should be allowed to set it. */
8488 && f == SELECTED_FRAME ()
8489 #endif
8490 )
8491 set_frame_menubar (f, 0, 0);
8492 else
8493 /* On a terminal screen, the menu bar is an ordinary screen
8494 line, and this makes it get updated. */
8495 w->update_mode_line = Qt;
8496 #else /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8497 /* In the non-toolkit version, the menu bar is an ordinary screen
8498 line, and this makes it get updated. */
8499 w->update_mode_line = Qt;
8500 #endif /* ! (USE_X_TOOLKIT || HAVE_NTGUI || MAC_OS || USE_GTK) */
8501
8502 unbind_to (count, Qnil);
8503 set_buffer_internal_1 (prev);
8504 }
8505 }
8506 }
8507
8508
8509 \f
8510 /***********************************************************************
8511 Output Cursor
8512 ***********************************************************************/
8513
8514 #ifdef HAVE_WINDOW_SYSTEM
8515
8516 /* EXPORT:
8517 Nominal cursor position -- where to draw output.
8518 HPOS and VPOS are window relative glyph matrix coordinates.
8519 X and Y are window relative pixel coordinates. */
8520
8521 struct cursor_pos output_cursor;
8522
8523
8524 /* EXPORT:
8525 Set the global variable output_cursor to CURSOR. All cursor
8526 positions are relative to updated_window. */
8527
8528 void
8529 set_output_cursor (cursor)
8530 struct cursor_pos *cursor;
8531 {
8532 output_cursor.hpos = cursor->hpos;
8533 output_cursor.vpos = cursor->vpos;
8534 output_cursor.x = cursor->x;
8535 output_cursor.y = cursor->y;
8536 }
8537
8538
8539 /* EXPORT for RIF:
8540 Set a nominal cursor position.
8541
8542 HPOS and VPOS are column/row positions in a window glyph matrix. X
8543 and Y are window text area relative pixel positions.
8544
8545 If this is done during an update, updated_window will contain the
8546 window that is being updated and the position is the future output
8547 cursor position for that window. If updated_window is null, use
8548 selected_window and display the cursor at the given position. */
8549
8550 void
8551 x_cursor_to (vpos, hpos, y, x)
8552 int vpos, hpos, y, x;
8553 {
8554 struct window *w;
8555
8556 /* If updated_window is not set, work on selected_window. */
8557 if (updated_window)
8558 w = updated_window;
8559 else
8560 w = XWINDOW (selected_window);
8561
8562 /* Set the output cursor. */
8563 output_cursor.hpos = hpos;
8564 output_cursor.vpos = vpos;
8565 output_cursor.x = x;
8566 output_cursor.y = y;
8567
8568 /* If not called as part of an update, really display the cursor.
8569 This will also set the cursor position of W. */
8570 if (updated_window == NULL)
8571 {
8572 BLOCK_INPUT;
8573 display_and_set_cursor (w, 1, hpos, vpos, x, y);
8574 if (rif->flush_display_optional)
8575 rif->flush_display_optional (SELECTED_FRAME ());
8576 UNBLOCK_INPUT;
8577 }
8578 }
8579
8580 #endif /* HAVE_WINDOW_SYSTEM */
8581
8582 \f
8583 /***********************************************************************
8584 Tool-bars
8585 ***********************************************************************/
8586
8587 #ifdef HAVE_WINDOW_SYSTEM
8588
8589 /* Where the mouse was last time we reported a mouse event. */
8590
8591 FRAME_PTR last_mouse_frame;
8592
8593 /* Tool-bar item index of the item on which a mouse button was pressed
8594 or -1. */
8595
8596 int last_tool_bar_item;
8597
8598
8599 /* Update the tool-bar item list for frame F. This has to be done
8600 before we start to fill in any display lines. Called from
8601 prepare_menu_bars. If SAVE_MATCH_DATA is non-zero, we must save
8602 and restore it here. */
8603
8604 static void
8605 update_tool_bar (f, save_match_data)
8606 struct frame *f;
8607 int save_match_data;
8608 {
8609 #ifdef USE_GTK
8610 int do_update = FRAME_EXTERNAL_TOOL_BAR (f);
8611 #else
8612 int do_update = WINDOWP (f->tool_bar_window)
8613 && WINDOW_TOTAL_LINES (XWINDOW (f->tool_bar_window)) > 0;
8614 #endif
8615
8616 if (do_update)
8617 {
8618 Lisp_Object window;
8619 struct window *w;
8620
8621 window = FRAME_SELECTED_WINDOW (f);
8622 w = XWINDOW (window);
8623
8624 /* If the user has switched buffers or windows, we need to
8625 recompute to reflect the new bindings. But we'll
8626 recompute when update_mode_lines is set too; that means
8627 that people can use force-mode-line-update to request
8628 that the menu bar be recomputed. The adverse effect on
8629 the rest of the redisplay algorithm is about the same as
8630 windows_or_buffers_changed anyway. */
8631 if (windows_or_buffers_changed
8632 || !NILP (w->update_mode_line)
8633 || update_mode_lines
8634 || ((BUF_SAVE_MODIFF (XBUFFER (w->buffer))
8635 < BUF_MODIFF (XBUFFER (w->buffer)))
8636 != !NILP (w->last_had_star))
8637 || ((!NILP (Vtransient_mark_mode)
8638 && !NILP (XBUFFER (w->buffer)->mark_active))
8639 != !NILP (w->region_showing)))
8640 {
8641 struct buffer *prev = current_buffer;
8642 int count = SPECPDL_INDEX ();
8643 Lisp_Object new_tool_bar;
8644 int new_n_tool_bar;
8645 struct gcpro gcpro1;
8646
8647 /* Set current_buffer to the buffer of the selected
8648 window of the frame, so that we get the right local
8649 keymaps. */
8650 set_buffer_internal_1 (XBUFFER (w->buffer));
8651
8652 /* Save match data, if we must. */
8653 if (save_match_data)
8654 record_unwind_protect (Fset_match_data, Fmatch_data (Qnil, Qnil));
8655
8656 /* Make sure that we don't accidentally use bogus keymaps. */
8657 if (NILP (Voverriding_local_map_menu_flag))
8658 {
8659 specbind (Qoverriding_terminal_local_map, Qnil);
8660 specbind (Qoverriding_local_map, Qnil);
8661 }
8662
8663 GCPRO1 (new_tool_bar);
8664
8665 /* Build desired tool-bar items from keymaps. */
8666 new_tool_bar = tool_bar_items (Fcopy_sequence (f->tool_bar_items),
8667 &new_n_tool_bar);
8668
8669 /* Redisplay the tool-bar if we changed it. */
8670 if (NILP (Fequal (new_tool_bar, f->tool_bar_items)))
8671 {
8672 /* Redisplay that happens asynchronously due to an expose event
8673 may access f->tool_bar_items. Make sure we update both
8674 variables within BLOCK_INPUT so no such event interrupts. */
8675 BLOCK_INPUT;
8676 f->tool_bar_items = new_tool_bar;
8677 f->n_tool_bar_items = new_n_tool_bar;
8678 w->update_mode_line = Qt;
8679 UNBLOCK_INPUT;
8680 }
8681
8682 UNGCPRO;
8683
8684 unbind_to (count, Qnil);
8685 set_buffer_internal_1 (prev);
8686 }
8687 }
8688 }
8689
8690
8691 /* Set F->desired_tool_bar_string to a Lisp string representing frame
8692 F's desired tool-bar contents. F->tool_bar_items must have
8693 been set up previously by calling prepare_menu_bars. */
8694
8695 static void
8696 build_desired_tool_bar_string (f)
8697 struct frame *f;
8698 {
8699 int i, size, size_needed;
8700 struct gcpro gcpro1, gcpro2, gcpro3;
8701 Lisp_Object image, plist, props;
8702
8703 image = plist = props = Qnil;
8704 GCPRO3 (image, plist, props);
8705
8706 /* Prepare F->desired_tool_bar_string. If we can reuse it, do so.
8707 Otherwise, make a new string. */
8708
8709 /* The size of the string we might be able to reuse. */
8710 size = (STRINGP (f->desired_tool_bar_string)
8711 ? SCHARS (f->desired_tool_bar_string)
8712 : 0);
8713
8714 /* We need one space in the string for each image. */
8715 size_needed = f->n_tool_bar_items;
8716
8717 /* Reuse f->desired_tool_bar_string, if possible. */
8718 if (size < size_needed || NILP (f->desired_tool_bar_string))
8719 f->desired_tool_bar_string = Fmake_string (make_number (size_needed),
8720 make_number (' '));
8721 else
8722 {
8723 props = list4 (Qdisplay, Qnil, Qmenu_item, Qnil);
8724 Fremove_text_properties (make_number (0), make_number (size),
8725 props, f->desired_tool_bar_string);
8726 }
8727
8728 /* Put a `display' property on the string for the images to display,
8729 put a `menu_item' property on tool-bar items with a value that
8730 is the index of the item in F's tool-bar item vector. */
8731 for (i = 0; i < f->n_tool_bar_items; ++i)
8732 {
8733 #define PROP(IDX) AREF (f->tool_bar_items, i * TOOL_BAR_ITEM_NSLOTS + (IDX))
8734
8735 int enabled_p = !NILP (PROP (TOOL_BAR_ITEM_ENABLED_P));
8736 int selected_p = !NILP (PROP (TOOL_BAR_ITEM_SELECTED_P));
8737 int hmargin, vmargin, relief, idx, end;
8738 extern Lisp_Object QCrelief, QCmargin, QCconversion;
8739
8740 /* If image is a vector, choose the image according to the
8741 button state. */
8742 image = PROP (TOOL_BAR_ITEM_IMAGES);
8743 if (VECTORP (image))
8744 {
8745 if (enabled_p)
8746 idx = (selected_p
8747 ? TOOL_BAR_IMAGE_ENABLED_SELECTED
8748 : TOOL_BAR_IMAGE_ENABLED_DESELECTED);
8749 else
8750 idx = (selected_p
8751 ? TOOL_BAR_IMAGE_DISABLED_SELECTED
8752 : TOOL_BAR_IMAGE_DISABLED_DESELECTED);
8753
8754 xassert (ASIZE (image) >= idx);
8755 image = AREF (image, idx);
8756 }
8757 else
8758 idx = -1;
8759
8760 /* Ignore invalid image specifications. */
8761 if (!valid_image_p (image))
8762 continue;
8763
8764 /* Display the tool-bar button pressed, or depressed. */
8765 plist = Fcopy_sequence (XCDR (image));
8766
8767 /* Compute margin and relief to draw. */
8768 relief = (tool_bar_button_relief >= 0
8769 ? tool_bar_button_relief
8770 : DEFAULT_TOOL_BAR_BUTTON_RELIEF);
8771 hmargin = vmargin = relief;
8772
8773 if (INTEGERP (Vtool_bar_button_margin)
8774 && XINT (Vtool_bar_button_margin) > 0)
8775 {
8776 hmargin += XFASTINT (Vtool_bar_button_margin);
8777 vmargin += XFASTINT (Vtool_bar_button_margin);
8778 }
8779 else if (CONSP (Vtool_bar_button_margin))
8780 {
8781 if (INTEGERP (XCAR (Vtool_bar_button_margin))
8782 && XINT (XCAR (Vtool_bar_button_margin)) > 0)
8783 hmargin += XFASTINT (XCAR (Vtool_bar_button_margin));
8784
8785 if (INTEGERP (XCDR (Vtool_bar_button_margin))
8786 && XINT (XCDR (Vtool_bar_button_margin)) > 0)
8787 vmargin += XFASTINT (XCDR (Vtool_bar_button_margin));
8788 }
8789
8790 if (auto_raise_tool_bar_buttons_p)
8791 {
8792 /* Add a `:relief' property to the image spec if the item is
8793 selected. */
8794 if (selected_p)
8795 {
8796 plist = Fplist_put (plist, QCrelief, make_number (-relief));
8797 hmargin -= relief;
8798 vmargin -= relief;
8799 }
8800 }
8801 else
8802 {
8803 /* If image is selected, display it pressed, i.e. with a
8804 negative relief. If it's not selected, display it with a
8805 raised relief. */
8806 plist = Fplist_put (plist, QCrelief,
8807 (selected_p
8808 ? make_number (-relief)
8809 : make_number (relief)));
8810 hmargin -= relief;
8811 vmargin -= relief;
8812 }
8813
8814 /* Put a margin around the image. */
8815 if (hmargin || vmargin)
8816 {
8817 if (hmargin == vmargin)
8818 plist = Fplist_put (plist, QCmargin, make_number (hmargin));
8819 else
8820 plist = Fplist_put (plist, QCmargin,
8821 Fcons (make_number (hmargin),
8822 make_number (vmargin)));
8823 }
8824
8825 /* If button is not enabled, and we don't have special images
8826 for the disabled state, make the image appear disabled by
8827 applying an appropriate algorithm to it. */
8828 if (!enabled_p && idx < 0)
8829 plist = Fplist_put (plist, QCconversion, Qdisabled);
8830
8831 /* Put a `display' text property on the string for the image to
8832 display. Put a `menu-item' property on the string that gives
8833 the start of this item's properties in the tool-bar items
8834 vector. */
8835 image = Fcons (Qimage, plist);
8836 props = list4 (Qdisplay, image,
8837 Qmenu_item, make_number (i * TOOL_BAR_ITEM_NSLOTS));
8838
8839 /* Let the last image hide all remaining spaces in the tool bar
8840 string. The string can be longer than needed when we reuse a
8841 previous string. */
8842 if (i + 1 == f->n_tool_bar_items)
8843 end = SCHARS (f->desired_tool_bar_string);
8844 else
8845 end = i + 1;
8846 Fadd_text_properties (make_number (i), make_number (end),
8847 props, f->desired_tool_bar_string);
8848 #undef PROP
8849 }
8850
8851 UNGCPRO;
8852 }
8853
8854
8855 /* Display one line of the tool-bar of frame IT->f. */
8856
8857 static void
8858 display_tool_bar_line (it)
8859 struct it *it;
8860 {
8861 struct glyph_row *row = it->glyph_row;
8862 int max_x = it->last_visible_x;
8863 struct glyph *last;
8864
8865 prepare_desired_row (row);
8866 row->y = it->current_y;
8867
8868 /* Note that this isn't made use of if the face hasn't a box,
8869 so there's no need to check the face here. */
8870 it->start_of_box_run_p = 1;
8871
8872 while (it->current_x < max_x)
8873 {
8874 int x_before, x, n_glyphs_before, i, nglyphs;
8875
8876 /* Get the next display element. */
8877 if (!get_next_display_element (it))
8878 break;
8879
8880 /* Produce glyphs. */
8881 x_before = it->current_x;
8882 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
8883 PRODUCE_GLYPHS (it);
8884
8885 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
8886 i = 0;
8887 x = x_before;
8888 while (i < nglyphs)
8889 {
8890 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
8891
8892 if (x + glyph->pixel_width > max_x)
8893 {
8894 /* Glyph doesn't fit on line. */
8895 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
8896 it->current_x = x;
8897 goto out;
8898 }
8899
8900 ++it->hpos;
8901 x += glyph->pixel_width;
8902 ++i;
8903 }
8904
8905 /* Stop at line ends. */
8906 if (ITERATOR_AT_END_OF_LINE_P (it))
8907 break;
8908
8909 set_iterator_to_next (it, 1);
8910 }
8911
8912 out:;
8913
8914 row->displays_text_p = row->used[TEXT_AREA] != 0;
8915 extend_face_to_end_of_line (it);
8916 last = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA] - 1;
8917 last->right_box_line_p = 1;
8918 if (last == row->glyphs[TEXT_AREA])
8919 last->left_box_line_p = 1;
8920 compute_line_metrics (it);
8921
8922 /* If line is empty, make it occupy the rest of the tool-bar. */
8923 if (!row->displays_text_p)
8924 {
8925 row->height = row->phys_height = it->last_visible_y - row->y;
8926 row->ascent = row->phys_ascent = 0;
8927 row->extra_line_spacing = 0;
8928 }
8929
8930 row->full_width_p = 1;
8931 row->continued_p = 0;
8932 row->truncated_on_left_p = 0;
8933 row->truncated_on_right_p = 0;
8934
8935 it->current_x = it->hpos = 0;
8936 it->current_y += row->height;
8937 ++it->vpos;
8938 ++it->glyph_row;
8939 }
8940
8941
8942 /* Value is the number of screen lines needed to make all tool-bar
8943 items of frame F visible. */
8944
8945 static int
8946 tool_bar_lines_needed (f)
8947 struct frame *f;
8948 {
8949 struct window *w = XWINDOW (f->tool_bar_window);
8950 struct it it;
8951
8952 /* Initialize an iterator for iteration over
8953 F->desired_tool_bar_string in the tool-bar window of frame F. */
8954 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
8955 it.first_visible_x = 0;
8956 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
8957 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
8958
8959 while (!ITERATOR_AT_END_P (&it))
8960 {
8961 it.glyph_row = w->desired_matrix->rows;
8962 clear_glyph_row (it.glyph_row);
8963 display_tool_bar_line (&it);
8964 }
8965
8966 return (it.current_y + FRAME_LINE_HEIGHT (f) - 1) / FRAME_LINE_HEIGHT (f);
8967 }
8968
8969
8970 DEFUN ("tool-bar-lines-needed", Ftool_bar_lines_needed, Stool_bar_lines_needed,
8971 0, 1, 0,
8972 doc: /* Return the number of lines occupied by the tool bar of FRAME. */)
8973 (frame)
8974 Lisp_Object frame;
8975 {
8976 struct frame *f;
8977 struct window *w;
8978 int nlines = 0;
8979
8980 if (NILP (frame))
8981 frame = selected_frame;
8982 else
8983 CHECK_FRAME (frame);
8984 f = XFRAME (frame);
8985
8986 if (WINDOWP (f->tool_bar_window)
8987 || (w = XWINDOW (f->tool_bar_window),
8988 WINDOW_TOTAL_LINES (w) > 0))
8989 {
8990 update_tool_bar (f, 1);
8991 if (f->n_tool_bar_items)
8992 {
8993 build_desired_tool_bar_string (f);
8994 nlines = tool_bar_lines_needed (f);
8995 }
8996 }
8997
8998 return make_number (nlines);
8999 }
9000
9001
9002 /* Display the tool-bar of frame F. Value is non-zero if tool-bar's
9003 height should be changed. */
9004
9005 static int
9006 redisplay_tool_bar (f)
9007 struct frame *f;
9008 {
9009 struct window *w;
9010 struct it it;
9011 struct glyph_row *row;
9012 int change_height_p = 0;
9013
9014 #ifdef USE_GTK
9015 if (FRAME_EXTERNAL_TOOL_BAR (f))
9016 update_frame_tool_bar (f);
9017 return 0;
9018 #endif
9019
9020 /* If frame hasn't a tool-bar window or if it is zero-height, don't
9021 do anything. This means you must start with tool-bar-lines
9022 non-zero to get the auto-sizing effect. Or in other words, you
9023 can turn off tool-bars by specifying tool-bar-lines zero. */
9024 if (!WINDOWP (f->tool_bar_window)
9025 || (w = XWINDOW (f->tool_bar_window),
9026 WINDOW_TOTAL_LINES (w) == 0))
9027 return 0;
9028
9029 /* Set up an iterator for the tool-bar window. */
9030 init_iterator (&it, w, -1, -1, w->desired_matrix->rows, TOOL_BAR_FACE_ID);
9031 it.first_visible_x = 0;
9032 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
9033 row = it.glyph_row;
9034
9035 /* Build a string that represents the contents of the tool-bar. */
9036 build_desired_tool_bar_string (f);
9037 reseat_to_string (&it, NULL, f->desired_tool_bar_string, 0, 0, 0, -1);
9038
9039 /* Display as many lines as needed to display all tool-bar items. */
9040 while (it.current_y < it.last_visible_y)
9041 display_tool_bar_line (&it);
9042
9043 /* It doesn't make much sense to try scrolling in the tool-bar
9044 window, so don't do it. */
9045 w->desired_matrix->no_scrolling_p = 1;
9046 w->must_be_updated_p = 1;
9047
9048 if (auto_resize_tool_bars_p)
9049 {
9050 int nlines;
9051
9052 /* If we couldn't display everything, change the tool-bar's
9053 height. */
9054 if (IT_STRING_CHARPOS (it) < it.end_charpos)
9055 change_height_p = 1;
9056
9057 /* If there are blank lines at the end, except for a partially
9058 visible blank line at the end that is smaller than
9059 FRAME_LINE_HEIGHT, change the tool-bar's height. */
9060 row = it.glyph_row - 1;
9061 if (!row->displays_text_p
9062 && row->height >= FRAME_LINE_HEIGHT (f))
9063 change_height_p = 1;
9064
9065 /* If row displays tool-bar items, but is partially visible,
9066 change the tool-bar's height. */
9067 if (row->displays_text_p
9068 && MATRIX_ROW_BOTTOM_Y (row) > it.last_visible_y)
9069 change_height_p = 1;
9070
9071 /* Resize windows as needed by changing the `tool-bar-lines'
9072 frame parameter. */
9073 if (change_height_p
9074 && (nlines = tool_bar_lines_needed (f),
9075 nlines != WINDOW_TOTAL_LINES (w)))
9076 {
9077 extern Lisp_Object Qtool_bar_lines;
9078 Lisp_Object frame;
9079 int old_height = WINDOW_TOTAL_LINES (w);
9080
9081 XSETFRAME (frame, f);
9082 clear_glyph_matrix (w->desired_matrix);
9083 Fmodify_frame_parameters (frame,
9084 Fcons (Fcons (Qtool_bar_lines,
9085 make_number (nlines)),
9086 Qnil));
9087 if (WINDOW_TOTAL_LINES (w) != old_height)
9088 fonts_changed_p = 1;
9089 }
9090 }
9091
9092 return change_height_p;
9093 }
9094
9095
9096 /* Get information about the tool-bar item which is displayed in GLYPH
9097 on frame F. Return in *PROP_IDX the index where tool-bar item
9098 properties start in F->tool_bar_items. Value is zero if
9099 GLYPH doesn't display a tool-bar item. */
9100
9101 static int
9102 tool_bar_item_info (f, glyph, prop_idx)
9103 struct frame *f;
9104 struct glyph *glyph;
9105 int *prop_idx;
9106 {
9107 Lisp_Object prop;
9108 int success_p;
9109 int charpos;
9110
9111 /* This function can be called asynchronously, which means we must
9112 exclude any possibility that Fget_text_property signals an
9113 error. */
9114 charpos = min (SCHARS (f->current_tool_bar_string), glyph->charpos);
9115 charpos = max (0, charpos);
9116
9117 /* Get the text property `menu-item' at pos. The value of that
9118 property is the start index of this item's properties in
9119 F->tool_bar_items. */
9120 prop = Fget_text_property (make_number (charpos),
9121 Qmenu_item, f->current_tool_bar_string);
9122 if (INTEGERP (prop))
9123 {
9124 *prop_idx = XINT (prop);
9125 success_p = 1;
9126 }
9127 else
9128 success_p = 0;
9129
9130 return success_p;
9131 }
9132
9133 \f
9134 /* Get information about the tool-bar item at position X/Y on frame F.
9135 Return in *GLYPH a pointer to the glyph of the tool-bar item in
9136 the current matrix of the tool-bar window of F, or NULL if not
9137 on a tool-bar item. Return in *PROP_IDX the index of the tool-bar
9138 item in F->tool_bar_items. Value is
9139
9140 -1 if X/Y is not on a tool-bar item
9141 0 if X/Y is on the same item that was highlighted before.
9142 1 otherwise. */
9143
9144 static int
9145 get_tool_bar_item (f, x, y, glyph, hpos, vpos, prop_idx)
9146 struct frame *f;
9147 int x, y;
9148 struct glyph **glyph;
9149 int *hpos, *vpos, *prop_idx;
9150 {
9151 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9152 struct window *w = XWINDOW (f->tool_bar_window);
9153 int area;
9154
9155 /* Find the glyph under X/Y. */
9156 *glyph = x_y_to_hpos_vpos (w, x, y, hpos, vpos, 0, 0, &area);
9157 if (*glyph == NULL)
9158 return -1;
9159
9160 /* Get the start of this tool-bar item's properties in
9161 f->tool_bar_items. */
9162 if (!tool_bar_item_info (f, *glyph, prop_idx))
9163 return -1;
9164
9165 /* Is mouse on the highlighted item? */
9166 if (EQ (f->tool_bar_window, dpyinfo->mouse_face_window)
9167 && *vpos >= dpyinfo->mouse_face_beg_row
9168 && *vpos <= dpyinfo->mouse_face_end_row
9169 && (*vpos > dpyinfo->mouse_face_beg_row
9170 || *hpos >= dpyinfo->mouse_face_beg_col)
9171 && (*vpos < dpyinfo->mouse_face_end_row
9172 || *hpos < dpyinfo->mouse_face_end_col
9173 || dpyinfo->mouse_face_past_end))
9174 return 0;
9175
9176 return 1;
9177 }
9178
9179
9180 /* EXPORT:
9181 Handle mouse button event on the tool-bar of frame F, at
9182 frame-relative coordinates X/Y. DOWN_P is 1 for a button press,
9183 0 for button release. MODIFIERS is event modifiers for button
9184 release. */
9185
9186 void
9187 handle_tool_bar_click (f, x, y, down_p, modifiers)
9188 struct frame *f;
9189 int x, y, down_p;
9190 unsigned int modifiers;
9191 {
9192 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9193 struct window *w = XWINDOW (f->tool_bar_window);
9194 int hpos, vpos, prop_idx;
9195 struct glyph *glyph;
9196 Lisp_Object enabled_p;
9197
9198 /* If not on the highlighted tool-bar item, return. */
9199 frame_to_window_pixel_xy (w, &x, &y);
9200 if (get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx) != 0)
9201 return;
9202
9203 /* If item is disabled, do nothing. */
9204 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9205 if (NILP (enabled_p))
9206 return;
9207
9208 if (down_p)
9209 {
9210 /* Show item in pressed state. */
9211 show_mouse_face (dpyinfo, DRAW_IMAGE_SUNKEN);
9212 dpyinfo->mouse_face_image_state = DRAW_IMAGE_SUNKEN;
9213 last_tool_bar_item = prop_idx;
9214 }
9215 else
9216 {
9217 Lisp_Object key, frame;
9218 struct input_event event;
9219 EVENT_INIT (event);
9220
9221 /* Show item in released state. */
9222 show_mouse_face (dpyinfo, DRAW_IMAGE_RAISED);
9223 dpyinfo->mouse_face_image_state = DRAW_IMAGE_RAISED;
9224
9225 key = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_KEY);
9226
9227 XSETFRAME (frame, f);
9228 event.kind = TOOL_BAR_EVENT;
9229 event.frame_or_window = frame;
9230 event.arg = frame;
9231 kbd_buffer_store_event (&event);
9232
9233 event.kind = TOOL_BAR_EVENT;
9234 event.frame_or_window = frame;
9235 event.arg = key;
9236 event.modifiers = modifiers;
9237 kbd_buffer_store_event (&event);
9238 last_tool_bar_item = -1;
9239 }
9240 }
9241
9242
9243 /* Possibly highlight a tool-bar item on frame F when mouse moves to
9244 tool-bar window-relative coordinates X/Y. Called from
9245 note_mouse_highlight. */
9246
9247 static void
9248 note_tool_bar_highlight (f, x, y)
9249 struct frame *f;
9250 int x, y;
9251 {
9252 Lisp_Object window = f->tool_bar_window;
9253 struct window *w = XWINDOW (window);
9254 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
9255 int hpos, vpos;
9256 struct glyph *glyph;
9257 struct glyph_row *row;
9258 int i;
9259 Lisp_Object enabled_p;
9260 int prop_idx;
9261 enum draw_glyphs_face draw = DRAW_IMAGE_RAISED;
9262 int mouse_down_p, rc;
9263
9264 /* Function note_mouse_highlight is called with negative x(y
9265 values when mouse moves outside of the frame. */
9266 if (x <= 0 || y <= 0)
9267 {
9268 clear_mouse_face (dpyinfo);
9269 return;
9270 }
9271
9272 rc = get_tool_bar_item (f, x, y, &glyph, &hpos, &vpos, &prop_idx);
9273 if (rc < 0)
9274 {
9275 /* Not on tool-bar item. */
9276 clear_mouse_face (dpyinfo);
9277 return;
9278 }
9279 else if (rc == 0)
9280 /* On same tool-bar item as before. */
9281 goto set_help_echo;
9282
9283 clear_mouse_face (dpyinfo);
9284
9285 /* Mouse is down, but on different tool-bar item? */
9286 mouse_down_p = (dpyinfo->grabbed
9287 && f == last_mouse_frame
9288 && FRAME_LIVE_P (f));
9289 if (mouse_down_p
9290 && last_tool_bar_item != prop_idx)
9291 return;
9292
9293 dpyinfo->mouse_face_image_state = DRAW_NORMAL_TEXT;
9294 draw = mouse_down_p ? DRAW_IMAGE_SUNKEN : DRAW_IMAGE_RAISED;
9295
9296 /* If tool-bar item is not enabled, don't highlight it. */
9297 enabled_p = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_ENABLED_P);
9298 if (!NILP (enabled_p))
9299 {
9300 /* Compute the x-position of the glyph. In front and past the
9301 image is a space. We include this in the highlighted area. */
9302 row = MATRIX_ROW (w->current_matrix, vpos);
9303 for (i = x = 0; i < hpos; ++i)
9304 x += row->glyphs[TEXT_AREA][i].pixel_width;
9305
9306 /* Record this as the current active region. */
9307 dpyinfo->mouse_face_beg_col = hpos;
9308 dpyinfo->mouse_face_beg_row = vpos;
9309 dpyinfo->mouse_face_beg_x = x;
9310 dpyinfo->mouse_face_beg_y = row->y;
9311 dpyinfo->mouse_face_past_end = 0;
9312
9313 dpyinfo->mouse_face_end_col = hpos + 1;
9314 dpyinfo->mouse_face_end_row = vpos;
9315 dpyinfo->mouse_face_end_x = x + glyph->pixel_width;
9316 dpyinfo->mouse_face_end_y = row->y;
9317 dpyinfo->mouse_face_window = window;
9318 dpyinfo->mouse_face_face_id = TOOL_BAR_FACE_ID;
9319
9320 /* Display it as active. */
9321 show_mouse_face (dpyinfo, draw);
9322 dpyinfo->mouse_face_image_state = draw;
9323 }
9324
9325 set_help_echo:
9326
9327 /* Set help_echo_string to a help string to display for this tool-bar item.
9328 XTread_socket does the rest. */
9329 help_echo_object = help_echo_window = Qnil;
9330 help_echo_pos = -1;
9331 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_HELP);
9332 if (NILP (help_echo_string))
9333 help_echo_string = AREF (f->tool_bar_items, prop_idx + TOOL_BAR_ITEM_CAPTION);
9334 }
9335
9336 #endif /* HAVE_WINDOW_SYSTEM */
9337
9338
9339 \f
9340 /************************************************************************
9341 Horizontal scrolling
9342 ************************************************************************/
9343
9344 static int hscroll_window_tree P_ ((Lisp_Object));
9345 static int hscroll_windows P_ ((Lisp_Object));
9346
9347 /* For all leaf windows in the window tree rooted at WINDOW, set their
9348 hscroll value so that PT is (i) visible in the window, and (ii) so
9349 that it is not within a certain margin at the window's left and
9350 right border. Value is non-zero if any window's hscroll has been
9351 changed. */
9352
9353 static int
9354 hscroll_window_tree (window)
9355 Lisp_Object window;
9356 {
9357 int hscrolled_p = 0;
9358 int hscroll_relative_p = FLOATP (Vhscroll_step);
9359 int hscroll_step_abs = 0;
9360 double hscroll_step_rel = 0;
9361
9362 if (hscroll_relative_p)
9363 {
9364 hscroll_step_rel = XFLOAT_DATA (Vhscroll_step);
9365 if (hscroll_step_rel < 0)
9366 {
9367 hscroll_relative_p = 0;
9368 hscroll_step_abs = 0;
9369 }
9370 }
9371 else if (INTEGERP (Vhscroll_step))
9372 {
9373 hscroll_step_abs = XINT (Vhscroll_step);
9374 if (hscroll_step_abs < 0)
9375 hscroll_step_abs = 0;
9376 }
9377 else
9378 hscroll_step_abs = 0;
9379
9380 while (WINDOWP (window))
9381 {
9382 struct window *w = XWINDOW (window);
9383
9384 if (WINDOWP (w->hchild))
9385 hscrolled_p |= hscroll_window_tree (w->hchild);
9386 else if (WINDOWP (w->vchild))
9387 hscrolled_p |= hscroll_window_tree (w->vchild);
9388 else if (w->cursor.vpos >= 0)
9389 {
9390 int h_margin;
9391 int text_area_width;
9392 struct glyph_row *current_cursor_row
9393 = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
9394 struct glyph_row *desired_cursor_row
9395 = MATRIX_ROW (w->desired_matrix, w->cursor.vpos);
9396 struct glyph_row *cursor_row
9397 = (desired_cursor_row->enabled_p
9398 ? desired_cursor_row
9399 : current_cursor_row);
9400
9401 text_area_width = window_box_width (w, TEXT_AREA);
9402
9403 /* Scroll when cursor is inside this scroll margin. */
9404 h_margin = hscroll_margin * WINDOW_FRAME_COLUMN_WIDTH (w);
9405
9406 if ((XFASTINT (w->hscroll)
9407 && w->cursor.x <= h_margin)
9408 || (cursor_row->enabled_p
9409 && cursor_row->truncated_on_right_p
9410 && (w->cursor.x >= text_area_width - h_margin)))
9411 {
9412 struct it it;
9413 int hscroll;
9414 struct buffer *saved_current_buffer;
9415 int pt;
9416 int wanted_x;
9417
9418 /* Find point in a display of infinite width. */
9419 saved_current_buffer = current_buffer;
9420 current_buffer = XBUFFER (w->buffer);
9421
9422 if (w == XWINDOW (selected_window))
9423 pt = BUF_PT (current_buffer);
9424 else
9425 {
9426 pt = marker_position (w->pointm);
9427 pt = max (BEGV, pt);
9428 pt = min (ZV, pt);
9429 }
9430
9431 /* Move iterator to pt starting at cursor_row->start in
9432 a line with infinite width. */
9433 init_to_row_start (&it, w, cursor_row);
9434 it.last_visible_x = INFINITY;
9435 move_it_in_display_line_to (&it, pt, -1, MOVE_TO_POS);
9436 current_buffer = saved_current_buffer;
9437
9438 /* Position cursor in window. */
9439 if (!hscroll_relative_p && hscroll_step_abs == 0)
9440 hscroll = max (0, (it.current_x
9441 - (ITERATOR_AT_END_OF_LINE_P (&it)
9442 ? (text_area_width - 4 * FRAME_COLUMN_WIDTH (it.f))
9443 : (text_area_width / 2))))
9444 / FRAME_COLUMN_WIDTH (it.f);
9445 else if (w->cursor.x >= text_area_width - h_margin)
9446 {
9447 if (hscroll_relative_p)
9448 wanted_x = text_area_width * (1 - hscroll_step_rel)
9449 - h_margin;
9450 else
9451 wanted_x = text_area_width
9452 - hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9453 - h_margin;
9454 hscroll
9455 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9456 }
9457 else
9458 {
9459 if (hscroll_relative_p)
9460 wanted_x = text_area_width * hscroll_step_rel
9461 + h_margin;
9462 else
9463 wanted_x = hscroll_step_abs * FRAME_COLUMN_WIDTH (it.f)
9464 + h_margin;
9465 hscroll
9466 = max (0, it.current_x - wanted_x) / FRAME_COLUMN_WIDTH (it.f);
9467 }
9468 hscroll = max (hscroll, XFASTINT (w->min_hscroll));
9469
9470 /* Don't call Fset_window_hscroll if value hasn't
9471 changed because it will prevent redisplay
9472 optimizations. */
9473 if (XFASTINT (w->hscroll) != hscroll)
9474 {
9475 XBUFFER (w->buffer)->prevent_redisplay_optimizations_p = 1;
9476 w->hscroll = make_number (hscroll);
9477 hscrolled_p = 1;
9478 }
9479 }
9480 }
9481
9482 window = w->next;
9483 }
9484
9485 /* Value is non-zero if hscroll of any leaf window has been changed. */
9486 return hscrolled_p;
9487 }
9488
9489
9490 /* Set hscroll so that cursor is visible and not inside horizontal
9491 scroll margins for all windows in the tree rooted at WINDOW. See
9492 also hscroll_window_tree above. Value is non-zero if any window's
9493 hscroll has been changed. If it has, desired matrices on the frame
9494 of WINDOW are cleared. */
9495
9496 static int
9497 hscroll_windows (window)
9498 Lisp_Object window;
9499 {
9500 int hscrolled_p;
9501
9502 if (automatic_hscrolling_p)
9503 {
9504 hscrolled_p = hscroll_window_tree (window);
9505 if (hscrolled_p)
9506 clear_desired_matrices (XFRAME (WINDOW_FRAME (XWINDOW (window))));
9507 }
9508 else
9509 hscrolled_p = 0;
9510 return hscrolled_p;
9511 }
9512
9513
9514 \f
9515 /************************************************************************
9516 Redisplay
9517 ************************************************************************/
9518
9519 /* Variables holding some state of redisplay if GLYPH_DEBUG is defined
9520 to a non-zero value. This is sometimes handy to have in a debugger
9521 session. */
9522
9523 #if GLYPH_DEBUG
9524
9525 /* First and last unchanged row for try_window_id. */
9526
9527 int debug_first_unchanged_at_end_vpos;
9528 int debug_last_unchanged_at_beg_vpos;
9529
9530 /* Delta vpos and y. */
9531
9532 int debug_dvpos, debug_dy;
9533
9534 /* Delta in characters and bytes for try_window_id. */
9535
9536 int debug_delta, debug_delta_bytes;
9537
9538 /* Values of window_end_pos and window_end_vpos at the end of
9539 try_window_id. */
9540
9541 EMACS_INT debug_end_pos, debug_end_vpos;
9542
9543 /* Append a string to W->desired_matrix->method. FMT is a printf
9544 format string. A1...A9 are a supplement for a variable-length
9545 argument list. If trace_redisplay_p is non-zero also printf the
9546 resulting string to stderr. */
9547
9548 static void
9549 debug_method_add (w, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9)
9550 struct window *w;
9551 char *fmt;
9552 int a1, a2, a3, a4, a5, a6, a7, a8, a9;
9553 {
9554 char buffer[512];
9555 char *method = w->desired_matrix->method;
9556 int len = strlen (method);
9557 int size = sizeof w->desired_matrix->method;
9558 int remaining = size - len - 1;
9559
9560 sprintf (buffer, fmt, a1, a2, a3, a4, a5, a6, a7, a8, a9);
9561 if (len && remaining)
9562 {
9563 method[len] = '|';
9564 --remaining, ++len;
9565 }
9566
9567 strncpy (method + len, buffer, remaining);
9568
9569 if (trace_redisplay_p)
9570 fprintf (stderr, "%p (%s): %s\n",
9571 w,
9572 ((BUFFERP (w->buffer)
9573 && STRINGP (XBUFFER (w->buffer)->name))
9574 ? (char *) SDATA (XBUFFER (w->buffer)->name)
9575 : "no buffer"),
9576 buffer);
9577 }
9578
9579 #endif /* GLYPH_DEBUG */
9580
9581
9582 /* Value is non-zero if all changes in window W, which displays
9583 current_buffer, are in the text between START and END. START is a
9584 buffer position, END is given as a distance from Z. Used in
9585 redisplay_internal for display optimization. */
9586
9587 static INLINE int
9588 text_outside_line_unchanged_p (w, start, end)
9589 struct window *w;
9590 int start, end;
9591 {
9592 int unchanged_p = 1;
9593
9594 /* If text or overlays have changed, see where. */
9595 if (XFASTINT (w->last_modified) < MODIFF
9596 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
9597 {
9598 /* Gap in the line? */
9599 if (GPT < start || Z - GPT < end)
9600 unchanged_p = 0;
9601
9602 /* Changes start in front of the line, or end after it? */
9603 if (unchanged_p
9604 && (BEG_UNCHANGED < start - 1
9605 || END_UNCHANGED < end))
9606 unchanged_p = 0;
9607
9608 /* If selective display, can't optimize if changes start at the
9609 beginning of the line. */
9610 if (unchanged_p
9611 && INTEGERP (current_buffer->selective_display)
9612 && XINT (current_buffer->selective_display) > 0
9613 && (BEG_UNCHANGED < start || GPT <= start))
9614 unchanged_p = 0;
9615
9616 /* If there are overlays at the start or end of the line, these
9617 may have overlay strings with newlines in them. A change at
9618 START, for instance, may actually concern the display of such
9619 overlay strings as well, and they are displayed on different
9620 lines. So, quickly rule out this case. (For the future, it
9621 might be desirable to implement something more telling than
9622 just BEG/END_UNCHANGED.) */
9623 if (unchanged_p)
9624 {
9625 if (BEG + BEG_UNCHANGED == start
9626 && overlay_touches_p (start))
9627 unchanged_p = 0;
9628 if (END_UNCHANGED == end
9629 && overlay_touches_p (Z - end))
9630 unchanged_p = 0;
9631 }
9632 }
9633
9634 return unchanged_p;
9635 }
9636
9637
9638 /* Do a frame update, taking possible shortcuts into account. This is
9639 the main external entry point for redisplay.
9640
9641 If the last redisplay displayed an echo area message and that message
9642 is no longer requested, we clear the echo area or bring back the
9643 mini-buffer if that is in use. */
9644
9645 void
9646 redisplay ()
9647 {
9648 redisplay_internal (0);
9649 }
9650
9651
9652 static Lisp_Object
9653 overlay_arrow_string_or_property (var)
9654 Lisp_Object var;
9655 {
9656 Lisp_Object val;
9657
9658 if (val = Fget (var, Qoverlay_arrow_string), STRINGP (val))
9659 return val;
9660
9661 return Voverlay_arrow_string;
9662 }
9663
9664 /* Return 1 if there are any overlay-arrows in current_buffer. */
9665 static int
9666 overlay_arrow_in_current_buffer_p ()
9667 {
9668 Lisp_Object vlist;
9669
9670 for (vlist = Voverlay_arrow_variable_list;
9671 CONSP (vlist);
9672 vlist = XCDR (vlist))
9673 {
9674 Lisp_Object var = XCAR (vlist);
9675 Lisp_Object val;
9676
9677 if (!SYMBOLP (var))
9678 continue;
9679 val = find_symbol_value (var);
9680 if (MARKERP (val)
9681 && current_buffer == XMARKER (val)->buffer)
9682 return 1;
9683 }
9684 return 0;
9685 }
9686
9687
9688 /* Return 1 if any overlay_arrows have moved or overlay-arrow-string
9689 has changed. */
9690
9691 static int
9692 overlay_arrows_changed_p ()
9693 {
9694 Lisp_Object vlist;
9695
9696 for (vlist = Voverlay_arrow_variable_list;
9697 CONSP (vlist);
9698 vlist = XCDR (vlist))
9699 {
9700 Lisp_Object var = XCAR (vlist);
9701 Lisp_Object val, pstr;
9702
9703 if (!SYMBOLP (var))
9704 continue;
9705 val = find_symbol_value (var);
9706 if (!MARKERP (val))
9707 continue;
9708 if (! EQ (COERCE_MARKER (val),
9709 Fget (var, Qlast_arrow_position))
9710 || ! (pstr = overlay_arrow_string_or_property (var),
9711 EQ (pstr, Fget (var, Qlast_arrow_string))))
9712 return 1;
9713 }
9714 return 0;
9715 }
9716
9717 /* Mark overlay arrows to be updated on next redisplay. */
9718
9719 static void
9720 update_overlay_arrows (up_to_date)
9721 int up_to_date;
9722 {
9723 Lisp_Object vlist;
9724
9725 for (vlist = Voverlay_arrow_variable_list;
9726 CONSP (vlist);
9727 vlist = XCDR (vlist))
9728 {
9729 Lisp_Object var = XCAR (vlist);
9730
9731 if (!SYMBOLP (var))
9732 continue;
9733
9734 if (up_to_date > 0)
9735 {
9736 Lisp_Object val = find_symbol_value (var);
9737 Fput (var, Qlast_arrow_position,
9738 COERCE_MARKER (val));
9739 Fput (var, Qlast_arrow_string,
9740 overlay_arrow_string_or_property (var));
9741 }
9742 else if (up_to_date < 0
9743 || !NILP (Fget (var, Qlast_arrow_position)))
9744 {
9745 Fput (var, Qlast_arrow_position, Qt);
9746 Fput (var, Qlast_arrow_string, Qt);
9747 }
9748 }
9749 }
9750
9751
9752 /* Return overlay arrow string to display at row.
9753 Return integer (bitmap number) for arrow bitmap in left fringe.
9754 Return nil if no overlay arrow. */
9755
9756 static Lisp_Object
9757 overlay_arrow_at_row (it, row)
9758 struct it *it;
9759 struct glyph_row *row;
9760 {
9761 Lisp_Object vlist;
9762
9763 for (vlist = Voverlay_arrow_variable_list;
9764 CONSP (vlist);
9765 vlist = XCDR (vlist))
9766 {
9767 Lisp_Object var = XCAR (vlist);
9768 Lisp_Object val;
9769
9770 if (!SYMBOLP (var))
9771 continue;
9772
9773 val = find_symbol_value (var);
9774
9775 if (MARKERP (val)
9776 && current_buffer == XMARKER (val)->buffer
9777 && (MATRIX_ROW_START_CHARPOS (row) == marker_position (val)))
9778 {
9779 if (FRAME_WINDOW_P (it->f)
9780 && WINDOW_LEFT_FRINGE_WIDTH (it->w) > 0)
9781 {
9782 if (val = Fget (var, Qoverlay_arrow_bitmap), SYMBOLP (val))
9783 {
9784 int fringe_bitmap;
9785 if ((fringe_bitmap = lookup_fringe_bitmap (val)) != 0)
9786 return make_number (fringe_bitmap);
9787 }
9788 return make_number (-1); /* Use default arrow bitmap */
9789 }
9790 return overlay_arrow_string_or_property (var);
9791 }
9792 }
9793
9794 return Qnil;
9795 }
9796
9797 /* Return 1 if point moved out of or into a composition. Otherwise
9798 return 0. PREV_BUF and PREV_PT are the last point buffer and
9799 position. BUF and PT are the current point buffer and position. */
9800
9801 int
9802 check_point_in_composition (prev_buf, prev_pt, buf, pt)
9803 struct buffer *prev_buf, *buf;
9804 int prev_pt, pt;
9805 {
9806 int start, end;
9807 Lisp_Object prop;
9808 Lisp_Object buffer;
9809
9810 XSETBUFFER (buffer, buf);
9811 /* Check a composition at the last point if point moved within the
9812 same buffer. */
9813 if (prev_buf == buf)
9814 {
9815 if (prev_pt == pt)
9816 /* Point didn't move. */
9817 return 0;
9818
9819 if (prev_pt > BUF_BEGV (buf) && prev_pt < BUF_ZV (buf)
9820 && find_composition (prev_pt, -1, &start, &end, &prop, buffer)
9821 && COMPOSITION_VALID_P (start, end, prop)
9822 && start < prev_pt && end > prev_pt)
9823 /* The last point was within the composition. Return 1 iff
9824 point moved out of the composition. */
9825 return (pt <= start || pt >= end);
9826 }
9827
9828 /* Check a composition at the current point. */
9829 return (pt > BUF_BEGV (buf) && pt < BUF_ZV (buf)
9830 && find_composition (pt, -1, &start, &end, &prop, buffer)
9831 && COMPOSITION_VALID_P (start, end, prop)
9832 && start < pt && end > pt);
9833 }
9834
9835
9836 /* Reconsider the setting of B->clip_changed which is displayed
9837 in window W. */
9838
9839 static INLINE void
9840 reconsider_clip_changes (w, b)
9841 struct window *w;
9842 struct buffer *b;
9843 {
9844 if (b->clip_changed
9845 && !NILP (w->window_end_valid)
9846 && w->current_matrix->buffer == b
9847 && w->current_matrix->zv == BUF_ZV (b)
9848 && w->current_matrix->begv == BUF_BEGV (b))
9849 b->clip_changed = 0;
9850
9851 /* If display wasn't paused, and W is not a tool bar window, see if
9852 point has been moved into or out of a composition. In that case,
9853 we set b->clip_changed to 1 to force updating the screen. If
9854 b->clip_changed has already been set to 1, we can skip this
9855 check. */
9856 if (!b->clip_changed
9857 && BUFFERP (w->buffer) && !NILP (w->window_end_valid))
9858 {
9859 int pt;
9860
9861 if (w == XWINDOW (selected_window))
9862 pt = BUF_PT (current_buffer);
9863 else
9864 pt = marker_position (w->pointm);
9865
9866 if ((w->current_matrix->buffer != XBUFFER (w->buffer)
9867 || pt != XINT (w->last_point))
9868 && check_point_in_composition (w->current_matrix->buffer,
9869 XINT (w->last_point),
9870 XBUFFER (w->buffer), pt))
9871 b->clip_changed = 1;
9872 }
9873 }
9874 \f
9875
9876 /* Select FRAME to forward the values of frame-local variables into C
9877 variables so that the redisplay routines can access those values
9878 directly. */
9879
9880 static void
9881 select_frame_for_redisplay (frame)
9882 Lisp_Object frame;
9883 {
9884 Lisp_Object tail, sym, val;
9885 Lisp_Object old = selected_frame;
9886
9887 selected_frame = frame;
9888
9889 for (tail = XFRAME (frame)->param_alist; CONSP (tail); tail = XCDR (tail))
9890 if (CONSP (XCAR (tail))
9891 && (sym = XCAR (XCAR (tail)),
9892 SYMBOLP (sym))
9893 && (sym = indirect_variable (sym),
9894 val = SYMBOL_VALUE (sym),
9895 (BUFFER_LOCAL_VALUEP (val)
9896 || SOME_BUFFER_LOCAL_VALUEP (val)))
9897 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9898 Fsymbol_value (sym);
9899
9900 for (tail = XFRAME (old)->param_alist; CONSP (tail); tail = XCDR (tail))
9901 if (CONSP (XCAR (tail))
9902 && (sym = XCAR (XCAR (tail)),
9903 SYMBOLP (sym))
9904 && (sym = indirect_variable (sym),
9905 val = SYMBOL_VALUE (sym),
9906 (BUFFER_LOCAL_VALUEP (val)
9907 || SOME_BUFFER_LOCAL_VALUEP (val)))
9908 && XBUFFER_LOCAL_VALUE (val)->check_frame)
9909 Fsymbol_value (sym);
9910 }
9911
9912
9913 #define STOP_POLLING \
9914 do { if (! polling_stopped_here) stop_polling (); \
9915 polling_stopped_here = 1; } while (0)
9916
9917 #define RESUME_POLLING \
9918 do { if (polling_stopped_here) start_polling (); \
9919 polling_stopped_here = 0; } while (0)
9920
9921
9922 /* If PRESERVE_ECHO_AREA is nonzero, it means this redisplay is not in
9923 response to any user action; therefore, we should preserve the echo
9924 area. (Actually, our caller does that job.) Perhaps in the future
9925 avoid recentering windows if it is not necessary; currently that
9926 causes some problems. */
9927
9928 static void
9929 redisplay_internal (preserve_echo_area)
9930 int preserve_echo_area;
9931 {
9932 struct window *w = XWINDOW (selected_window);
9933 struct frame *f = XFRAME (w->frame);
9934 int pause;
9935 int must_finish = 0;
9936 struct text_pos tlbufpos, tlendpos;
9937 int number_of_visible_frames;
9938 int count;
9939 struct frame *sf = SELECTED_FRAME ();
9940 int polling_stopped_here = 0;
9941
9942 /* Non-zero means redisplay has to consider all windows on all
9943 frames. Zero means, only selected_window is considered. */
9944 int consider_all_windows_p;
9945
9946 TRACE ((stderr, "redisplay_internal %d\n", redisplaying_p));
9947
9948 /* No redisplay if running in batch mode or frame is not yet fully
9949 initialized, or redisplay is explicitly turned off by setting
9950 Vinhibit_redisplay. */
9951 if (noninteractive
9952 || !NILP (Vinhibit_redisplay)
9953 || !f->glyphs_initialized_p)
9954 return;
9955
9956 /* The flag redisplay_performed_directly_p is set by
9957 direct_output_for_insert when it already did the whole screen
9958 update necessary. */
9959 if (redisplay_performed_directly_p)
9960 {
9961 redisplay_performed_directly_p = 0;
9962 if (!hscroll_windows (selected_window))
9963 return;
9964 }
9965
9966 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
9967 if (popup_activated ())
9968 return;
9969 #endif
9970
9971 /* I don't think this happens but let's be paranoid. */
9972 if (redisplaying_p)
9973 return;
9974
9975 /* Record a function that resets redisplaying_p to its old value
9976 when we leave this function. */
9977 count = SPECPDL_INDEX ();
9978 record_unwind_protect (unwind_redisplay,
9979 Fcons (make_number (redisplaying_p), selected_frame));
9980 ++redisplaying_p;
9981 specbind (Qinhibit_free_realized_faces, Qnil);
9982
9983 retry:
9984 pause = 0;
9985 reconsider_clip_changes (w, current_buffer);
9986
9987 /* If new fonts have been loaded that make a glyph matrix adjustment
9988 necessary, do it. */
9989 if (fonts_changed_p)
9990 {
9991 adjust_glyphs (NULL);
9992 ++windows_or_buffers_changed;
9993 fonts_changed_p = 0;
9994 }
9995
9996 /* If face_change_count is non-zero, init_iterator will free all
9997 realized faces, which includes the faces referenced from current
9998 matrices. So, we can't reuse current matrices in this case. */
9999 if (face_change_count)
10000 ++windows_or_buffers_changed;
10001
10002 if (! FRAME_WINDOW_P (sf)
10003 && previous_terminal_frame != sf)
10004 {
10005 /* Since frames on an ASCII terminal share the same display
10006 area, displaying a different frame means redisplay the whole
10007 thing. */
10008 windows_or_buffers_changed++;
10009 SET_FRAME_GARBAGED (sf);
10010 XSETFRAME (Vterminal_frame, sf);
10011 }
10012 previous_terminal_frame = sf;
10013
10014 /* Set the visible flags for all frames. Do this before checking
10015 for resized or garbaged frames; they want to know if their frames
10016 are visible. See the comment in frame.h for
10017 FRAME_SAMPLE_VISIBILITY. */
10018 {
10019 Lisp_Object tail, frame;
10020
10021 number_of_visible_frames = 0;
10022
10023 FOR_EACH_FRAME (tail, frame)
10024 {
10025 struct frame *f = XFRAME (frame);
10026
10027 FRAME_SAMPLE_VISIBILITY (f);
10028 if (FRAME_VISIBLE_P (f))
10029 ++number_of_visible_frames;
10030 clear_desired_matrices (f);
10031 }
10032 }
10033
10034 /* Notice any pending interrupt request to change frame size. */
10035 do_pending_window_change (1);
10036
10037 /* Clear frames marked as garbaged. */
10038 if (frame_garbaged)
10039 clear_garbaged_frames ();
10040
10041 /* Build menubar and tool-bar items. */
10042 prepare_menu_bars ();
10043
10044 if (windows_or_buffers_changed)
10045 update_mode_lines++;
10046
10047 /* Detect case that we need to write or remove a star in the mode line. */
10048 if ((SAVE_MODIFF < MODIFF) != !NILP (w->last_had_star))
10049 {
10050 w->update_mode_line = Qt;
10051 if (buffer_shared > 1)
10052 update_mode_lines++;
10053 }
10054
10055 /* If %c is in the mode line, update it if needed. */
10056 if (!NILP (w->column_number_displayed)
10057 /* This alternative quickly identifies a common case
10058 where no change is needed. */
10059 && !(PT == XFASTINT (w->last_point)
10060 && XFASTINT (w->last_modified) >= MODIFF
10061 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
10062 && (XFASTINT (w->column_number_displayed)
10063 != (int) current_column ())) /* iftc */
10064 w->update_mode_line = Qt;
10065
10066 FRAME_SCROLL_BOTTOM_VPOS (XFRAME (w->frame)) = -1;
10067
10068 /* The variable buffer_shared is set in redisplay_window and
10069 indicates that we redisplay a buffer in different windows. See
10070 there. */
10071 consider_all_windows_p = (update_mode_lines || buffer_shared > 1
10072 || cursor_type_changed);
10073
10074 /* If specs for an arrow have changed, do thorough redisplay
10075 to ensure we remove any arrow that should no longer exist. */
10076 if (overlay_arrows_changed_p ())
10077 consider_all_windows_p = windows_or_buffers_changed = 1;
10078
10079 /* Normally the message* functions will have already displayed and
10080 updated the echo area, but the frame may have been trashed, or
10081 the update may have been preempted, so display the echo area
10082 again here. Checking message_cleared_p captures the case that
10083 the echo area should be cleared. */
10084 if ((!NILP (echo_area_buffer[0]) && !display_last_displayed_message_p)
10085 || (!NILP (echo_area_buffer[1]) && display_last_displayed_message_p)
10086 || (message_cleared_p
10087 && minibuf_level == 0
10088 /* If the mini-window is currently selected, this means the
10089 echo-area doesn't show through. */
10090 && !MINI_WINDOW_P (XWINDOW (selected_window))))
10091 {
10092 int window_height_changed_p = echo_area_display (0);
10093 must_finish = 1;
10094
10095 /* If we don't display the current message, don't clear the
10096 message_cleared_p flag, because, if we did, we wouldn't clear
10097 the echo area in the next redisplay which doesn't preserve
10098 the echo area. */
10099 if (!display_last_displayed_message_p)
10100 message_cleared_p = 0;
10101
10102 if (fonts_changed_p)
10103 goto retry;
10104 else if (window_height_changed_p)
10105 {
10106 consider_all_windows_p = 1;
10107 ++update_mode_lines;
10108 ++windows_or_buffers_changed;
10109
10110 /* If window configuration was changed, frames may have been
10111 marked garbaged. Clear them or we will experience
10112 surprises wrt scrolling. */
10113 if (frame_garbaged)
10114 clear_garbaged_frames ();
10115 }
10116 }
10117 else if (EQ (selected_window, minibuf_window)
10118 && (current_buffer->clip_changed
10119 || XFASTINT (w->last_modified) < MODIFF
10120 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF)
10121 && resize_mini_window (w, 0))
10122 {
10123 /* Resized active mini-window to fit the size of what it is
10124 showing if its contents might have changed. */
10125 must_finish = 1;
10126 consider_all_windows_p = 1;
10127 ++windows_or_buffers_changed;
10128 ++update_mode_lines;
10129
10130 /* If window configuration was changed, frames may have been
10131 marked garbaged. Clear them or we will experience
10132 surprises wrt scrolling. */
10133 if (frame_garbaged)
10134 clear_garbaged_frames ();
10135 }
10136
10137
10138 /* If showing the region, and mark has changed, we must redisplay
10139 the whole window. The assignment to this_line_start_pos prevents
10140 the optimization directly below this if-statement. */
10141 if (((!NILP (Vtransient_mark_mode)
10142 && !NILP (XBUFFER (w->buffer)->mark_active))
10143 != !NILP (w->region_showing))
10144 || (!NILP (w->region_showing)
10145 && !EQ (w->region_showing,
10146 Fmarker_position (XBUFFER (w->buffer)->mark))))
10147 CHARPOS (this_line_start_pos) = 0;
10148
10149 /* Optimize the case that only the line containing the cursor in the
10150 selected window has changed. Variables starting with this_ are
10151 set in display_line and record information about the line
10152 containing the cursor. */
10153 tlbufpos = this_line_start_pos;
10154 tlendpos = this_line_end_pos;
10155 if (!consider_all_windows_p
10156 && CHARPOS (tlbufpos) > 0
10157 && NILP (w->update_mode_line)
10158 && !current_buffer->clip_changed
10159 && !current_buffer->prevent_redisplay_optimizations_p
10160 && FRAME_VISIBLE_P (XFRAME (w->frame))
10161 && !FRAME_OBSCURED_P (XFRAME (w->frame))
10162 /* Make sure recorded data applies to current buffer, etc. */
10163 && this_line_buffer == current_buffer
10164 && current_buffer == XBUFFER (w->buffer)
10165 && NILP (w->force_start)
10166 && NILP (w->optional_new_start)
10167 /* Point must be on the line that we have info recorded about. */
10168 && PT >= CHARPOS (tlbufpos)
10169 && PT <= Z - CHARPOS (tlendpos)
10170 /* All text outside that line, including its final newline,
10171 must be unchanged */
10172 && text_outside_line_unchanged_p (w, CHARPOS (tlbufpos),
10173 CHARPOS (tlendpos)))
10174 {
10175 if (CHARPOS (tlbufpos) > BEGV
10176 && FETCH_BYTE (BYTEPOS (tlbufpos) - 1) != '\n'
10177 && (CHARPOS (tlbufpos) == ZV
10178 || FETCH_BYTE (BYTEPOS (tlbufpos)) == '\n'))
10179 /* Former continuation line has disappeared by becoming empty */
10180 goto cancel;
10181 else if (XFASTINT (w->last_modified) < MODIFF
10182 || XFASTINT (w->last_overlay_modified) < OVERLAY_MODIFF
10183 || MINI_WINDOW_P (w))
10184 {
10185 /* We have to handle the case of continuation around a
10186 wide-column character (See the comment in indent.c around
10187 line 885).
10188
10189 For instance, in the following case:
10190
10191 -------- Insert --------
10192 K_A_N_\\ `a' K_A_N_a\ `X_' are wide-column chars.
10193 J_I_ ==> J_I_ `^^' are cursors.
10194 ^^ ^^
10195 -------- --------
10196
10197 As we have to redraw the line above, we should goto cancel. */
10198
10199 struct it it;
10200 int line_height_before = this_line_pixel_height;
10201
10202 /* Note that start_display will handle the case that the
10203 line starting at tlbufpos is a continuation lines. */
10204 start_display (&it, w, tlbufpos);
10205
10206 /* Implementation note: It this still necessary? */
10207 if (it.current_x != this_line_start_x)
10208 goto cancel;
10209
10210 TRACE ((stderr, "trying display optimization 1\n"));
10211 w->cursor.vpos = -1;
10212 overlay_arrow_seen = 0;
10213 it.vpos = this_line_vpos;
10214 it.current_y = this_line_y;
10215 it.glyph_row = MATRIX_ROW (w->desired_matrix, this_line_vpos);
10216 display_line (&it);
10217
10218 /* If line contains point, is not continued,
10219 and ends at same distance from eob as before, we win */
10220 if (w->cursor.vpos >= 0
10221 /* Line is not continued, otherwise this_line_start_pos
10222 would have been set to 0 in display_line. */
10223 && CHARPOS (this_line_start_pos)
10224 /* Line ends as before. */
10225 && CHARPOS (this_line_end_pos) == CHARPOS (tlendpos)
10226 /* Line has same height as before. Otherwise other lines
10227 would have to be shifted up or down. */
10228 && this_line_pixel_height == line_height_before)
10229 {
10230 /* If this is not the window's last line, we must adjust
10231 the charstarts of the lines below. */
10232 if (it.current_y < it.last_visible_y)
10233 {
10234 struct glyph_row *row
10235 = MATRIX_ROW (w->current_matrix, this_line_vpos + 1);
10236 int delta, delta_bytes;
10237
10238 if (Z - CHARPOS (tlendpos) == ZV)
10239 {
10240 /* This line ends at end of (accessible part of)
10241 buffer. There is no newline to count. */
10242 delta = (Z
10243 - CHARPOS (tlendpos)
10244 - MATRIX_ROW_START_CHARPOS (row));
10245 delta_bytes = (Z_BYTE
10246 - BYTEPOS (tlendpos)
10247 - MATRIX_ROW_START_BYTEPOS (row));
10248 }
10249 else
10250 {
10251 /* This line ends in a newline. Must take
10252 account of the newline and the rest of the
10253 text that follows. */
10254 delta = (Z
10255 - CHARPOS (tlendpos)
10256 - MATRIX_ROW_START_CHARPOS (row));
10257 delta_bytes = (Z_BYTE
10258 - BYTEPOS (tlendpos)
10259 - MATRIX_ROW_START_BYTEPOS (row));
10260 }
10261
10262 increment_matrix_positions (w->current_matrix,
10263 this_line_vpos + 1,
10264 w->current_matrix->nrows,
10265 delta, delta_bytes);
10266 }
10267
10268 /* If this row displays text now but previously didn't,
10269 or vice versa, w->window_end_vpos may have to be
10270 adjusted. */
10271 if ((it.glyph_row - 1)->displays_text_p)
10272 {
10273 if (XFASTINT (w->window_end_vpos) < this_line_vpos)
10274 XSETINT (w->window_end_vpos, this_line_vpos);
10275 }
10276 else if (XFASTINT (w->window_end_vpos) == this_line_vpos
10277 && this_line_vpos > 0)
10278 XSETINT (w->window_end_vpos, this_line_vpos - 1);
10279 w->window_end_valid = Qnil;
10280
10281 /* Update hint: No need to try to scroll in update_window. */
10282 w->desired_matrix->no_scrolling_p = 1;
10283
10284 #if GLYPH_DEBUG
10285 *w->desired_matrix->method = 0;
10286 debug_method_add (w, "optimization 1");
10287 #endif
10288 #ifdef HAVE_WINDOW_SYSTEM
10289 update_window_fringes (w, 0);
10290 #endif
10291 goto update;
10292 }
10293 else
10294 goto cancel;
10295 }
10296 else if (/* Cursor position hasn't changed. */
10297 PT == XFASTINT (w->last_point)
10298 /* Make sure the cursor was last displayed
10299 in this window. Otherwise we have to reposition it. */
10300 && 0 <= w->cursor.vpos
10301 && WINDOW_TOTAL_LINES (w) > w->cursor.vpos)
10302 {
10303 if (!must_finish)
10304 {
10305 do_pending_window_change (1);
10306
10307 /* We used to always goto end_of_redisplay here, but this
10308 isn't enough if we have a blinking cursor. */
10309 if (w->cursor_off_p == w->last_cursor_off_p)
10310 goto end_of_redisplay;
10311 }
10312 goto update;
10313 }
10314 /* If highlighting the region, or if the cursor is in the echo area,
10315 then we can't just move the cursor. */
10316 else if (! (!NILP (Vtransient_mark_mode)
10317 && !NILP (current_buffer->mark_active))
10318 && (EQ (selected_window, current_buffer->last_selected_window)
10319 || highlight_nonselected_windows)
10320 && NILP (w->region_showing)
10321 && NILP (Vshow_trailing_whitespace)
10322 && !cursor_in_echo_area)
10323 {
10324 struct it it;
10325 struct glyph_row *row;
10326
10327 /* Skip from tlbufpos to PT and see where it is. Note that
10328 PT may be in invisible text. If so, we will end at the
10329 next visible position. */
10330 init_iterator (&it, w, CHARPOS (tlbufpos), BYTEPOS (tlbufpos),
10331 NULL, DEFAULT_FACE_ID);
10332 it.current_x = this_line_start_x;
10333 it.current_y = this_line_y;
10334 it.vpos = this_line_vpos;
10335
10336 /* The call to move_it_to stops in front of PT, but
10337 moves over before-strings. */
10338 move_it_to (&it, PT, -1, -1, -1, MOVE_TO_POS);
10339
10340 if (it.vpos == this_line_vpos
10341 && (row = MATRIX_ROW (w->current_matrix, this_line_vpos),
10342 row->enabled_p))
10343 {
10344 xassert (this_line_vpos == it.vpos);
10345 xassert (this_line_y == it.current_y);
10346 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
10347 #if GLYPH_DEBUG
10348 *w->desired_matrix->method = 0;
10349 debug_method_add (w, "optimization 3");
10350 #endif
10351 goto update;
10352 }
10353 else
10354 goto cancel;
10355 }
10356
10357 cancel:
10358 /* Text changed drastically or point moved off of line. */
10359 SET_MATRIX_ROW_ENABLED_P (w->desired_matrix, this_line_vpos, 0);
10360 }
10361
10362 CHARPOS (this_line_start_pos) = 0;
10363 consider_all_windows_p |= buffer_shared > 1;
10364 ++clear_face_cache_count;
10365 #ifdef HAVE_WINDOW_SYSTEM
10366 ++clear_image_cache_count;
10367 #endif
10368
10369 /* Build desired matrices, and update the display. If
10370 consider_all_windows_p is non-zero, do it for all windows on all
10371 frames. Otherwise do it for selected_window, only. */
10372
10373 if (consider_all_windows_p)
10374 {
10375 Lisp_Object tail, frame;
10376 int i, n = 0, size = 50;
10377 struct frame **updated
10378 = (struct frame **) alloca (size * sizeof *updated);
10379
10380 /* Recompute # windows showing selected buffer. This will be
10381 incremented each time such a window is displayed. */
10382 buffer_shared = 0;
10383
10384 FOR_EACH_FRAME (tail, frame)
10385 {
10386 struct frame *f = XFRAME (frame);
10387
10388 if (FRAME_WINDOW_P (f) || f == sf)
10389 {
10390 if (! EQ (frame, selected_frame))
10391 /* Select the frame, for the sake of frame-local
10392 variables. */
10393 select_frame_for_redisplay (frame);
10394
10395 /* Mark all the scroll bars to be removed; we'll redeem
10396 the ones we want when we redisplay their windows. */
10397 if (condemn_scroll_bars_hook)
10398 condemn_scroll_bars_hook (f);
10399
10400 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10401 redisplay_windows (FRAME_ROOT_WINDOW (f));
10402
10403 /* Any scroll bars which redisplay_windows should have
10404 nuked should now go away. */
10405 if (judge_scroll_bars_hook)
10406 judge_scroll_bars_hook (f);
10407
10408 /* If fonts changed, display again. */
10409 /* ??? rms: I suspect it is a mistake to jump all the way
10410 back to retry here. It should just retry this frame. */
10411 if (fonts_changed_p)
10412 goto retry;
10413
10414 if (FRAME_VISIBLE_P (f) && !FRAME_OBSCURED_P (f))
10415 {
10416 /* See if we have to hscroll. */
10417 if (hscroll_windows (f->root_window))
10418 goto retry;
10419
10420 /* Prevent various kinds of signals during display
10421 update. stdio is not robust about handling
10422 signals, which can cause an apparent I/O
10423 error. */
10424 if (interrupt_input)
10425 unrequest_sigio ();
10426 STOP_POLLING;
10427
10428 /* Update the display. */
10429 set_window_update_flags (XWINDOW (f->root_window), 1);
10430 pause |= update_frame (f, 0, 0);
10431 #if 0 /* Exiting the loop can leave the wrong value for buffer_shared. */
10432 if (pause)
10433 break;
10434 #endif
10435
10436 if (n == size)
10437 {
10438 int nbytes = size * sizeof *updated;
10439 struct frame **p = (struct frame **) alloca (2 * nbytes);
10440 bcopy (updated, p, nbytes);
10441 size *= 2;
10442 }
10443
10444 updated[n++] = f;
10445 }
10446 }
10447 }
10448
10449 if (!pause)
10450 {
10451 /* Do the mark_window_display_accurate after all windows have
10452 been redisplayed because this call resets flags in buffers
10453 which are needed for proper redisplay. */
10454 for (i = 0; i < n; ++i)
10455 {
10456 struct frame *f = updated[i];
10457 mark_window_display_accurate (f->root_window, 1);
10458 if (frame_up_to_date_hook)
10459 frame_up_to_date_hook (f);
10460 }
10461 }
10462 }
10463 else if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10464 {
10465 Lisp_Object mini_window;
10466 struct frame *mini_frame;
10467
10468 displayed_buffer = XBUFFER (XWINDOW (selected_window)->buffer);
10469 /* Use list_of_error, not Qerror, so that
10470 we catch only errors and don't run the debugger. */
10471 internal_condition_case_1 (redisplay_window_1, selected_window,
10472 list_of_error,
10473 redisplay_window_error);
10474
10475 /* Compare desired and current matrices, perform output. */
10476
10477 update:
10478 /* If fonts changed, display again. */
10479 if (fonts_changed_p)
10480 goto retry;
10481
10482 /* Prevent various kinds of signals during display update.
10483 stdio is not robust about handling signals,
10484 which can cause an apparent I/O error. */
10485 if (interrupt_input)
10486 unrequest_sigio ();
10487 STOP_POLLING;
10488
10489 if (FRAME_VISIBLE_P (sf) && !FRAME_OBSCURED_P (sf))
10490 {
10491 if (hscroll_windows (selected_window))
10492 goto retry;
10493
10494 XWINDOW (selected_window)->must_be_updated_p = 1;
10495 pause = update_frame (sf, 0, 0);
10496 }
10497
10498 /* We may have called echo_area_display at the top of this
10499 function. If the echo area is on another frame, that may
10500 have put text on a frame other than the selected one, so the
10501 above call to update_frame would not have caught it. Catch
10502 it here. */
10503 mini_window = FRAME_MINIBUF_WINDOW (sf);
10504 mini_frame = XFRAME (WINDOW_FRAME (XWINDOW (mini_window)));
10505
10506 if (mini_frame != sf && FRAME_WINDOW_P (mini_frame))
10507 {
10508 XWINDOW (mini_window)->must_be_updated_p = 1;
10509 pause |= update_frame (mini_frame, 0, 0);
10510 if (!pause && hscroll_windows (mini_window))
10511 goto retry;
10512 }
10513 }
10514
10515 /* If display was paused because of pending input, make sure we do a
10516 thorough update the next time. */
10517 if (pause)
10518 {
10519 /* Prevent the optimization at the beginning of
10520 redisplay_internal that tries a single-line update of the
10521 line containing the cursor in the selected window. */
10522 CHARPOS (this_line_start_pos) = 0;
10523
10524 /* Let the overlay arrow be updated the next time. */
10525 update_overlay_arrows (0);
10526
10527 /* If we pause after scrolling, some rows in the current
10528 matrices of some windows are not valid. */
10529 if (!WINDOW_FULL_WIDTH_P (w)
10530 && !FRAME_WINDOW_P (XFRAME (w->frame)))
10531 update_mode_lines = 1;
10532 }
10533 else
10534 {
10535 if (!consider_all_windows_p)
10536 {
10537 /* This has already been done above if
10538 consider_all_windows_p is set. */
10539 mark_window_display_accurate_1 (w, 1);
10540
10541 /* Say overlay arrows are up to date. */
10542 update_overlay_arrows (1);
10543
10544 if (frame_up_to_date_hook != 0)
10545 frame_up_to_date_hook (sf);
10546 }
10547
10548 update_mode_lines = 0;
10549 windows_or_buffers_changed = 0;
10550 cursor_type_changed = 0;
10551 }
10552
10553 /* Start SIGIO interrupts coming again. Having them off during the
10554 code above makes it less likely one will discard output, but not
10555 impossible, since there might be stuff in the system buffer here.
10556 But it is much hairier to try to do anything about that. */
10557 if (interrupt_input)
10558 request_sigio ();
10559 RESUME_POLLING;
10560
10561 /* If a frame has become visible which was not before, redisplay
10562 again, so that we display it. Expose events for such a frame
10563 (which it gets when becoming visible) don't call the parts of
10564 redisplay constructing glyphs, so simply exposing a frame won't
10565 display anything in this case. So, we have to display these
10566 frames here explicitly. */
10567 if (!pause)
10568 {
10569 Lisp_Object tail, frame;
10570 int new_count = 0;
10571
10572 FOR_EACH_FRAME (tail, frame)
10573 {
10574 int this_is_visible = 0;
10575
10576 if (XFRAME (frame)->visible)
10577 this_is_visible = 1;
10578 FRAME_SAMPLE_VISIBILITY (XFRAME (frame));
10579 if (XFRAME (frame)->visible)
10580 this_is_visible = 1;
10581
10582 if (this_is_visible)
10583 new_count++;
10584 }
10585
10586 if (new_count != number_of_visible_frames)
10587 windows_or_buffers_changed++;
10588 }
10589
10590 /* Change frame size now if a change is pending. */
10591 do_pending_window_change (1);
10592
10593 /* If we just did a pending size change, or have additional
10594 visible frames, redisplay again. */
10595 if (windows_or_buffers_changed && !pause)
10596 goto retry;
10597
10598 /* Clear the face cache eventually. */
10599 if (consider_all_windows_p)
10600 {
10601 if (clear_face_cache_count > CLEAR_FACE_CACHE_COUNT)
10602 {
10603 clear_face_cache (0);
10604 clear_face_cache_count = 0;
10605 }
10606 #ifdef HAVE_WINDOW_SYSTEM
10607 if (clear_image_cache_count > CLEAR_IMAGE_CACHE_COUNT)
10608 {
10609 Lisp_Object tail, frame;
10610 FOR_EACH_FRAME (tail, frame)
10611 {
10612 struct frame *f = XFRAME (frame);
10613 if (FRAME_WINDOW_P (f))
10614 clear_image_cache (f, 0);
10615 }
10616 clear_image_cache_count = 0;
10617 }
10618 #endif /* HAVE_WINDOW_SYSTEM */
10619 }
10620
10621 end_of_redisplay:
10622 unbind_to (count, Qnil);
10623 RESUME_POLLING;
10624 }
10625
10626
10627 /* Redisplay, but leave alone any recent echo area message unless
10628 another message has been requested in its place.
10629
10630 This is useful in situations where you need to redisplay but no
10631 user action has occurred, making it inappropriate for the message
10632 area to be cleared. See tracking_off and
10633 wait_reading_process_output for examples of these situations.
10634
10635 FROM_WHERE is an integer saying from where this function was
10636 called. This is useful for debugging. */
10637
10638 void
10639 redisplay_preserve_echo_area (from_where)
10640 int from_where;
10641 {
10642 TRACE ((stderr, "redisplay_preserve_echo_area (%d)\n", from_where));
10643
10644 if (!NILP (echo_area_buffer[1]))
10645 {
10646 /* We have a previously displayed message, but no current
10647 message. Redisplay the previous message. */
10648 display_last_displayed_message_p = 1;
10649 redisplay_internal (1);
10650 display_last_displayed_message_p = 0;
10651 }
10652 else
10653 redisplay_internal (1);
10654
10655 if (rif != NULL && rif->flush_display_optional)
10656 rif->flush_display_optional (NULL);
10657 }
10658
10659
10660 /* Function registered with record_unwind_protect in
10661 redisplay_internal. Reset redisplaying_p to the value it had
10662 before redisplay_internal was called, and clear
10663 prevent_freeing_realized_faces_p. It also selects the previously
10664 selected frame. */
10665
10666 static Lisp_Object
10667 unwind_redisplay (val)
10668 Lisp_Object val;
10669 {
10670 Lisp_Object old_redisplaying_p, old_frame;
10671
10672 old_redisplaying_p = XCAR (val);
10673 redisplaying_p = XFASTINT (old_redisplaying_p);
10674 old_frame = XCDR (val);
10675 if (! EQ (old_frame, selected_frame))
10676 select_frame_for_redisplay (old_frame);
10677 return Qnil;
10678 }
10679
10680
10681 /* Mark the display of window W as accurate or inaccurate. If
10682 ACCURATE_P is non-zero mark display of W as accurate. If
10683 ACCURATE_P is zero, arrange for W to be redisplayed the next time
10684 redisplay_internal is called. */
10685
10686 static void
10687 mark_window_display_accurate_1 (w, accurate_p)
10688 struct window *w;
10689 int accurate_p;
10690 {
10691 if (BUFFERP (w->buffer))
10692 {
10693 struct buffer *b = XBUFFER (w->buffer);
10694
10695 w->last_modified
10696 = make_number (accurate_p ? BUF_MODIFF (b) : 0);
10697 w->last_overlay_modified
10698 = make_number (accurate_p ? BUF_OVERLAY_MODIFF (b) : 0);
10699 w->last_had_star
10700 = BUF_MODIFF (b) > BUF_SAVE_MODIFF (b) ? Qt : Qnil;
10701
10702 if (accurate_p)
10703 {
10704 b->clip_changed = 0;
10705 b->prevent_redisplay_optimizations_p = 0;
10706
10707 BUF_UNCHANGED_MODIFIED (b) = BUF_MODIFF (b);
10708 BUF_OVERLAY_UNCHANGED_MODIFIED (b) = BUF_OVERLAY_MODIFF (b);
10709 BUF_BEG_UNCHANGED (b) = BUF_GPT (b) - BUF_BEG (b);
10710 BUF_END_UNCHANGED (b) = BUF_Z (b) - BUF_GPT (b);
10711
10712 w->current_matrix->buffer = b;
10713 w->current_matrix->begv = BUF_BEGV (b);
10714 w->current_matrix->zv = BUF_ZV (b);
10715
10716 w->last_cursor = w->cursor;
10717 w->last_cursor_off_p = w->cursor_off_p;
10718
10719 if (w == XWINDOW (selected_window))
10720 w->last_point = make_number (BUF_PT (b));
10721 else
10722 w->last_point = make_number (XMARKER (w->pointm)->charpos);
10723 }
10724 }
10725
10726 if (accurate_p)
10727 {
10728 w->window_end_valid = w->buffer;
10729 #if 0 /* This is incorrect with variable-height lines. */
10730 xassert (XINT (w->window_end_vpos)
10731 < (WINDOW_TOTAL_LINES (w)
10732 - (WINDOW_WANTS_MODELINE_P (w) ? 1 : 0)));
10733 #endif
10734 w->update_mode_line = Qnil;
10735 }
10736 }
10737
10738
10739 /* Mark the display of windows in the window tree rooted at WINDOW as
10740 accurate or inaccurate. If ACCURATE_P is non-zero mark display of
10741 windows as accurate. If ACCURATE_P is zero, arrange for windows to
10742 be redisplayed the next time redisplay_internal is called. */
10743
10744 void
10745 mark_window_display_accurate (window, accurate_p)
10746 Lisp_Object window;
10747 int accurate_p;
10748 {
10749 struct window *w;
10750
10751 for (; !NILP (window); window = w->next)
10752 {
10753 w = XWINDOW (window);
10754 mark_window_display_accurate_1 (w, accurate_p);
10755
10756 if (!NILP (w->vchild))
10757 mark_window_display_accurate (w->vchild, accurate_p);
10758 if (!NILP (w->hchild))
10759 mark_window_display_accurate (w->hchild, accurate_p);
10760 }
10761
10762 if (accurate_p)
10763 {
10764 update_overlay_arrows (1);
10765 }
10766 else
10767 {
10768 /* Force a thorough redisplay the next time by setting
10769 last_arrow_position and last_arrow_string to t, which is
10770 unequal to any useful value of Voverlay_arrow_... */
10771 update_overlay_arrows (-1);
10772 }
10773 }
10774
10775
10776 /* Return value in display table DP (Lisp_Char_Table *) for character
10777 C. Since a display table doesn't have any parent, we don't have to
10778 follow parent. Do not call this function directly but use the
10779 macro DISP_CHAR_VECTOR. */
10780
10781 Lisp_Object
10782 disp_char_vector (dp, c)
10783 struct Lisp_Char_Table *dp;
10784 int c;
10785 {
10786 int code[4], i;
10787 Lisp_Object val;
10788
10789 if (SINGLE_BYTE_CHAR_P (c))
10790 return (dp->contents[c]);
10791
10792 SPLIT_CHAR (c, code[0], code[1], code[2]);
10793 if (code[1] < 32)
10794 code[1] = -1;
10795 else if (code[2] < 32)
10796 code[2] = -1;
10797
10798 /* Here, the possible range of code[0] (== charset ID) is
10799 128..max_charset. Since the top level char table contains data
10800 for multibyte characters after 256th element, we must increment
10801 code[0] by 128 to get a correct index. */
10802 code[0] += 128;
10803 code[3] = -1; /* anchor */
10804
10805 for (i = 0; code[i] >= 0; i++, dp = XCHAR_TABLE (val))
10806 {
10807 val = dp->contents[code[i]];
10808 if (!SUB_CHAR_TABLE_P (val))
10809 return (NILP (val) ? dp->defalt : val);
10810 }
10811
10812 /* Here, val is a sub char table. We return the default value of
10813 it. */
10814 return (dp->defalt);
10815 }
10816
10817
10818 \f
10819 /***********************************************************************
10820 Window Redisplay
10821 ***********************************************************************/
10822
10823 /* Redisplay all leaf windows in the window tree rooted at WINDOW. */
10824
10825 static void
10826 redisplay_windows (window)
10827 Lisp_Object window;
10828 {
10829 while (!NILP (window))
10830 {
10831 struct window *w = XWINDOW (window);
10832
10833 if (!NILP (w->hchild))
10834 redisplay_windows (w->hchild);
10835 else if (!NILP (w->vchild))
10836 redisplay_windows (w->vchild);
10837 else
10838 {
10839 displayed_buffer = XBUFFER (w->buffer);
10840 /* Use list_of_error, not Qerror, so that
10841 we catch only errors and don't run the debugger. */
10842 internal_condition_case_1 (redisplay_window_0, window,
10843 list_of_error,
10844 redisplay_window_error);
10845 }
10846
10847 window = w->next;
10848 }
10849 }
10850
10851 static Lisp_Object
10852 redisplay_window_error ()
10853 {
10854 displayed_buffer->display_error_modiff = BUF_MODIFF (displayed_buffer);
10855 return Qnil;
10856 }
10857
10858 static Lisp_Object
10859 redisplay_window_0 (window)
10860 Lisp_Object window;
10861 {
10862 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10863 redisplay_window (window, 0);
10864 return Qnil;
10865 }
10866
10867 static Lisp_Object
10868 redisplay_window_1 (window)
10869 Lisp_Object window;
10870 {
10871 if (displayed_buffer->display_error_modiff < BUF_MODIFF (displayed_buffer))
10872 redisplay_window (window, 1);
10873 return Qnil;
10874 }
10875 \f
10876
10877 /* Increment GLYPH until it reaches END or CONDITION fails while
10878 adding (GLYPH)->pixel_width to X. */
10879
10880 #define SKIP_GLYPHS(glyph, end, x, condition) \
10881 do \
10882 { \
10883 (x) += (glyph)->pixel_width; \
10884 ++(glyph); \
10885 } \
10886 while ((glyph) < (end) && (condition))
10887
10888
10889 /* Set cursor position of W. PT is assumed to be displayed in ROW.
10890 DELTA is the number of bytes by which positions recorded in ROW
10891 differ from current buffer positions. */
10892
10893 void
10894 set_cursor_from_row (w, row, matrix, delta, delta_bytes, dy, dvpos)
10895 struct window *w;
10896 struct glyph_row *row;
10897 struct glyph_matrix *matrix;
10898 int delta, delta_bytes, dy, dvpos;
10899 {
10900 struct glyph *glyph = row->glyphs[TEXT_AREA];
10901 struct glyph *end = glyph + row->used[TEXT_AREA];
10902 struct glyph *cursor = NULL;
10903 /* The first glyph that starts a sequence of glyphs from string. */
10904 struct glyph *string_start;
10905 /* The X coordinate of string_start. */
10906 int string_start_x;
10907 /* The last known character position. */
10908 int last_pos = MATRIX_ROW_START_CHARPOS (row) + delta;
10909 /* The last known character position before string_start. */
10910 int string_before_pos;
10911 int x = row->x;
10912 int cursor_x = x;
10913 int cursor_from_overlay_pos = 0;
10914 int pt_old = PT - delta;
10915
10916 /* Skip over glyphs not having an object at the start of the row.
10917 These are special glyphs like truncation marks on terminal
10918 frames. */
10919 if (row->displays_text_p)
10920 while (glyph < end
10921 && INTEGERP (glyph->object)
10922 && glyph->charpos < 0)
10923 {
10924 x += glyph->pixel_width;
10925 ++glyph;
10926 }
10927
10928 string_start = NULL;
10929 while (glyph < end
10930 && !INTEGERP (glyph->object)
10931 && (!BUFFERP (glyph->object)
10932 || (last_pos = glyph->charpos) < pt_old))
10933 {
10934 if (! STRINGP (glyph->object))
10935 {
10936 string_start = NULL;
10937 x += glyph->pixel_width;
10938 ++glyph;
10939 if (cursor_from_overlay_pos
10940 && last_pos > cursor_from_overlay_pos)
10941 {
10942 cursor_from_overlay_pos = 0;
10943 cursor = 0;
10944 }
10945 }
10946 else
10947 {
10948 string_before_pos = last_pos;
10949 string_start = glyph;
10950 string_start_x = x;
10951 /* Skip all glyphs from string. */
10952 do
10953 {
10954 int pos;
10955 if ((cursor == NULL || glyph > cursor)
10956 && !NILP (Fget_char_property (make_number ((glyph)->charpos),
10957 Qcursor, (glyph)->object))
10958 && (pos = string_buffer_position (w, glyph->object,
10959 string_before_pos),
10960 (pos == 0 /* From overlay */
10961 || pos == pt_old)))
10962 {
10963 /* Estimate overlay buffer position from the buffer
10964 positions of the glyphs before and after the overlay.
10965 Add 1 to last_pos so that if point corresponds to the
10966 glyph right after the overlay, we still use a 'cursor'
10967 property found in that overlay. */
10968 cursor_from_overlay_pos = pos == 0 ? last_pos+1 : 0;
10969 cursor = glyph;
10970 cursor_x = x;
10971 }
10972 x += glyph->pixel_width;
10973 ++glyph;
10974 }
10975 while (glyph < end && STRINGP (glyph->object));
10976 }
10977 }
10978
10979 if (cursor != NULL)
10980 {
10981 glyph = cursor;
10982 x = cursor_x;
10983 }
10984 else if (row->ends_in_ellipsis_p && glyph == end)
10985 {
10986 /* Scan back over the ellipsis glyphs, decrementing positions. */
10987 while (glyph > row->glyphs[TEXT_AREA]
10988 && (glyph - 1)->charpos == last_pos)
10989 glyph--, x -= glyph->pixel_width;
10990 /* That loop always goes one position too far,
10991 including the glyph before the ellipsis.
10992 So scan forward over that one. */
10993 x += glyph->pixel_width;
10994 glyph++;
10995 }
10996 else if (string_start
10997 && (glyph == end || !BUFFERP (glyph->object) || last_pos > pt_old))
10998 {
10999 /* We may have skipped over point because the previous glyphs
11000 are from string. As there's no easy way to know the
11001 character position of the current glyph, find the correct
11002 glyph on point by scanning from string_start again. */
11003 Lisp_Object limit;
11004 Lisp_Object string;
11005 int pos;
11006
11007 limit = make_number (pt_old + 1);
11008 end = glyph;
11009 glyph = string_start;
11010 x = string_start_x;
11011 string = glyph->object;
11012 pos = string_buffer_position (w, string, string_before_pos);
11013 /* If STRING is from overlay, LAST_POS == 0. We skip such glyphs
11014 because we always put cursor after overlay strings. */
11015 while (pos == 0 && glyph < end)
11016 {
11017 string = glyph->object;
11018 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11019 if (glyph < end)
11020 pos = string_buffer_position (w, glyph->object, string_before_pos);
11021 }
11022
11023 while (glyph < end)
11024 {
11025 pos = XINT (Fnext_single_char_property_change
11026 (make_number (pos), Qdisplay, Qnil, limit));
11027 if (pos > pt_old)
11028 break;
11029 /* Skip glyphs from the same string. */
11030 string = glyph->object;
11031 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11032 /* Skip glyphs from an overlay. */
11033 while (glyph < end
11034 && ! string_buffer_position (w, glyph->object, pos))
11035 {
11036 string = glyph->object;
11037 SKIP_GLYPHS (glyph, end, x, EQ (glyph->object, string));
11038 }
11039 }
11040 }
11041
11042 w->cursor.hpos = glyph - row->glyphs[TEXT_AREA];
11043 w->cursor.x = x;
11044 w->cursor.vpos = MATRIX_ROW_VPOS (row, matrix) + dvpos;
11045 w->cursor.y = row->y + dy;
11046
11047 if (w == XWINDOW (selected_window))
11048 {
11049 if (!row->continued_p
11050 && !MATRIX_ROW_CONTINUATION_LINE_P (row)
11051 && row->x == 0)
11052 {
11053 this_line_buffer = XBUFFER (w->buffer);
11054
11055 CHARPOS (this_line_start_pos)
11056 = MATRIX_ROW_START_CHARPOS (row) + delta;
11057 BYTEPOS (this_line_start_pos)
11058 = MATRIX_ROW_START_BYTEPOS (row) + delta_bytes;
11059
11060 CHARPOS (this_line_end_pos)
11061 = Z - (MATRIX_ROW_END_CHARPOS (row) + delta);
11062 BYTEPOS (this_line_end_pos)
11063 = Z_BYTE - (MATRIX_ROW_END_BYTEPOS (row) + delta_bytes);
11064
11065 this_line_y = w->cursor.y;
11066 this_line_pixel_height = row->height;
11067 this_line_vpos = w->cursor.vpos;
11068 this_line_start_x = row->x;
11069 }
11070 else
11071 CHARPOS (this_line_start_pos) = 0;
11072 }
11073 }
11074
11075
11076 /* Run window scroll functions, if any, for WINDOW with new window
11077 start STARTP. Sets the window start of WINDOW to that position.
11078
11079 We assume that the window's buffer is really current. */
11080
11081 static INLINE struct text_pos
11082 run_window_scroll_functions (window, startp)
11083 Lisp_Object window;
11084 struct text_pos startp;
11085 {
11086 struct window *w = XWINDOW (window);
11087 SET_MARKER_FROM_TEXT_POS (w->start, startp);
11088
11089 if (current_buffer != XBUFFER (w->buffer))
11090 abort ();
11091
11092 if (!NILP (Vwindow_scroll_functions))
11093 {
11094 run_hook_with_args_2 (Qwindow_scroll_functions, window,
11095 make_number (CHARPOS (startp)));
11096 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11097 /* In case the hook functions switch buffers. */
11098 if (current_buffer != XBUFFER (w->buffer))
11099 set_buffer_internal_1 (XBUFFER (w->buffer));
11100 }
11101
11102 return startp;
11103 }
11104
11105
11106 /* Make sure the line containing the cursor is fully visible.
11107 A value of 1 means there is nothing to be done.
11108 (Either the line is fully visible, or it cannot be made so,
11109 or we cannot tell.)
11110
11111 If FORCE_P is non-zero, return 0 even if partial visible cursor row
11112 is higher than window.
11113
11114 A value of 0 means the caller should do scrolling
11115 as if point had gone off the screen. */
11116
11117 static int
11118 cursor_row_fully_visible_p (w, force_p, current_matrix_p)
11119 struct window *w;
11120 int force_p;
11121 {
11122 struct glyph_matrix *matrix;
11123 struct glyph_row *row;
11124 int window_height;
11125
11126 if (!make_cursor_line_fully_visible_p)
11127 return 1;
11128
11129 /* It's not always possible to find the cursor, e.g, when a window
11130 is full of overlay strings. Don't do anything in that case. */
11131 if (w->cursor.vpos < 0)
11132 return 1;
11133
11134 matrix = current_matrix_p ? w->current_matrix : w->desired_matrix;
11135 row = MATRIX_ROW (matrix, w->cursor.vpos);
11136
11137 /* If the cursor row is not partially visible, there's nothing to do. */
11138 if (!MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row))
11139 return 1;
11140
11141 /* If the row the cursor is in is taller than the window's height,
11142 it's not clear what to do, so do nothing. */
11143 window_height = window_box_height (w);
11144 if (row->height >= window_height)
11145 {
11146 if (!force_p || w->vscroll)
11147 return 1;
11148 }
11149 return 0;
11150
11151 #if 0
11152 /* This code used to try to scroll the window just enough to make
11153 the line visible. It returned 0 to say that the caller should
11154 allocate larger glyph matrices. */
11155
11156 if (MATRIX_ROW_PARTIALLY_VISIBLE_AT_TOP_P (w, row))
11157 {
11158 int dy = row->height - row->visible_height;
11159 w->vscroll = 0;
11160 w->cursor.y += dy;
11161 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11162 }
11163 else /* MATRIX_ROW_PARTIALLY_VISIBLE_AT_BOTTOM_P (w, row)) */
11164 {
11165 int dy = - (row->height - row->visible_height);
11166 w->vscroll = dy;
11167 w->cursor.y += dy;
11168 shift_glyph_matrix (w, matrix, 0, matrix->nrows, dy);
11169 }
11170
11171 /* When we change the cursor y-position of the selected window,
11172 change this_line_y as well so that the display optimization for
11173 the cursor line of the selected window in redisplay_internal uses
11174 the correct y-position. */
11175 if (w == XWINDOW (selected_window))
11176 this_line_y = w->cursor.y;
11177
11178 /* If vscrolling requires a larger glyph matrix, arrange for a fresh
11179 redisplay with larger matrices. */
11180 if (matrix->nrows < required_matrix_height (w))
11181 {
11182 fonts_changed_p = 1;
11183 return 0;
11184 }
11185
11186 return 1;
11187 #endif /* 0 */
11188 }
11189
11190
11191 /* Try scrolling PT into view in window WINDOW. JUST_THIS_ONE_P
11192 non-zero means only WINDOW is redisplayed in redisplay_internal.
11193 TEMP_SCROLL_STEP has the same meaning as scroll_step, and is used
11194 in redisplay_window to bring a partially visible line into view in
11195 the case that only the cursor has moved.
11196
11197 LAST_LINE_MISFIT should be nonzero if we're scrolling because the
11198 last screen line's vertical height extends past the end of the screen.
11199
11200 Value is
11201
11202 1 if scrolling succeeded
11203
11204 0 if scrolling didn't find point.
11205
11206 -1 if new fonts have been loaded so that we must interrupt
11207 redisplay, adjust glyph matrices, and try again. */
11208
11209 enum
11210 {
11211 SCROLLING_SUCCESS,
11212 SCROLLING_FAILED,
11213 SCROLLING_NEED_LARGER_MATRICES
11214 };
11215
11216 static int
11217 try_scrolling (window, just_this_one_p, scroll_conservatively,
11218 scroll_step, temp_scroll_step, last_line_misfit)
11219 Lisp_Object window;
11220 int just_this_one_p;
11221 EMACS_INT scroll_conservatively, scroll_step;
11222 int temp_scroll_step;
11223 int last_line_misfit;
11224 {
11225 struct window *w = XWINDOW (window);
11226 struct frame *f = XFRAME (w->frame);
11227 struct text_pos scroll_margin_pos;
11228 struct text_pos pos;
11229 struct text_pos startp;
11230 struct it it;
11231 Lisp_Object window_end;
11232 int this_scroll_margin;
11233 int dy = 0;
11234 int scroll_max;
11235 int rc;
11236 int amount_to_scroll = 0;
11237 Lisp_Object aggressive;
11238 int height;
11239 int extra_scroll_margin_lines = last_line_misfit ? 1 : 0;
11240
11241 #if GLYPH_DEBUG
11242 debug_method_add (w, "try_scrolling");
11243 #endif
11244
11245 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11246
11247 /* Compute scroll margin height in pixels. We scroll when point is
11248 within this distance from the top or bottom of the window. */
11249 if (scroll_margin > 0)
11250 {
11251 this_scroll_margin = min (scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11252 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11253 }
11254 else
11255 this_scroll_margin = 0;
11256
11257 /* Force scroll_conservatively to have a reasonable value so it doesn't
11258 cause an overflow while computing how much to scroll. */
11259 if (scroll_conservatively)
11260 scroll_conservatively = min (scroll_conservatively,
11261 MOST_POSITIVE_FIXNUM / FRAME_LINE_HEIGHT (f));
11262
11263 /* Compute how much we should try to scroll maximally to bring point
11264 into view. */
11265 if (scroll_step || scroll_conservatively || temp_scroll_step)
11266 scroll_max = max (scroll_step,
11267 max (scroll_conservatively, temp_scroll_step));
11268 else if (NUMBERP (current_buffer->scroll_down_aggressively)
11269 || NUMBERP (current_buffer->scroll_up_aggressively))
11270 /* We're trying to scroll because of aggressive scrolling
11271 but no scroll_step is set. Choose an arbitrary one. Maybe
11272 there should be a variable for this. */
11273 scroll_max = 10;
11274 else
11275 scroll_max = 0;
11276 scroll_max *= FRAME_LINE_HEIGHT (f);
11277
11278 /* Decide whether we have to scroll down. Start at the window end
11279 and move this_scroll_margin up to find the position of the scroll
11280 margin. */
11281 window_end = Fwindow_end (window, Qt);
11282
11283 too_near_end:
11284
11285 CHARPOS (scroll_margin_pos) = XINT (window_end);
11286 BYTEPOS (scroll_margin_pos) = CHAR_TO_BYTE (CHARPOS (scroll_margin_pos));
11287
11288 if (this_scroll_margin || extra_scroll_margin_lines)
11289 {
11290 start_display (&it, w, scroll_margin_pos);
11291 if (this_scroll_margin)
11292 move_it_vertically_backward (&it, this_scroll_margin);
11293 if (extra_scroll_margin_lines)
11294 move_it_by_lines (&it, - extra_scroll_margin_lines, 0);
11295 scroll_margin_pos = it.current.pos;
11296 }
11297
11298 if (PT >= CHARPOS (scroll_margin_pos))
11299 {
11300 int y0;
11301
11302 /* Point is in the scroll margin at the bottom of the window, or
11303 below. Compute a new window start that makes point visible. */
11304
11305 /* Compute the distance from the scroll margin to PT.
11306 Give up if the distance is greater than scroll_max. */
11307 start_display (&it, w, scroll_margin_pos);
11308 y0 = it.current_y;
11309 move_it_to (&it, PT, 0, it.last_visible_y, -1,
11310 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11311
11312 /* To make point visible, we have to move the window start
11313 down so that the line the cursor is in is visible, which
11314 means we have to add in the height of the cursor line. */
11315 dy = line_bottom_y (&it) - y0;
11316
11317 if (dy > scroll_max)
11318 return SCROLLING_FAILED;
11319
11320 /* Move the window start down. If scrolling conservatively,
11321 move it just enough down to make point visible. If
11322 scroll_step is set, move it down by scroll_step. */
11323 start_display (&it, w, startp);
11324
11325 if (scroll_conservatively)
11326 /* Set AMOUNT_TO_SCROLL to at least one line,
11327 and at most scroll_conservatively lines. */
11328 amount_to_scroll
11329 = min (max (dy, FRAME_LINE_HEIGHT (f)),
11330 FRAME_LINE_HEIGHT (f) * scroll_conservatively);
11331 else if (scroll_step || temp_scroll_step)
11332 amount_to_scroll = scroll_max;
11333 else
11334 {
11335 aggressive = current_buffer->scroll_up_aggressively;
11336 height = WINDOW_BOX_TEXT_HEIGHT (w);
11337 if (NUMBERP (aggressive))
11338 {
11339 double float_amount = XFLOATINT (aggressive) * height;
11340 amount_to_scroll = float_amount;
11341 if (amount_to_scroll == 0 && float_amount > 0)
11342 amount_to_scroll = 1;
11343 }
11344 }
11345
11346 if (amount_to_scroll <= 0)
11347 return SCROLLING_FAILED;
11348
11349 /* If moving by amount_to_scroll leaves STARTP unchanged,
11350 move it down one screen line. */
11351
11352 move_it_vertically (&it, amount_to_scroll);
11353 if (CHARPOS (it.current.pos) == CHARPOS (startp))
11354 move_it_by_lines (&it, 1, 1);
11355 startp = it.current.pos;
11356 }
11357 else
11358 {
11359 /* See if point is inside the scroll margin at the top of the
11360 window. */
11361 scroll_margin_pos = startp;
11362 if (this_scroll_margin)
11363 {
11364 start_display (&it, w, startp);
11365 move_it_vertically (&it, this_scroll_margin);
11366 scroll_margin_pos = it.current.pos;
11367 }
11368
11369 if (PT < CHARPOS (scroll_margin_pos))
11370 {
11371 /* Point is in the scroll margin at the top of the window or
11372 above what is displayed in the window. */
11373 int y0;
11374
11375 /* Compute the vertical distance from PT to the scroll
11376 margin position. Give up if distance is greater than
11377 scroll_max. */
11378 SET_TEXT_POS (pos, PT, PT_BYTE);
11379 start_display (&it, w, pos);
11380 y0 = it.current_y;
11381 move_it_to (&it, CHARPOS (scroll_margin_pos), 0,
11382 it.last_visible_y, -1,
11383 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
11384 dy = it.current_y - y0;
11385 if (dy > scroll_max)
11386 return SCROLLING_FAILED;
11387
11388 /* Compute new window start. */
11389 start_display (&it, w, startp);
11390
11391 if (scroll_conservatively)
11392 amount_to_scroll
11393 = max (dy, FRAME_LINE_HEIGHT (f) * max (scroll_step, temp_scroll_step));
11394 else if (scroll_step || temp_scroll_step)
11395 amount_to_scroll = scroll_max;
11396 else
11397 {
11398 aggressive = current_buffer->scroll_down_aggressively;
11399 height = WINDOW_BOX_TEXT_HEIGHT (w);
11400 if (NUMBERP (aggressive))
11401 {
11402 double float_amount = XFLOATINT (aggressive) * height;
11403 amount_to_scroll = float_amount;
11404 if (amount_to_scroll == 0 && float_amount > 0)
11405 amount_to_scroll = 1;
11406 }
11407 }
11408
11409 if (amount_to_scroll <= 0)
11410 return SCROLLING_FAILED;
11411
11412 move_it_vertically_backward (&it, amount_to_scroll);
11413 startp = it.current.pos;
11414 }
11415 }
11416
11417 /* Run window scroll functions. */
11418 startp = run_window_scroll_functions (window, startp);
11419
11420 /* Display the window. Give up if new fonts are loaded, or if point
11421 doesn't appear. */
11422 if (!try_window (window, startp))
11423 rc = SCROLLING_NEED_LARGER_MATRICES;
11424 else if (w->cursor.vpos < 0)
11425 {
11426 clear_glyph_matrix (w->desired_matrix);
11427 rc = SCROLLING_FAILED;
11428 }
11429 else
11430 {
11431 /* Maybe forget recorded base line for line number display. */
11432 if (!just_this_one_p
11433 || current_buffer->clip_changed
11434 || BEG_UNCHANGED < CHARPOS (startp))
11435 w->base_line_number = Qnil;
11436
11437 /* If cursor ends up on a partially visible line,
11438 treat that as being off the bottom of the screen. */
11439 if (! cursor_row_fully_visible_p (w, extra_scroll_margin_lines <= 1, 0))
11440 {
11441 clear_glyph_matrix (w->desired_matrix);
11442 ++extra_scroll_margin_lines;
11443 goto too_near_end;
11444 }
11445 rc = SCROLLING_SUCCESS;
11446 }
11447
11448 return rc;
11449 }
11450
11451
11452 /* Compute a suitable window start for window W if display of W starts
11453 on a continuation line. Value is non-zero if a new window start
11454 was computed.
11455
11456 The new window start will be computed, based on W's width, starting
11457 from the start of the continued line. It is the start of the
11458 screen line with the minimum distance from the old start W->start. */
11459
11460 static int
11461 compute_window_start_on_continuation_line (w)
11462 struct window *w;
11463 {
11464 struct text_pos pos, start_pos;
11465 int window_start_changed_p = 0;
11466
11467 SET_TEXT_POS_FROM_MARKER (start_pos, w->start);
11468
11469 /* If window start is on a continuation line... Window start may be
11470 < BEGV in case there's invisible text at the start of the
11471 buffer (M-x rmail, for example). */
11472 if (CHARPOS (start_pos) > BEGV
11473 && FETCH_BYTE (BYTEPOS (start_pos) - 1) != '\n')
11474 {
11475 struct it it;
11476 struct glyph_row *row;
11477
11478 /* Handle the case that the window start is out of range. */
11479 if (CHARPOS (start_pos) < BEGV)
11480 SET_TEXT_POS (start_pos, BEGV, BEGV_BYTE);
11481 else if (CHARPOS (start_pos) > ZV)
11482 SET_TEXT_POS (start_pos, ZV, ZV_BYTE);
11483
11484 /* Find the start of the continued line. This should be fast
11485 because scan_buffer is fast (newline cache). */
11486 row = w->desired_matrix->rows + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0);
11487 init_iterator (&it, w, CHARPOS (start_pos), BYTEPOS (start_pos),
11488 row, DEFAULT_FACE_ID);
11489 reseat_at_previous_visible_line_start (&it);
11490
11491 /* If the line start is "too far" away from the window start,
11492 say it takes too much time to compute a new window start. */
11493 if (CHARPOS (start_pos) - IT_CHARPOS (it)
11494 < WINDOW_TOTAL_LINES (w) * WINDOW_TOTAL_COLS (w))
11495 {
11496 int min_distance, distance;
11497
11498 /* Move forward by display lines to find the new window
11499 start. If window width was enlarged, the new start can
11500 be expected to be > the old start. If window width was
11501 decreased, the new window start will be < the old start.
11502 So, we're looking for the display line start with the
11503 minimum distance from the old window start. */
11504 pos = it.current.pos;
11505 min_distance = INFINITY;
11506 while ((distance = abs (CHARPOS (start_pos) - IT_CHARPOS (it))),
11507 distance < min_distance)
11508 {
11509 min_distance = distance;
11510 pos = it.current.pos;
11511 move_it_by_lines (&it, 1, 0);
11512 }
11513
11514 /* Set the window start there. */
11515 SET_MARKER_FROM_TEXT_POS (w->start, pos);
11516 window_start_changed_p = 1;
11517 }
11518 }
11519
11520 return window_start_changed_p;
11521 }
11522
11523
11524 /* Try cursor movement in case text has not changed in window WINDOW,
11525 with window start STARTP. Value is
11526
11527 CURSOR_MOVEMENT_SUCCESS if successful
11528
11529 CURSOR_MOVEMENT_CANNOT_BE_USED if this method cannot be used
11530
11531 CURSOR_MOVEMENT_MUST_SCROLL if we know we have to scroll the
11532 display. *SCROLL_STEP is set to 1, under certain circumstances, if
11533 we want to scroll as if scroll-step were set to 1. See the code.
11534
11535 CURSOR_MOVEMENT_NEED_LARGER_MATRICES if we need larger matrices, in
11536 which case we have to abort this redisplay, and adjust matrices
11537 first. */
11538
11539 enum
11540 {
11541 CURSOR_MOVEMENT_SUCCESS,
11542 CURSOR_MOVEMENT_CANNOT_BE_USED,
11543 CURSOR_MOVEMENT_MUST_SCROLL,
11544 CURSOR_MOVEMENT_NEED_LARGER_MATRICES
11545 };
11546
11547 static int
11548 try_cursor_movement (window, startp, scroll_step)
11549 Lisp_Object window;
11550 struct text_pos startp;
11551 int *scroll_step;
11552 {
11553 struct window *w = XWINDOW (window);
11554 struct frame *f = XFRAME (w->frame);
11555 int rc = CURSOR_MOVEMENT_CANNOT_BE_USED;
11556
11557 #if GLYPH_DEBUG
11558 if (inhibit_try_cursor_movement)
11559 return rc;
11560 #endif
11561
11562 /* Handle case where text has not changed, only point, and it has
11563 not moved off the frame. */
11564 if (/* Point may be in this window. */
11565 PT >= CHARPOS (startp)
11566 /* Selective display hasn't changed. */
11567 && !current_buffer->clip_changed
11568 /* Function force-mode-line-update is used to force a thorough
11569 redisplay. It sets either windows_or_buffers_changed or
11570 update_mode_lines. So don't take a shortcut here for these
11571 cases. */
11572 && !update_mode_lines
11573 && !windows_or_buffers_changed
11574 && !cursor_type_changed
11575 /* Can't use this case if highlighting a region. When a
11576 region exists, cursor movement has to do more than just
11577 set the cursor. */
11578 && !(!NILP (Vtransient_mark_mode)
11579 && !NILP (current_buffer->mark_active))
11580 && NILP (w->region_showing)
11581 && NILP (Vshow_trailing_whitespace)
11582 /* Right after splitting windows, last_point may be nil. */
11583 && INTEGERP (w->last_point)
11584 /* This code is not used for mini-buffer for the sake of the case
11585 of redisplaying to replace an echo area message; since in
11586 that case the mini-buffer contents per se are usually
11587 unchanged. This code is of no real use in the mini-buffer
11588 since the handling of this_line_start_pos, etc., in redisplay
11589 handles the same cases. */
11590 && !EQ (window, minibuf_window)
11591 /* When splitting windows or for new windows, it happens that
11592 redisplay is called with a nil window_end_vpos or one being
11593 larger than the window. This should really be fixed in
11594 window.c. I don't have this on my list, now, so we do
11595 approximately the same as the old redisplay code. --gerd. */
11596 && INTEGERP (w->window_end_vpos)
11597 && XFASTINT (w->window_end_vpos) < w->current_matrix->nrows
11598 && (FRAME_WINDOW_P (f)
11599 || !overlay_arrow_in_current_buffer_p ()))
11600 {
11601 int this_scroll_margin, top_scroll_margin;
11602 struct glyph_row *row = NULL;
11603
11604 #if GLYPH_DEBUG
11605 debug_method_add (w, "cursor movement");
11606 #endif
11607
11608 /* Scroll if point within this distance from the top or bottom
11609 of the window. This is a pixel value. */
11610 this_scroll_margin = max (0, scroll_margin);
11611 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
11612 this_scroll_margin *= FRAME_LINE_HEIGHT (f);
11613
11614 top_scroll_margin = this_scroll_margin;
11615 if (WINDOW_WANTS_HEADER_LINE_P (w))
11616 top_scroll_margin += CURRENT_HEADER_LINE_HEIGHT (w);
11617
11618 /* Start with the row the cursor was displayed during the last
11619 not paused redisplay. Give up if that row is not valid. */
11620 if (w->last_cursor.vpos < 0
11621 || w->last_cursor.vpos >= w->current_matrix->nrows)
11622 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11623 else
11624 {
11625 row = MATRIX_ROW (w->current_matrix, w->last_cursor.vpos);
11626 if (row->mode_line_p)
11627 ++row;
11628 if (!row->enabled_p)
11629 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11630 }
11631
11632 if (rc == CURSOR_MOVEMENT_CANNOT_BE_USED)
11633 {
11634 int scroll_p = 0;
11635 int last_y = window_text_bottom_y (w) - this_scroll_margin;
11636
11637 if (PT > XFASTINT (w->last_point))
11638 {
11639 /* Point has moved forward. */
11640 while (MATRIX_ROW_END_CHARPOS (row) < PT
11641 && MATRIX_ROW_BOTTOM_Y (row) < last_y)
11642 {
11643 xassert (row->enabled_p);
11644 ++row;
11645 }
11646
11647 /* The end position of a row equals the start position
11648 of the next row. If PT is there, we would rather
11649 display it in the next line. */
11650 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11651 && MATRIX_ROW_END_CHARPOS (row) == PT
11652 && !cursor_row_p (w, row))
11653 ++row;
11654
11655 /* If within the scroll margin, scroll. Note that
11656 MATRIX_ROW_BOTTOM_Y gives the pixel position at which
11657 the next line would be drawn, and that
11658 this_scroll_margin can be zero. */
11659 if (MATRIX_ROW_BOTTOM_Y (row) > last_y
11660 || PT > MATRIX_ROW_END_CHARPOS (row)
11661 /* Line is completely visible last line in window
11662 and PT is to be set in the next line. */
11663 || (MATRIX_ROW_BOTTOM_Y (row) == last_y
11664 && PT == MATRIX_ROW_END_CHARPOS (row)
11665 && !row->ends_at_zv_p
11666 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
11667 scroll_p = 1;
11668 }
11669 else if (PT < XFASTINT (w->last_point))
11670 {
11671 /* Cursor has to be moved backward. Note that PT >=
11672 CHARPOS (startp) because of the outer if-statement. */
11673 while (!row->mode_line_p
11674 && (MATRIX_ROW_START_CHARPOS (row) > PT
11675 || (MATRIX_ROW_START_CHARPOS (row) == PT
11676 && MATRIX_ROW_STARTS_IN_MIDDLE_OF_CHAR_P (row)))
11677 && (row->y > top_scroll_margin
11678 || CHARPOS (startp) == BEGV))
11679 {
11680 xassert (row->enabled_p);
11681 --row;
11682 }
11683
11684 /* Consider the following case: Window starts at BEGV,
11685 there is invisible, intangible text at BEGV, so that
11686 display starts at some point START > BEGV. It can
11687 happen that we are called with PT somewhere between
11688 BEGV and START. Try to handle that case. */
11689 if (row < w->current_matrix->rows
11690 || row->mode_line_p)
11691 {
11692 row = w->current_matrix->rows;
11693 if (row->mode_line_p)
11694 ++row;
11695 }
11696
11697 /* Due to newlines in overlay strings, we may have to
11698 skip forward over overlay strings. */
11699 while (MATRIX_ROW_BOTTOM_Y (row) < last_y
11700 && MATRIX_ROW_END_CHARPOS (row) == PT
11701 && !cursor_row_p (w, row))
11702 ++row;
11703
11704 /* If within the scroll margin, scroll. */
11705 if (row->y < top_scroll_margin
11706 && CHARPOS (startp) != BEGV)
11707 scroll_p = 1;
11708 }
11709 else
11710 {
11711 /* Cursor did not move. So don't scroll even if cursor line
11712 is partially visible, as it was so before. */
11713 rc = CURSOR_MOVEMENT_SUCCESS;
11714 }
11715
11716 if (PT < MATRIX_ROW_START_CHARPOS (row)
11717 || PT > MATRIX_ROW_END_CHARPOS (row))
11718 {
11719 /* if PT is not in the glyph row, give up. */
11720 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11721 }
11722 else if (rc != CURSOR_MOVEMENT_SUCCESS
11723 && MATRIX_ROW_PARTIALLY_VISIBLE_P (w, row)
11724 && make_cursor_line_fully_visible_p)
11725 {
11726 if (PT == MATRIX_ROW_END_CHARPOS (row)
11727 && !row->ends_at_zv_p
11728 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
11729 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11730 else if (row->height > window_box_height (w))
11731 {
11732 /* If we end up in a partially visible line, let's
11733 make it fully visible, except when it's taller
11734 than the window, in which case we can't do much
11735 about it. */
11736 *scroll_step = 1;
11737 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11738 }
11739 else
11740 {
11741 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11742 if (!cursor_row_fully_visible_p (w, 0, 1))
11743 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11744 else
11745 rc = CURSOR_MOVEMENT_SUCCESS;
11746 }
11747 }
11748 else if (scroll_p)
11749 rc = CURSOR_MOVEMENT_MUST_SCROLL;
11750 else
11751 {
11752 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
11753 rc = CURSOR_MOVEMENT_SUCCESS;
11754 }
11755 }
11756 }
11757
11758 return rc;
11759 }
11760
11761 void
11762 set_vertical_scroll_bar (w)
11763 struct window *w;
11764 {
11765 int start, end, whole;
11766
11767 /* Calculate the start and end positions for the current window.
11768 At some point, it would be nice to choose between scrollbars
11769 which reflect the whole buffer size, with special markers
11770 indicating narrowing, and scrollbars which reflect only the
11771 visible region.
11772
11773 Note that mini-buffers sometimes aren't displaying any text. */
11774 if (!MINI_WINDOW_P (w)
11775 || (w == XWINDOW (minibuf_window)
11776 && NILP (echo_area_buffer[0])))
11777 {
11778 struct buffer *buf = XBUFFER (w->buffer);
11779 whole = BUF_ZV (buf) - BUF_BEGV (buf);
11780 start = marker_position (w->start) - BUF_BEGV (buf);
11781 /* I don't think this is guaranteed to be right. For the
11782 moment, we'll pretend it is. */
11783 end = BUF_Z (buf) - XFASTINT (w->window_end_pos) - BUF_BEGV (buf);
11784
11785 if (end < start)
11786 end = start;
11787 if (whole < (end - start))
11788 whole = end - start;
11789 }
11790 else
11791 start = end = whole = 0;
11792
11793 /* Indicate what this scroll bar ought to be displaying now. */
11794 set_vertical_scroll_bar_hook (w, end - start, whole, start);
11795 }
11796
11797
11798 /* Redisplay leaf window WINDOW. JUST_THIS_ONE_P non-zero means only
11799 selected_window is redisplayed.
11800
11801 We can return without actually redisplaying the window if
11802 fonts_changed_p is nonzero. In that case, redisplay_internal will
11803 retry. */
11804
11805 static void
11806 redisplay_window (window, just_this_one_p)
11807 Lisp_Object window;
11808 int just_this_one_p;
11809 {
11810 struct window *w = XWINDOW (window);
11811 struct frame *f = XFRAME (w->frame);
11812 struct buffer *buffer = XBUFFER (w->buffer);
11813 struct buffer *old = current_buffer;
11814 struct text_pos lpoint, opoint, startp;
11815 int update_mode_line;
11816 int tem;
11817 struct it it;
11818 /* Record it now because it's overwritten. */
11819 int current_matrix_up_to_date_p = 0;
11820 int used_current_matrix_p = 0;
11821 /* This is less strict than current_matrix_up_to_date_p.
11822 It indictes that the buffer contents and narrowing are unchanged. */
11823 int buffer_unchanged_p = 0;
11824 int temp_scroll_step = 0;
11825 int count = SPECPDL_INDEX ();
11826 int rc;
11827 int centering_position = -1;
11828 int last_line_misfit = 0;
11829
11830 SET_TEXT_POS (lpoint, PT, PT_BYTE);
11831 opoint = lpoint;
11832
11833 /* W must be a leaf window here. */
11834 xassert (!NILP (w->buffer));
11835 #if GLYPH_DEBUG
11836 *w->desired_matrix->method = 0;
11837 #endif
11838
11839 specbind (Qinhibit_point_motion_hooks, Qt);
11840
11841 reconsider_clip_changes (w, buffer);
11842
11843 /* Has the mode line to be updated? */
11844 update_mode_line = (!NILP (w->update_mode_line)
11845 || update_mode_lines
11846 || buffer->clip_changed
11847 || buffer->prevent_redisplay_optimizations_p);
11848
11849 if (MINI_WINDOW_P (w))
11850 {
11851 if (w == XWINDOW (echo_area_window)
11852 && !NILP (echo_area_buffer[0]))
11853 {
11854 if (update_mode_line)
11855 /* We may have to update a tty frame's menu bar or a
11856 tool-bar. Example `M-x C-h C-h C-g'. */
11857 goto finish_menu_bars;
11858 else
11859 /* We've already displayed the echo area glyphs in this window. */
11860 goto finish_scroll_bars;
11861 }
11862 else if ((w != XWINDOW (minibuf_window)
11863 || minibuf_level == 0)
11864 /* When buffer is nonempty, redisplay window normally. */
11865 && BUF_Z (XBUFFER (w->buffer)) == BUF_BEG (XBUFFER (w->buffer))
11866 /* Quail displays non-mini buffers in minibuffer window.
11867 In that case, redisplay the window normally. */
11868 && !NILP (Fmemq (w->buffer, Vminibuffer_list)))
11869 {
11870 /* W is a mini-buffer window, but it's not active, so clear
11871 it. */
11872 int yb = window_text_bottom_y (w);
11873 struct glyph_row *row;
11874 int y;
11875
11876 for (y = 0, row = w->desired_matrix->rows;
11877 y < yb;
11878 y += row->height, ++row)
11879 blank_row (w, row, y);
11880 goto finish_scroll_bars;
11881 }
11882
11883 clear_glyph_matrix (w->desired_matrix);
11884 }
11885
11886 /* Otherwise set up data on this window; select its buffer and point
11887 value. */
11888 /* Really select the buffer, for the sake of buffer-local
11889 variables. */
11890 set_buffer_internal_1 (XBUFFER (w->buffer));
11891 SET_TEXT_POS (opoint, PT, PT_BYTE);
11892
11893 current_matrix_up_to_date_p
11894 = (!NILP (w->window_end_valid)
11895 && !current_buffer->clip_changed
11896 && !current_buffer->prevent_redisplay_optimizations_p
11897 && XFASTINT (w->last_modified) >= MODIFF
11898 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11899
11900 buffer_unchanged_p
11901 = (!NILP (w->window_end_valid)
11902 && !current_buffer->clip_changed
11903 && XFASTINT (w->last_modified) >= MODIFF
11904 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF);
11905
11906 /* When windows_or_buffers_changed is non-zero, we can't rely on
11907 the window end being valid, so set it to nil there. */
11908 if (windows_or_buffers_changed)
11909 {
11910 /* If window starts on a continuation line, maybe adjust the
11911 window start in case the window's width changed. */
11912 if (XMARKER (w->start)->buffer == current_buffer)
11913 compute_window_start_on_continuation_line (w);
11914
11915 w->window_end_valid = Qnil;
11916 }
11917
11918 /* Some sanity checks. */
11919 CHECK_WINDOW_END (w);
11920 if (Z == Z_BYTE && CHARPOS (opoint) != BYTEPOS (opoint))
11921 abort ();
11922 if (BYTEPOS (opoint) < CHARPOS (opoint))
11923 abort ();
11924
11925 /* If %c is in mode line, update it if needed. */
11926 if (!NILP (w->column_number_displayed)
11927 /* This alternative quickly identifies a common case
11928 where no change is needed. */
11929 && !(PT == XFASTINT (w->last_point)
11930 && XFASTINT (w->last_modified) >= MODIFF
11931 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)
11932 && (XFASTINT (w->column_number_displayed)
11933 != (int) current_column ())) /* iftc */
11934 update_mode_line = 1;
11935
11936 /* Count number of windows showing the selected buffer. An indirect
11937 buffer counts as its base buffer. */
11938 if (!just_this_one_p)
11939 {
11940 struct buffer *current_base, *window_base;
11941 current_base = current_buffer;
11942 window_base = XBUFFER (XWINDOW (selected_window)->buffer);
11943 if (current_base->base_buffer)
11944 current_base = current_base->base_buffer;
11945 if (window_base->base_buffer)
11946 window_base = window_base->base_buffer;
11947 if (current_base == window_base)
11948 buffer_shared++;
11949 }
11950
11951 /* Point refers normally to the selected window. For any other
11952 window, set up appropriate value. */
11953 if (!EQ (window, selected_window))
11954 {
11955 int new_pt = XMARKER (w->pointm)->charpos;
11956 int new_pt_byte = marker_byte_position (w->pointm);
11957 if (new_pt < BEGV)
11958 {
11959 new_pt = BEGV;
11960 new_pt_byte = BEGV_BYTE;
11961 set_marker_both (w->pointm, Qnil, BEGV, BEGV_BYTE);
11962 }
11963 else if (new_pt > (ZV - 1))
11964 {
11965 new_pt = ZV;
11966 new_pt_byte = ZV_BYTE;
11967 set_marker_both (w->pointm, Qnil, ZV, ZV_BYTE);
11968 }
11969
11970 /* We don't use SET_PT so that the point-motion hooks don't run. */
11971 TEMP_SET_PT_BOTH (new_pt, new_pt_byte);
11972 }
11973
11974 /* If any of the character widths specified in the display table
11975 have changed, invalidate the width run cache. It's true that
11976 this may be a bit late to catch such changes, but the rest of
11977 redisplay goes (non-fatally) haywire when the display table is
11978 changed, so why should we worry about doing any better? */
11979 if (current_buffer->width_run_cache)
11980 {
11981 struct Lisp_Char_Table *disptab = buffer_display_table ();
11982
11983 if (! disptab_matches_widthtab (disptab,
11984 XVECTOR (current_buffer->width_table)))
11985 {
11986 invalidate_region_cache (current_buffer,
11987 current_buffer->width_run_cache,
11988 BEG, Z);
11989 recompute_width_table (current_buffer, disptab);
11990 }
11991 }
11992
11993 /* If window-start is screwed up, choose a new one. */
11994 if (XMARKER (w->start)->buffer != current_buffer)
11995 goto recenter;
11996
11997 SET_TEXT_POS_FROM_MARKER (startp, w->start);
11998
11999 /* If someone specified a new starting point but did not insist,
12000 check whether it can be used. */
12001 if (!NILP (w->optional_new_start)
12002 && CHARPOS (startp) >= BEGV
12003 && CHARPOS (startp) <= ZV)
12004 {
12005 w->optional_new_start = Qnil;
12006 start_display (&it, w, startp);
12007 move_it_to (&it, PT, 0, it.last_visible_y, -1,
12008 MOVE_TO_POS | MOVE_TO_X | MOVE_TO_Y);
12009 if (IT_CHARPOS (it) == PT)
12010 w->force_start = Qt;
12011 /* IT may overshoot PT if text at PT is invisible. */
12012 else if (IT_CHARPOS (it) > PT && CHARPOS (startp) <= PT)
12013 w->force_start = Qt;
12014
12015
12016 }
12017
12018 /* Handle case where place to start displaying has been specified,
12019 unless the specified location is outside the accessible range. */
12020 if (!NILP (w->force_start)
12021 || w->frozen_window_start_p)
12022 {
12023 /* We set this later on if we have to adjust point. */
12024 int new_vpos = -1;
12025
12026 w->force_start = Qnil;
12027 w->vscroll = 0;
12028 w->window_end_valid = Qnil;
12029
12030 /* Forget any recorded base line for line number display. */
12031 if (!buffer_unchanged_p)
12032 w->base_line_number = Qnil;
12033
12034 /* Redisplay the mode line. Select the buffer properly for that.
12035 Also, run the hook window-scroll-functions
12036 because we have scrolled. */
12037 /* Note, we do this after clearing force_start because
12038 if there's an error, it is better to forget about force_start
12039 than to get into an infinite loop calling the hook functions
12040 and having them get more errors. */
12041 if (!update_mode_line
12042 || ! NILP (Vwindow_scroll_functions))
12043 {
12044 update_mode_line = 1;
12045 w->update_mode_line = Qt;
12046 startp = run_window_scroll_functions (window, startp);
12047 }
12048
12049 w->last_modified = make_number (0);
12050 w->last_overlay_modified = make_number (0);
12051 if (CHARPOS (startp) < BEGV)
12052 SET_TEXT_POS (startp, BEGV, BEGV_BYTE);
12053 else if (CHARPOS (startp) > ZV)
12054 SET_TEXT_POS (startp, ZV, ZV_BYTE);
12055
12056 /* Redisplay, then check if cursor has been set during the
12057 redisplay. Give up if new fonts were loaded. */
12058 if (!try_window (window, startp))
12059 {
12060 w->force_start = Qt;
12061 clear_glyph_matrix (w->desired_matrix);
12062 goto need_larger_matrices;
12063 }
12064
12065 if (w->cursor.vpos < 0 && !w->frozen_window_start_p)
12066 {
12067 /* If point does not appear, try to move point so it does
12068 appear. The desired matrix has been built above, so we
12069 can use it here. */
12070 new_vpos = window_box_height (w) / 2;
12071 }
12072
12073 if (!cursor_row_fully_visible_p (w, 0, 0))
12074 {
12075 /* Point does appear, but on a line partly visible at end of window.
12076 Move it back to a fully-visible line. */
12077 new_vpos = window_box_height (w);
12078 }
12079
12080 /* If we need to move point for either of the above reasons,
12081 now actually do it. */
12082 if (new_vpos >= 0)
12083 {
12084 struct glyph_row *row;
12085
12086 row = MATRIX_FIRST_TEXT_ROW (w->desired_matrix);
12087 while (MATRIX_ROW_BOTTOM_Y (row) < new_vpos)
12088 ++row;
12089
12090 TEMP_SET_PT_BOTH (MATRIX_ROW_START_CHARPOS (row),
12091 MATRIX_ROW_START_BYTEPOS (row));
12092
12093 if (w != XWINDOW (selected_window))
12094 set_marker_both (w->pointm, Qnil, PT, PT_BYTE);
12095 else if (current_buffer == old)
12096 SET_TEXT_POS (lpoint, PT, PT_BYTE);
12097
12098 set_cursor_from_row (w, row, w->desired_matrix, 0, 0, 0, 0);
12099
12100 /* If we are highlighting the region, then we just changed
12101 the region, so redisplay to show it. */
12102 if (!NILP (Vtransient_mark_mode)
12103 && !NILP (current_buffer->mark_active))
12104 {
12105 clear_glyph_matrix (w->desired_matrix);
12106 if (!try_window (window, startp))
12107 goto need_larger_matrices;
12108 }
12109 }
12110
12111 #if GLYPH_DEBUG
12112 debug_method_add (w, "forced window start");
12113 #endif
12114 goto done;
12115 }
12116
12117 /* Handle case where text has not changed, only point, and it has
12118 not moved off the frame, and we are not retrying after hscroll.
12119 (current_matrix_up_to_date_p is nonzero when retrying.) */
12120 if (current_matrix_up_to_date_p
12121 && (rc = try_cursor_movement (window, startp, &temp_scroll_step),
12122 rc != CURSOR_MOVEMENT_CANNOT_BE_USED))
12123 {
12124 switch (rc)
12125 {
12126 case CURSOR_MOVEMENT_SUCCESS:
12127 used_current_matrix_p = 1;
12128 goto done;
12129
12130 #if 0 /* try_cursor_movement never returns this value. */
12131 case CURSOR_MOVEMENT_NEED_LARGER_MATRICES:
12132 goto need_larger_matrices;
12133 #endif
12134
12135 case CURSOR_MOVEMENT_MUST_SCROLL:
12136 goto try_to_scroll;
12137
12138 default:
12139 abort ();
12140 }
12141 }
12142 /* If current starting point was originally the beginning of a line
12143 but no longer is, find a new starting point. */
12144 else if (!NILP (w->start_at_line_beg)
12145 && !(CHARPOS (startp) <= BEGV
12146 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n'))
12147 {
12148 #if GLYPH_DEBUG
12149 debug_method_add (w, "recenter 1");
12150 #endif
12151 goto recenter;
12152 }
12153
12154 /* Try scrolling with try_window_id. Value is > 0 if update has
12155 been done, it is -1 if we know that the same window start will
12156 not work. It is 0 if unsuccessful for some other reason. */
12157 else if ((tem = try_window_id (w)) != 0)
12158 {
12159 #if GLYPH_DEBUG
12160 debug_method_add (w, "try_window_id %d", tem);
12161 #endif
12162
12163 if (fonts_changed_p)
12164 goto need_larger_matrices;
12165 if (tem > 0)
12166 goto done;
12167
12168 /* Otherwise try_window_id has returned -1 which means that we
12169 don't want the alternative below this comment to execute. */
12170 }
12171 else if (CHARPOS (startp) >= BEGV
12172 && CHARPOS (startp) <= ZV
12173 && PT >= CHARPOS (startp)
12174 && (CHARPOS (startp) < ZV
12175 /* Avoid starting at end of buffer. */
12176 || CHARPOS (startp) == BEGV
12177 || (XFASTINT (w->last_modified) >= MODIFF
12178 && XFASTINT (w->last_overlay_modified) >= OVERLAY_MODIFF)))
12179 {
12180 #if GLYPH_DEBUG
12181 debug_method_add (w, "same window start");
12182 #endif
12183
12184 /* Try to redisplay starting at same place as before.
12185 If point has not moved off frame, accept the results. */
12186 if (!current_matrix_up_to_date_p
12187 /* Don't use try_window_reusing_current_matrix in this case
12188 because a window scroll function can have changed the
12189 buffer. */
12190 || !NILP (Vwindow_scroll_functions)
12191 || MINI_WINDOW_P (w)
12192 || !(used_current_matrix_p
12193 = try_window_reusing_current_matrix (w)))
12194 {
12195 IF_DEBUG (debug_method_add (w, "1"));
12196 try_window (window, startp);
12197 }
12198
12199 if (fonts_changed_p)
12200 goto need_larger_matrices;
12201
12202 if (w->cursor.vpos >= 0)
12203 {
12204 if (!just_this_one_p
12205 || current_buffer->clip_changed
12206 || BEG_UNCHANGED < CHARPOS (startp))
12207 /* Forget any recorded base line for line number display. */
12208 w->base_line_number = Qnil;
12209
12210 if (!cursor_row_fully_visible_p (w, 1, 0))
12211 {
12212 clear_glyph_matrix (w->desired_matrix);
12213 last_line_misfit = 1;
12214 }
12215 /* Drop through and scroll. */
12216 else
12217 goto done;
12218 }
12219 else
12220 clear_glyph_matrix (w->desired_matrix);
12221 }
12222
12223 try_to_scroll:
12224
12225 w->last_modified = make_number (0);
12226 w->last_overlay_modified = make_number (0);
12227
12228 /* Redisplay the mode line. Select the buffer properly for that. */
12229 if (!update_mode_line)
12230 {
12231 update_mode_line = 1;
12232 w->update_mode_line = Qt;
12233 }
12234
12235 /* Try to scroll by specified few lines. */
12236 if ((scroll_conservatively
12237 || scroll_step
12238 || temp_scroll_step
12239 || NUMBERP (current_buffer->scroll_up_aggressively)
12240 || NUMBERP (current_buffer->scroll_down_aggressively))
12241 && !current_buffer->clip_changed
12242 && CHARPOS (startp) >= BEGV
12243 && CHARPOS (startp) <= ZV)
12244 {
12245 /* The function returns -1 if new fonts were loaded, 1 if
12246 successful, 0 if not successful. */
12247 int rc = try_scrolling (window, just_this_one_p,
12248 scroll_conservatively,
12249 scroll_step,
12250 temp_scroll_step, last_line_misfit);
12251 switch (rc)
12252 {
12253 case SCROLLING_SUCCESS:
12254 goto done;
12255
12256 case SCROLLING_NEED_LARGER_MATRICES:
12257 goto need_larger_matrices;
12258
12259 case SCROLLING_FAILED:
12260 break;
12261
12262 default:
12263 abort ();
12264 }
12265 }
12266
12267 /* Finally, just choose place to start which centers point */
12268
12269 recenter:
12270 if (centering_position < 0)
12271 centering_position = window_box_height (w) / 2;
12272
12273 #if GLYPH_DEBUG
12274 debug_method_add (w, "recenter");
12275 #endif
12276
12277 /* w->vscroll = 0; */
12278
12279 /* Forget any previously recorded base line for line number display. */
12280 if (!buffer_unchanged_p)
12281 w->base_line_number = Qnil;
12282
12283 /* Move backward half the height of the window. */
12284 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12285 it.current_y = it.last_visible_y;
12286 move_it_vertically_backward (&it, centering_position);
12287 xassert (IT_CHARPOS (it) >= BEGV);
12288
12289 /* The function move_it_vertically_backward may move over more
12290 than the specified y-distance. If it->w is small, e.g. a
12291 mini-buffer window, we may end up in front of the window's
12292 display area. Start displaying at the start of the line
12293 containing PT in this case. */
12294 if (it.current_y <= 0)
12295 {
12296 init_iterator (&it, w, PT, PT_BYTE, NULL, DEFAULT_FACE_ID);
12297 move_it_vertically_backward (&it, 0);
12298 #if 0
12299 /* I think this assert is bogus if buffer contains
12300 invisible text or images. KFS. */
12301 xassert (IT_CHARPOS (it) <= PT);
12302 #endif
12303 it.current_y = 0;
12304 }
12305
12306 it.current_x = it.hpos = 0;
12307
12308 /* Set startp here explicitly in case that helps avoid an infinite loop
12309 in case the window-scroll-functions functions get errors. */
12310 set_marker_both (w->start, Qnil, IT_CHARPOS (it), IT_BYTEPOS (it));
12311
12312 /* Run scroll hooks. */
12313 startp = run_window_scroll_functions (window, it.current.pos);
12314
12315 /* Redisplay the window. */
12316 if (!current_matrix_up_to_date_p
12317 || windows_or_buffers_changed
12318 || cursor_type_changed
12319 /* Don't use try_window_reusing_current_matrix in this case
12320 because it can have changed the buffer. */
12321 || !NILP (Vwindow_scroll_functions)
12322 || !just_this_one_p
12323 || MINI_WINDOW_P (w)
12324 || !(used_current_matrix_p
12325 = try_window_reusing_current_matrix (w)))
12326 try_window (window, startp);
12327
12328 /* If new fonts have been loaded (due to fontsets), give up. We
12329 have to start a new redisplay since we need to re-adjust glyph
12330 matrices. */
12331 if (fonts_changed_p)
12332 goto need_larger_matrices;
12333
12334 /* If cursor did not appear assume that the middle of the window is
12335 in the first line of the window. Do it again with the next line.
12336 (Imagine a window of height 100, displaying two lines of height
12337 60. Moving back 50 from it->last_visible_y will end in the first
12338 line.) */
12339 if (w->cursor.vpos < 0)
12340 {
12341 if (!NILP (w->window_end_valid)
12342 && PT >= Z - XFASTINT (w->window_end_pos))
12343 {
12344 clear_glyph_matrix (w->desired_matrix);
12345 move_it_by_lines (&it, 1, 0);
12346 try_window (window, it.current.pos);
12347 }
12348 else if (PT < IT_CHARPOS (it))
12349 {
12350 clear_glyph_matrix (w->desired_matrix);
12351 move_it_by_lines (&it, -1, 0);
12352 try_window (window, it.current.pos);
12353 }
12354 else
12355 {
12356 /* Not much we can do about it. */
12357 }
12358 }
12359
12360 /* Consider the following case: Window starts at BEGV, there is
12361 invisible, intangible text at BEGV, so that display starts at
12362 some point START > BEGV. It can happen that we are called with
12363 PT somewhere between BEGV and START. Try to handle that case. */
12364 if (w->cursor.vpos < 0)
12365 {
12366 struct glyph_row *row = w->current_matrix->rows;
12367 if (row->mode_line_p)
12368 ++row;
12369 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
12370 }
12371
12372 if (!cursor_row_fully_visible_p (w, 0, 0))
12373 {
12374 /* If vscroll is enabled, disable it and try again. */
12375 if (w->vscroll)
12376 {
12377 w->vscroll = 0;
12378 clear_glyph_matrix (w->desired_matrix);
12379 goto recenter;
12380 }
12381
12382 /* If centering point failed to make the whole line visible,
12383 put point at the top instead. That has to make the whole line
12384 visible, if it can be done. */
12385 if (centering_position == 0)
12386 goto done;
12387
12388 clear_glyph_matrix (w->desired_matrix);
12389 centering_position = 0;
12390 goto recenter;
12391 }
12392
12393 done:
12394
12395 SET_TEXT_POS_FROM_MARKER (startp, w->start);
12396 w->start_at_line_beg = ((CHARPOS (startp) == BEGV
12397 || FETCH_BYTE (BYTEPOS (startp) - 1) == '\n')
12398 ? Qt : Qnil);
12399
12400 /* Display the mode line, if we must. */
12401 if ((update_mode_line
12402 /* If window not full width, must redo its mode line
12403 if (a) the window to its side is being redone and
12404 (b) we do a frame-based redisplay. This is a consequence
12405 of how inverted lines are drawn in frame-based redisplay. */
12406 || (!just_this_one_p
12407 && !FRAME_WINDOW_P (f)
12408 && !WINDOW_FULL_WIDTH_P (w))
12409 /* Line number to display. */
12410 || INTEGERP (w->base_line_pos)
12411 /* Column number is displayed and different from the one displayed. */
12412 || (!NILP (w->column_number_displayed)
12413 && (XFASTINT (w->column_number_displayed)
12414 != (int) current_column ()))) /* iftc */
12415 /* This means that the window has a mode line. */
12416 && (WINDOW_WANTS_MODELINE_P (w)
12417 || WINDOW_WANTS_HEADER_LINE_P (w)))
12418 {
12419 display_mode_lines (w);
12420
12421 /* If mode line height has changed, arrange for a thorough
12422 immediate redisplay using the correct mode line height. */
12423 if (WINDOW_WANTS_MODELINE_P (w)
12424 && CURRENT_MODE_LINE_HEIGHT (w) != DESIRED_MODE_LINE_HEIGHT (w))
12425 {
12426 fonts_changed_p = 1;
12427 MATRIX_MODE_LINE_ROW (w->current_matrix)->height
12428 = DESIRED_MODE_LINE_HEIGHT (w);
12429 }
12430
12431 /* If top line height has changed, arrange for a thorough
12432 immediate redisplay using the correct mode line height. */
12433 if (WINDOW_WANTS_HEADER_LINE_P (w)
12434 && CURRENT_HEADER_LINE_HEIGHT (w) != DESIRED_HEADER_LINE_HEIGHT (w))
12435 {
12436 fonts_changed_p = 1;
12437 MATRIX_HEADER_LINE_ROW (w->current_matrix)->height
12438 = DESIRED_HEADER_LINE_HEIGHT (w);
12439 }
12440
12441 if (fonts_changed_p)
12442 goto need_larger_matrices;
12443 }
12444
12445 if (!line_number_displayed
12446 && !BUFFERP (w->base_line_pos))
12447 {
12448 w->base_line_pos = Qnil;
12449 w->base_line_number = Qnil;
12450 }
12451
12452 finish_menu_bars:
12453
12454 /* When we reach a frame's selected window, redo the frame's menu bar. */
12455 if (update_mode_line
12456 && EQ (FRAME_SELECTED_WINDOW (f), window))
12457 {
12458 int redisplay_menu_p = 0;
12459 int redisplay_tool_bar_p = 0;
12460
12461 if (FRAME_WINDOW_P (f))
12462 {
12463 #if defined (USE_X_TOOLKIT) || defined (HAVE_NTGUI) || defined (MAC_OS) \
12464 || defined (USE_GTK)
12465 redisplay_menu_p = FRAME_EXTERNAL_MENU_BAR (f);
12466 #else
12467 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12468 #endif
12469 }
12470 else
12471 redisplay_menu_p = FRAME_MENU_BAR_LINES (f) > 0;
12472
12473 if (redisplay_menu_p)
12474 display_menu_bar (w);
12475
12476 #ifdef HAVE_WINDOW_SYSTEM
12477 #ifdef USE_GTK
12478 redisplay_tool_bar_p = FRAME_EXTERNAL_TOOL_BAR (f);
12479 #else
12480 redisplay_tool_bar_p = WINDOWP (f->tool_bar_window)
12481 && (FRAME_TOOL_BAR_LINES (f) > 0
12482 || auto_resize_tool_bars_p);
12483
12484 #endif
12485
12486 if (redisplay_tool_bar_p)
12487 redisplay_tool_bar (f);
12488 #endif
12489 }
12490
12491 #ifdef HAVE_WINDOW_SYSTEM
12492 if (FRAME_WINDOW_P (f)
12493 && update_window_fringes (w, 0)
12494 && !just_this_one_p
12495 && (used_current_matrix_p || overlay_arrow_seen)
12496 && !w->pseudo_window_p)
12497 {
12498 update_begin (f);
12499 BLOCK_INPUT;
12500 if (draw_window_fringes (w, 1))
12501 x_draw_vertical_border (w);
12502 UNBLOCK_INPUT;
12503 update_end (f);
12504 }
12505 #endif /* HAVE_WINDOW_SYSTEM */
12506
12507 /* We go to this label, with fonts_changed_p nonzero,
12508 if it is necessary to try again using larger glyph matrices.
12509 We have to redeem the scroll bar even in this case,
12510 because the loop in redisplay_internal expects that. */
12511 need_larger_matrices:
12512 ;
12513 finish_scroll_bars:
12514
12515 if (WINDOW_HAS_VERTICAL_SCROLL_BAR (w))
12516 {
12517 /* Set the thumb's position and size. */
12518 set_vertical_scroll_bar (w);
12519
12520 /* Note that we actually used the scroll bar attached to this
12521 window, so it shouldn't be deleted at the end of redisplay. */
12522 redeem_scroll_bar_hook (w);
12523 }
12524
12525 /* Restore current_buffer and value of point in it. */
12526 TEMP_SET_PT_BOTH (CHARPOS (opoint), BYTEPOS (opoint));
12527 set_buffer_internal_1 (old);
12528 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
12529
12530 unbind_to (count, Qnil);
12531 }
12532
12533
12534 /* Build the complete desired matrix of WINDOW with a window start
12535 buffer position POS. Value is non-zero if successful. It is zero
12536 if fonts were loaded during redisplay which makes re-adjusting
12537 glyph matrices necessary. */
12538
12539 int
12540 try_window (window, pos)
12541 Lisp_Object window;
12542 struct text_pos pos;
12543 {
12544 struct window *w = XWINDOW (window);
12545 struct it it;
12546 struct glyph_row *last_text_row = NULL;
12547
12548 /* Make POS the new window start. */
12549 set_marker_both (w->start, Qnil, CHARPOS (pos), BYTEPOS (pos));
12550
12551 /* Mark cursor position as unknown. No overlay arrow seen. */
12552 w->cursor.vpos = -1;
12553 overlay_arrow_seen = 0;
12554
12555 /* Initialize iterator and info to start at POS. */
12556 start_display (&it, w, pos);
12557
12558 /* Display all lines of W. */
12559 while (it.current_y < it.last_visible_y)
12560 {
12561 if (display_line (&it))
12562 last_text_row = it.glyph_row - 1;
12563 if (fonts_changed_p)
12564 return 0;
12565 }
12566
12567 /* If bottom moved off end of frame, change mode line percentage. */
12568 if (XFASTINT (w->window_end_pos) <= 0
12569 && Z != IT_CHARPOS (it))
12570 w->update_mode_line = Qt;
12571
12572 /* Set window_end_pos to the offset of the last character displayed
12573 on the window from the end of current_buffer. Set
12574 window_end_vpos to its row number. */
12575 if (last_text_row)
12576 {
12577 xassert (MATRIX_ROW_DISPLAYS_TEXT_P (last_text_row));
12578 w->window_end_bytepos
12579 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12580 w->window_end_pos
12581 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12582 w->window_end_vpos
12583 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12584 xassert (MATRIX_ROW (w->desired_matrix, XFASTINT (w->window_end_vpos))
12585 ->displays_text_p);
12586 }
12587 else
12588 {
12589 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12590 w->window_end_pos = make_number (Z - ZV);
12591 w->window_end_vpos = make_number (0);
12592 }
12593
12594 /* But that is not valid info until redisplay finishes. */
12595 w->window_end_valid = Qnil;
12596 return 1;
12597 }
12598
12599
12600 \f
12601 /************************************************************************
12602 Window redisplay reusing current matrix when buffer has not changed
12603 ************************************************************************/
12604
12605 /* Try redisplay of window W showing an unchanged buffer with a
12606 different window start than the last time it was displayed by
12607 reusing its current matrix. Value is non-zero if successful.
12608 W->start is the new window start. */
12609
12610 static int
12611 try_window_reusing_current_matrix (w)
12612 struct window *w;
12613 {
12614 struct frame *f = XFRAME (w->frame);
12615 struct glyph_row *row, *bottom_row;
12616 struct it it;
12617 struct run run;
12618 struct text_pos start, new_start;
12619 int nrows_scrolled, i;
12620 struct glyph_row *last_text_row;
12621 struct glyph_row *last_reused_text_row;
12622 struct glyph_row *start_row;
12623 int start_vpos, min_y, max_y;
12624
12625 #if GLYPH_DEBUG
12626 if (inhibit_try_window_reusing)
12627 return 0;
12628 #endif
12629
12630 if (/* This function doesn't handle terminal frames. */
12631 !FRAME_WINDOW_P (f)
12632 /* Don't try to reuse the display if windows have been split
12633 or such. */
12634 || windows_or_buffers_changed
12635 || cursor_type_changed)
12636 return 0;
12637
12638 /* Can't do this if region may have changed. */
12639 if ((!NILP (Vtransient_mark_mode)
12640 && !NILP (current_buffer->mark_active))
12641 || !NILP (w->region_showing)
12642 || !NILP (Vshow_trailing_whitespace))
12643 return 0;
12644
12645 /* If top-line visibility has changed, give up. */
12646 if (WINDOW_WANTS_HEADER_LINE_P (w)
12647 != MATRIX_HEADER_LINE_ROW (w->current_matrix)->mode_line_p)
12648 return 0;
12649
12650 /* Give up if old or new display is scrolled vertically. We could
12651 make this function handle this, but right now it doesn't. */
12652 start_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12653 if (w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row))
12654 return 0;
12655
12656 /* The variable new_start now holds the new window start. The old
12657 start `start' can be determined from the current matrix. */
12658 SET_TEXT_POS_FROM_MARKER (new_start, w->start);
12659 start = start_row->start.pos;
12660 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12661
12662 /* Clear the desired matrix for the display below. */
12663 clear_glyph_matrix (w->desired_matrix);
12664
12665 if (CHARPOS (new_start) <= CHARPOS (start))
12666 {
12667 int first_row_y;
12668
12669 /* Don't use this method if the display starts with an ellipsis
12670 displayed for invisible text. It's not easy to handle that case
12671 below, and it's certainly not worth the effort since this is
12672 not a frequent case. */
12673 if (in_ellipses_for_invisible_text_p (&start_row->start, w))
12674 return 0;
12675
12676 IF_DEBUG (debug_method_add (w, "twu1"));
12677
12678 /* Display up to a row that can be reused. The variable
12679 last_text_row is set to the last row displayed that displays
12680 text. Note that it.vpos == 0 if or if not there is a
12681 header-line; it's not the same as the MATRIX_ROW_VPOS! */
12682 start_display (&it, w, new_start);
12683 first_row_y = it.current_y;
12684 w->cursor.vpos = -1;
12685 last_text_row = last_reused_text_row = NULL;
12686
12687 while (it.current_y < it.last_visible_y
12688 && !fonts_changed_p)
12689 {
12690 /* If we have reached into the characters in the START row,
12691 that means the line boundaries have changed. So we
12692 can't start copying with the row START. Maybe it will
12693 work to start copying with the following row. */
12694 while (IT_CHARPOS (it) > CHARPOS (start))
12695 {
12696 /* Advance to the next row as the "start". */
12697 start_row++;
12698 start = start_row->start.pos;
12699 /* If there are no more rows to try, or just one, give up. */
12700 if (start_row == MATRIX_MODE_LINE_ROW (w->current_matrix) - 1
12701 || w->vscroll || MATRIX_ROW_PARTIALLY_VISIBLE_P (w, start_row)
12702 || CHARPOS (start) == ZV)
12703 {
12704 clear_glyph_matrix (w->desired_matrix);
12705 return 0;
12706 }
12707
12708 start_vpos = MATRIX_ROW_VPOS (start_row, w->current_matrix);
12709 }
12710 /* If we have reached alignment,
12711 we can copy the rest of the rows. */
12712 if (IT_CHARPOS (it) == CHARPOS (start))
12713 break;
12714
12715 if (display_line (&it))
12716 last_text_row = it.glyph_row - 1;
12717 }
12718
12719 /* A value of current_y < last_visible_y means that we stopped
12720 at the previous window start, which in turn means that we
12721 have at least one reusable row. */
12722 if (it.current_y < it.last_visible_y)
12723 {
12724 /* IT.vpos always starts from 0; it counts text lines. */
12725 nrows_scrolled = it.vpos - (start_row - MATRIX_FIRST_TEXT_ROW (w->current_matrix));
12726
12727 /* Find PT if not already found in the lines displayed. */
12728 if (w->cursor.vpos < 0)
12729 {
12730 int dy = it.current_y - start_row->y;
12731
12732 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
12733 row = row_containing_pos (w, PT, row, NULL, dy);
12734 if (row)
12735 set_cursor_from_row (w, row, w->current_matrix, 0, 0,
12736 dy, nrows_scrolled);
12737 else
12738 {
12739 clear_glyph_matrix (w->desired_matrix);
12740 return 0;
12741 }
12742 }
12743
12744 /* Scroll the display. Do it before the current matrix is
12745 changed. The problem here is that update has not yet
12746 run, i.e. part of the current matrix is not up to date.
12747 scroll_run_hook will clear the cursor, and use the
12748 current matrix to get the height of the row the cursor is
12749 in. */
12750 run.current_y = start_row->y;
12751 run.desired_y = it.current_y;
12752 run.height = it.last_visible_y - it.current_y;
12753
12754 if (run.height > 0 && run.current_y != run.desired_y)
12755 {
12756 update_begin (f);
12757 rif->update_window_begin_hook (w);
12758 rif->clear_window_mouse_face (w);
12759 rif->scroll_run_hook (w, &run);
12760 rif->update_window_end_hook (w, 0, 0);
12761 update_end (f);
12762 }
12763
12764 /* Shift current matrix down by nrows_scrolled lines. */
12765 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12766 rotate_matrix (w->current_matrix,
12767 start_vpos,
12768 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12769 nrows_scrolled);
12770
12771 /* Disable lines that must be updated. */
12772 for (i = 0; i < it.vpos; ++i)
12773 (start_row + i)->enabled_p = 0;
12774
12775 /* Re-compute Y positions. */
12776 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12777 max_y = it.last_visible_y;
12778 for (row = start_row + nrows_scrolled;
12779 row < bottom_row;
12780 ++row)
12781 {
12782 row->y = it.current_y;
12783 row->visible_height = row->height;
12784
12785 if (row->y < min_y)
12786 row->visible_height -= min_y - row->y;
12787 if (row->y + row->height > max_y)
12788 row->visible_height -= row->y + row->height - max_y;
12789 row->redraw_fringe_bitmaps_p = 1;
12790
12791 it.current_y += row->height;
12792
12793 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
12794 last_reused_text_row = row;
12795 if (MATRIX_ROW_BOTTOM_Y (row) >= it.last_visible_y)
12796 break;
12797 }
12798
12799 /* Disable lines in the current matrix which are now
12800 below the window. */
12801 for (++row; row < bottom_row; ++row)
12802 row->enabled_p = 0;
12803 }
12804
12805 /* Update window_end_pos etc.; last_reused_text_row is the last
12806 reused row from the current matrix containing text, if any.
12807 The value of last_text_row is the last displayed line
12808 containing text. */
12809 if (last_reused_text_row)
12810 {
12811 w->window_end_bytepos
12812 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_reused_text_row);
12813 w->window_end_pos
12814 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_reused_text_row));
12815 w->window_end_vpos
12816 = make_number (MATRIX_ROW_VPOS (last_reused_text_row,
12817 w->current_matrix));
12818 }
12819 else if (last_text_row)
12820 {
12821 w->window_end_bytepos
12822 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12823 w->window_end_pos
12824 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12825 w->window_end_vpos
12826 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12827 }
12828 else
12829 {
12830 /* This window must be completely empty. */
12831 w->window_end_bytepos = Z_BYTE - ZV_BYTE;
12832 w->window_end_pos = make_number (Z - ZV);
12833 w->window_end_vpos = make_number (0);
12834 }
12835 w->window_end_valid = Qnil;
12836
12837 /* Update hint: don't try scrolling again in update_window. */
12838 w->desired_matrix->no_scrolling_p = 1;
12839
12840 #if GLYPH_DEBUG
12841 debug_method_add (w, "try_window_reusing_current_matrix 1");
12842 #endif
12843 return 1;
12844 }
12845 else if (CHARPOS (new_start) > CHARPOS (start))
12846 {
12847 struct glyph_row *pt_row, *row;
12848 struct glyph_row *first_reusable_row;
12849 struct glyph_row *first_row_to_display;
12850 int dy;
12851 int yb = window_text_bottom_y (w);
12852
12853 /* Find the row starting at new_start, if there is one. Don't
12854 reuse a partially visible line at the end. */
12855 first_reusable_row = start_row;
12856 while (first_reusable_row->enabled_p
12857 && MATRIX_ROW_BOTTOM_Y (first_reusable_row) < yb
12858 && (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12859 < CHARPOS (new_start)))
12860 ++first_reusable_row;
12861
12862 /* Give up if there is no row to reuse. */
12863 if (MATRIX_ROW_BOTTOM_Y (first_reusable_row) >= yb
12864 || !first_reusable_row->enabled_p
12865 || (MATRIX_ROW_START_CHARPOS (first_reusable_row)
12866 != CHARPOS (new_start)))
12867 return 0;
12868
12869 /* We can reuse fully visible rows beginning with
12870 first_reusable_row to the end of the window. Set
12871 first_row_to_display to the first row that cannot be reused.
12872 Set pt_row to the row containing point, if there is any. */
12873 pt_row = NULL;
12874 for (first_row_to_display = first_reusable_row;
12875 MATRIX_ROW_BOTTOM_Y (first_row_to_display) < yb;
12876 ++first_row_to_display)
12877 {
12878 if (PT >= MATRIX_ROW_START_CHARPOS (first_row_to_display)
12879 && PT < MATRIX_ROW_END_CHARPOS (first_row_to_display))
12880 pt_row = first_row_to_display;
12881 }
12882
12883 /* Start displaying at the start of first_row_to_display. */
12884 xassert (first_row_to_display->y < yb);
12885 init_to_row_start (&it, w, first_row_to_display);
12886
12887 nrows_scrolled = (MATRIX_ROW_VPOS (first_reusable_row, w->current_matrix)
12888 - start_vpos);
12889 it.vpos = (MATRIX_ROW_VPOS (first_row_to_display, w->current_matrix)
12890 - nrows_scrolled);
12891 it.current_y = (first_row_to_display->y - first_reusable_row->y
12892 + WINDOW_HEADER_LINE_HEIGHT (w));
12893
12894 /* Display lines beginning with first_row_to_display in the
12895 desired matrix. Set last_text_row to the last row displayed
12896 that displays text. */
12897 it.glyph_row = MATRIX_ROW (w->desired_matrix, it.vpos);
12898 if (pt_row == NULL)
12899 w->cursor.vpos = -1;
12900 last_text_row = NULL;
12901 while (it.current_y < it.last_visible_y && !fonts_changed_p)
12902 if (display_line (&it))
12903 last_text_row = it.glyph_row - 1;
12904
12905 /* Give up If point isn't in a row displayed or reused. */
12906 if (w->cursor.vpos < 0)
12907 {
12908 clear_glyph_matrix (w->desired_matrix);
12909 return 0;
12910 }
12911
12912 /* If point is in a reused row, adjust y and vpos of the cursor
12913 position. */
12914 if (pt_row)
12915 {
12916 w->cursor.vpos -= nrows_scrolled;
12917 w->cursor.y -= first_reusable_row->y - start_row->y;
12918 }
12919
12920 /* Scroll the display. */
12921 run.current_y = first_reusable_row->y;
12922 run.desired_y = WINDOW_HEADER_LINE_HEIGHT (w);
12923 run.height = it.last_visible_y - run.current_y;
12924 dy = run.current_y - run.desired_y;
12925
12926 if (run.height)
12927 {
12928 update_begin (f);
12929 rif->update_window_begin_hook (w);
12930 rif->clear_window_mouse_face (w);
12931 rif->scroll_run_hook (w, &run);
12932 rif->update_window_end_hook (w, 0, 0);
12933 update_end (f);
12934 }
12935
12936 /* Adjust Y positions of reused rows. */
12937 bottom_row = MATRIX_BOTTOM_TEXT_ROW (w->current_matrix, w);
12938 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
12939 max_y = it.last_visible_y;
12940 for (row = first_reusable_row; row < first_row_to_display; ++row)
12941 {
12942 row->y -= dy;
12943 row->visible_height = row->height;
12944 if (row->y < min_y)
12945 row->visible_height -= min_y - row->y;
12946 if (row->y + row->height > max_y)
12947 row->visible_height -= row->y + row->height - max_y;
12948 row->redraw_fringe_bitmaps_p = 1;
12949 }
12950
12951 /* Scroll the current matrix. */
12952 xassert (nrows_scrolled > 0);
12953 rotate_matrix (w->current_matrix,
12954 start_vpos,
12955 MATRIX_ROW_VPOS (bottom_row, w->current_matrix),
12956 -nrows_scrolled);
12957
12958 /* Disable rows not reused. */
12959 for (row -= nrows_scrolled; row < bottom_row; ++row)
12960 row->enabled_p = 0;
12961
12962 /* Point may have moved to a different line, so we cannot assume that
12963 the previous cursor position is valid; locate the correct row. */
12964 if (pt_row)
12965 {
12966 for (row = MATRIX_ROW (w->current_matrix, w->cursor.vpos);
12967 row < bottom_row && PT >= MATRIX_ROW_END_CHARPOS (row);
12968 row++)
12969 {
12970 w->cursor.vpos++;
12971 w->cursor.y = row->y;
12972 }
12973 if (row < bottom_row)
12974 {
12975 struct glyph *glyph = row->glyphs[TEXT_AREA] + w->cursor.hpos;
12976 while (glyph->charpos < PT)
12977 {
12978 w->cursor.hpos++;
12979 w->cursor.x += glyph->pixel_width;
12980 glyph++;
12981 }
12982 }
12983 }
12984
12985 /* Adjust window end. A null value of last_text_row means that
12986 the window end is in reused rows which in turn means that
12987 only its vpos can have changed. */
12988 if (last_text_row)
12989 {
12990 w->window_end_bytepos
12991 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
12992 w->window_end_pos
12993 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
12994 w->window_end_vpos
12995 = make_number (MATRIX_ROW_VPOS (last_text_row, w->desired_matrix));
12996 }
12997 else
12998 {
12999 w->window_end_vpos
13000 = make_number (XFASTINT (w->window_end_vpos) - nrows_scrolled);
13001 }
13002
13003 w->window_end_valid = Qnil;
13004 w->desired_matrix->no_scrolling_p = 1;
13005
13006 #if GLYPH_DEBUG
13007 debug_method_add (w, "try_window_reusing_current_matrix 2");
13008 #endif
13009 return 1;
13010 }
13011
13012 return 0;
13013 }
13014
13015
13016 \f
13017 /************************************************************************
13018 Window redisplay reusing current matrix when buffer has changed
13019 ************************************************************************/
13020
13021 static struct glyph_row *find_last_unchanged_at_beg_row P_ ((struct window *));
13022 static struct glyph_row *find_first_unchanged_at_end_row P_ ((struct window *,
13023 int *, int *));
13024 static struct glyph_row *
13025 find_last_row_displaying_text P_ ((struct glyph_matrix *, struct it *,
13026 struct glyph_row *));
13027
13028
13029 /* Return the last row in MATRIX displaying text. If row START is
13030 non-null, start searching with that row. IT gives the dimensions
13031 of the display. Value is null if matrix is empty; otherwise it is
13032 a pointer to the row found. */
13033
13034 static struct glyph_row *
13035 find_last_row_displaying_text (matrix, it, start)
13036 struct glyph_matrix *matrix;
13037 struct it *it;
13038 struct glyph_row *start;
13039 {
13040 struct glyph_row *row, *row_found;
13041
13042 /* Set row_found to the last row in IT->w's current matrix
13043 displaying text. The loop looks funny but think of partially
13044 visible lines. */
13045 row_found = NULL;
13046 row = start ? start : MATRIX_FIRST_TEXT_ROW (matrix);
13047 while (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13048 {
13049 xassert (row->enabled_p);
13050 row_found = row;
13051 if (MATRIX_ROW_BOTTOM_Y (row) >= it->last_visible_y)
13052 break;
13053 ++row;
13054 }
13055
13056 return row_found;
13057 }
13058
13059
13060 /* Return the last row in the current matrix of W that is not affected
13061 by changes at the start of current_buffer that occurred since W's
13062 current matrix was built. Value is null if no such row exists.
13063
13064 BEG_UNCHANGED us the number of characters unchanged at the start of
13065 current_buffer. BEG + BEG_UNCHANGED is the buffer position of the
13066 first changed character in current_buffer. Characters at positions <
13067 BEG + BEG_UNCHANGED are at the same buffer positions as they were
13068 when the current matrix was built. */
13069
13070 static struct glyph_row *
13071 find_last_unchanged_at_beg_row (w)
13072 struct window *w;
13073 {
13074 int first_changed_pos = BEG + BEG_UNCHANGED;
13075 struct glyph_row *row;
13076 struct glyph_row *row_found = NULL;
13077 int yb = window_text_bottom_y (w);
13078
13079 /* Find the last row displaying unchanged text. */
13080 row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13081 while (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13082 && MATRIX_ROW_START_CHARPOS (row) < first_changed_pos)
13083 {
13084 if (/* If row ends before first_changed_pos, it is unchanged,
13085 except in some case. */
13086 MATRIX_ROW_END_CHARPOS (row) <= first_changed_pos
13087 /* When row ends in ZV and we write at ZV it is not
13088 unchanged. */
13089 && !row->ends_at_zv_p
13090 /* When first_changed_pos is the end of a continued line,
13091 row is not unchanged because it may be no longer
13092 continued. */
13093 && !(MATRIX_ROW_END_CHARPOS (row) == first_changed_pos
13094 && (row->continued_p
13095 || row->exact_window_width_line_p)))
13096 row_found = row;
13097
13098 /* Stop if last visible row. */
13099 if (MATRIX_ROW_BOTTOM_Y (row) >= yb)
13100 break;
13101
13102 ++row;
13103 }
13104
13105 return row_found;
13106 }
13107
13108
13109 /* Find the first glyph row in the current matrix of W that is not
13110 affected by changes at the end of current_buffer since the
13111 time W's current matrix was built.
13112
13113 Return in *DELTA the number of chars by which buffer positions in
13114 unchanged text at the end of current_buffer must be adjusted.
13115
13116 Return in *DELTA_BYTES the corresponding number of bytes.
13117
13118 Value is null if no such row exists, i.e. all rows are affected by
13119 changes. */
13120
13121 static struct glyph_row *
13122 find_first_unchanged_at_end_row (w, delta, delta_bytes)
13123 struct window *w;
13124 int *delta, *delta_bytes;
13125 {
13126 struct glyph_row *row;
13127 struct glyph_row *row_found = NULL;
13128
13129 *delta = *delta_bytes = 0;
13130
13131 /* Display must not have been paused, otherwise the current matrix
13132 is not up to date. */
13133 if (NILP (w->window_end_valid))
13134 abort ();
13135
13136 /* A value of window_end_pos >= END_UNCHANGED means that the window
13137 end is in the range of changed text. If so, there is no
13138 unchanged row at the end of W's current matrix. */
13139 if (XFASTINT (w->window_end_pos) >= END_UNCHANGED)
13140 return NULL;
13141
13142 /* Set row to the last row in W's current matrix displaying text. */
13143 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13144
13145 /* If matrix is entirely empty, no unchanged row exists. */
13146 if (MATRIX_ROW_DISPLAYS_TEXT_P (row))
13147 {
13148 /* The value of row is the last glyph row in the matrix having a
13149 meaningful buffer position in it. The end position of row
13150 corresponds to window_end_pos. This allows us to translate
13151 buffer positions in the current matrix to current buffer
13152 positions for characters not in changed text. */
13153 int Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13154 int Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13155 int last_unchanged_pos, last_unchanged_pos_old;
13156 struct glyph_row *first_text_row
13157 = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
13158
13159 *delta = Z - Z_old;
13160 *delta_bytes = Z_BYTE - Z_BYTE_old;
13161
13162 /* Set last_unchanged_pos to the buffer position of the last
13163 character in the buffer that has not been changed. Z is the
13164 index + 1 of the last character in current_buffer, i.e. by
13165 subtracting END_UNCHANGED we get the index of the last
13166 unchanged character, and we have to add BEG to get its buffer
13167 position. */
13168 last_unchanged_pos = Z - END_UNCHANGED + BEG;
13169 last_unchanged_pos_old = last_unchanged_pos - *delta;
13170
13171 /* Search backward from ROW for a row displaying a line that
13172 starts at a minimum position >= last_unchanged_pos_old. */
13173 for (; row > first_text_row; --row)
13174 {
13175 /* This used to abort, but it can happen.
13176 It is ok to just stop the search instead here. KFS. */
13177 if (!row->enabled_p || !MATRIX_ROW_DISPLAYS_TEXT_P (row))
13178 break;
13179
13180 if (MATRIX_ROW_START_CHARPOS (row) >= last_unchanged_pos_old)
13181 row_found = row;
13182 }
13183 }
13184
13185 if (row_found && !MATRIX_ROW_DISPLAYS_TEXT_P (row_found))
13186 abort ();
13187
13188 return row_found;
13189 }
13190
13191
13192 /* Make sure that glyph rows in the current matrix of window W
13193 reference the same glyph memory as corresponding rows in the
13194 frame's frame matrix. This function is called after scrolling W's
13195 current matrix on a terminal frame in try_window_id and
13196 try_window_reusing_current_matrix. */
13197
13198 static void
13199 sync_frame_with_window_matrix_rows (w)
13200 struct window *w;
13201 {
13202 struct frame *f = XFRAME (w->frame);
13203 struct glyph_row *window_row, *window_row_end, *frame_row;
13204
13205 /* Preconditions: W must be a leaf window and full-width. Its frame
13206 must have a frame matrix. */
13207 xassert (NILP (w->hchild) && NILP (w->vchild));
13208 xassert (WINDOW_FULL_WIDTH_P (w));
13209 xassert (!FRAME_WINDOW_P (f));
13210
13211 /* If W is a full-width window, glyph pointers in W's current matrix
13212 have, by definition, to be the same as glyph pointers in the
13213 corresponding frame matrix. Note that frame matrices have no
13214 marginal areas (see build_frame_matrix). */
13215 window_row = w->current_matrix->rows;
13216 window_row_end = window_row + w->current_matrix->nrows;
13217 frame_row = f->current_matrix->rows + WINDOW_TOP_EDGE_LINE (w);
13218 while (window_row < window_row_end)
13219 {
13220 struct glyph *start = window_row->glyphs[LEFT_MARGIN_AREA];
13221 struct glyph *end = window_row->glyphs[LAST_AREA];
13222
13223 frame_row->glyphs[LEFT_MARGIN_AREA] = start;
13224 frame_row->glyphs[TEXT_AREA] = start;
13225 frame_row->glyphs[RIGHT_MARGIN_AREA] = end;
13226 frame_row->glyphs[LAST_AREA] = end;
13227
13228 /* Disable frame rows whose corresponding window rows have
13229 been disabled in try_window_id. */
13230 if (!window_row->enabled_p)
13231 frame_row->enabled_p = 0;
13232
13233 ++window_row, ++frame_row;
13234 }
13235 }
13236
13237
13238 /* Find the glyph row in window W containing CHARPOS. Consider all
13239 rows between START and END (not inclusive). END null means search
13240 all rows to the end of the display area of W. Value is the row
13241 containing CHARPOS or null. */
13242
13243 struct glyph_row *
13244 row_containing_pos (w, charpos, start, end, dy)
13245 struct window *w;
13246 int charpos;
13247 struct glyph_row *start, *end;
13248 int dy;
13249 {
13250 struct glyph_row *row = start;
13251 int last_y;
13252
13253 /* If we happen to start on a header-line, skip that. */
13254 if (row->mode_line_p)
13255 ++row;
13256
13257 if ((end && row >= end) || !row->enabled_p)
13258 return NULL;
13259
13260 last_y = window_text_bottom_y (w) - dy;
13261
13262 while (1)
13263 {
13264 /* Give up if we have gone too far. */
13265 if (end && row >= end)
13266 return NULL;
13267 /* This formerly returned if they were equal.
13268 I think that both quantities are of a "last plus one" type;
13269 if so, when they are equal, the row is within the screen. -- rms. */
13270 if (MATRIX_ROW_BOTTOM_Y (row) > last_y)
13271 return NULL;
13272
13273 /* If it is in this row, return this row. */
13274 if (! (MATRIX_ROW_END_CHARPOS (row) < charpos
13275 || (MATRIX_ROW_END_CHARPOS (row) == charpos
13276 /* The end position of a row equals the start
13277 position of the next row. If CHARPOS is there, we
13278 would rather display it in the next line, except
13279 when this line ends in ZV. */
13280 && !row->ends_at_zv_p
13281 && !MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row)))
13282 && charpos >= MATRIX_ROW_START_CHARPOS (row))
13283 return row;
13284 ++row;
13285 }
13286 }
13287
13288
13289 /* Try to redisplay window W by reusing its existing display. W's
13290 current matrix must be up to date when this function is called,
13291 i.e. window_end_valid must not be nil.
13292
13293 Value is
13294
13295 1 if display has been updated
13296 0 if otherwise unsuccessful
13297 -1 if redisplay with same window start is known not to succeed
13298
13299 The following steps are performed:
13300
13301 1. Find the last row in the current matrix of W that is not
13302 affected by changes at the start of current_buffer. If no such row
13303 is found, give up.
13304
13305 2. Find the first row in W's current matrix that is not affected by
13306 changes at the end of current_buffer. Maybe there is no such row.
13307
13308 3. Display lines beginning with the row + 1 found in step 1 to the
13309 row found in step 2 or, if step 2 didn't find a row, to the end of
13310 the window.
13311
13312 4. If cursor is not known to appear on the window, give up.
13313
13314 5. If display stopped at the row found in step 2, scroll the
13315 display and current matrix as needed.
13316
13317 6. Maybe display some lines at the end of W, if we must. This can
13318 happen under various circumstances, like a partially visible line
13319 becoming fully visible, or because newly displayed lines are displayed
13320 in smaller font sizes.
13321
13322 7. Update W's window end information. */
13323
13324 static int
13325 try_window_id (w)
13326 struct window *w;
13327 {
13328 struct frame *f = XFRAME (w->frame);
13329 struct glyph_matrix *current_matrix = w->current_matrix;
13330 struct glyph_matrix *desired_matrix = w->desired_matrix;
13331 struct glyph_row *last_unchanged_at_beg_row;
13332 struct glyph_row *first_unchanged_at_end_row;
13333 struct glyph_row *row;
13334 struct glyph_row *bottom_row;
13335 int bottom_vpos;
13336 struct it it;
13337 int delta = 0, delta_bytes = 0, stop_pos, dvpos, dy;
13338 struct text_pos start_pos;
13339 struct run run;
13340 int first_unchanged_at_end_vpos = 0;
13341 struct glyph_row *last_text_row, *last_text_row_at_end;
13342 struct text_pos start;
13343 int first_changed_charpos, last_changed_charpos;
13344
13345 #if GLYPH_DEBUG
13346 if (inhibit_try_window_id)
13347 return 0;
13348 #endif
13349
13350 /* This is handy for debugging. */
13351 #if 0
13352 #define GIVE_UP(X) \
13353 do { \
13354 fprintf (stderr, "try_window_id give up %d\n", (X)); \
13355 return 0; \
13356 } while (0)
13357 #else
13358 #define GIVE_UP(X) return 0
13359 #endif
13360
13361 SET_TEXT_POS_FROM_MARKER (start, w->start);
13362
13363 /* Don't use this for mini-windows because these can show
13364 messages and mini-buffers, and we don't handle that here. */
13365 if (MINI_WINDOW_P (w))
13366 GIVE_UP (1);
13367
13368 /* This flag is used to prevent redisplay optimizations. */
13369 if (windows_or_buffers_changed || cursor_type_changed)
13370 GIVE_UP (2);
13371
13372 /* Verify that narrowing has not changed.
13373 Also verify that we were not told to prevent redisplay optimizations.
13374 It would be nice to further
13375 reduce the number of cases where this prevents try_window_id. */
13376 if (current_buffer->clip_changed
13377 || current_buffer->prevent_redisplay_optimizations_p)
13378 GIVE_UP (3);
13379
13380 /* Window must either use window-based redisplay or be full width. */
13381 if (!FRAME_WINDOW_P (f)
13382 && (!line_ins_del_ok
13383 || !WINDOW_FULL_WIDTH_P (w)))
13384 GIVE_UP (4);
13385
13386 /* Give up if point is not known NOT to appear in W. */
13387 if (PT < CHARPOS (start))
13388 GIVE_UP (5);
13389
13390 /* Another way to prevent redisplay optimizations. */
13391 if (XFASTINT (w->last_modified) == 0)
13392 GIVE_UP (6);
13393
13394 /* Verify that window is not hscrolled. */
13395 if (XFASTINT (w->hscroll) != 0)
13396 GIVE_UP (7);
13397
13398 /* Verify that display wasn't paused. */
13399 if (NILP (w->window_end_valid))
13400 GIVE_UP (8);
13401
13402 /* Can't use this if highlighting a region because a cursor movement
13403 will do more than just set the cursor. */
13404 if (!NILP (Vtransient_mark_mode)
13405 && !NILP (current_buffer->mark_active))
13406 GIVE_UP (9);
13407
13408 /* Likewise if highlighting trailing whitespace. */
13409 if (!NILP (Vshow_trailing_whitespace))
13410 GIVE_UP (11);
13411
13412 /* Likewise if showing a region. */
13413 if (!NILP (w->region_showing))
13414 GIVE_UP (10);
13415
13416 /* Can use this if overlay arrow position and or string have changed. */
13417 if (overlay_arrows_changed_p ())
13418 GIVE_UP (12);
13419
13420
13421 /* Make sure beg_unchanged and end_unchanged are up to date. Do it
13422 only if buffer has really changed. The reason is that the gap is
13423 initially at Z for freshly visited files. The code below would
13424 set end_unchanged to 0 in that case. */
13425 if (MODIFF > SAVE_MODIFF
13426 /* This seems to happen sometimes after saving a buffer. */
13427 || BEG_UNCHANGED + END_UNCHANGED > Z_BYTE)
13428 {
13429 if (GPT - BEG < BEG_UNCHANGED)
13430 BEG_UNCHANGED = GPT - BEG;
13431 if (Z - GPT < END_UNCHANGED)
13432 END_UNCHANGED = Z - GPT;
13433 }
13434
13435 /* The position of the first and last character that has been changed. */
13436 first_changed_charpos = BEG + BEG_UNCHANGED;
13437 last_changed_charpos = Z - END_UNCHANGED;
13438
13439 /* If window starts after a line end, and the last change is in
13440 front of that newline, then changes don't affect the display.
13441 This case happens with stealth-fontification. Note that although
13442 the display is unchanged, glyph positions in the matrix have to
13443 be adjusted, of course. */
13444 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
13445 if (MATRIX_ROW_DISPLAYS_TEXT_P (row)
13446 && ((last_changed_charpos < CHARPOS (start)
13447 && CHARPOS (start) == BEGV)
13448 || (last_changed_charpos < CHARPOS (start) - 1
13449 && FETCH_BYTE (BYTEPOS (start) - 1) == '\n')))
13450 {
13451 int Z_old, delta, Z_BYTE_old, delta_bytes;
13452 struct glyph_row *r0;
13453
13454 /* Compute how many chars/bytes have been added to or removed
13455 from the buffer. */
13456 Z_old = MATRIX_ROW_END_CHARPOS (row) + XFASTINT (w->window_end_pos);
13457 Z_BYTE_old = MATRIX_ROW_END_BYTEPOS (row) + w->window_end_bytepos;
13458 delta = Z - Z_old;
13459 delta_bytes = Z_BYTE - Z_BYTE_old;
13460
13461 /* Give up if PT is not in the window. Note that it already has
13462 been checked at the start of try_window_id that PT is not in
13463 front of the window start. */
13464 if (PT >= MATRIX_ROW_END_CHARPOS (row) + delta)
13465 GIVE_UP (13);
13466
13467 /* If window start is unchanged, we can reuse the whole matrix
13468 as is, after adjusting glyph positions. No need to compute
13469 the window end again, since its offset from Z hasn't changed. */
13470 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13471 if (CHARPOS (start) == MATRIX_ROW_START_CHARPOS (r0) + delta
13472 && BYTEPOS (start) == MATRIX_ROW_START_BYTEPOS (r0) + delta_bytes
13473 /* PT must not be in a partially visible line. */
13474 && !(PT >= MATRIX_ROW_START_CHARPOS (row) + delta
13475 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13476 {
13477 /* Adjust positions in the glyph matrix. */
13478 if (delta || delta_bytes)
13479 {
13480 struct glyph_row *r1
13481 = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13482 increment_matrix_positions (w->current_matrix,
13483 MATRIX_ROW_VPOS (r0, current_matrix),
13484 MATRIX_ROW_VPOS (r1, current_matrix),
13485 delta, delta_bytes);
13486 }
13487
13488 /* Set the cursor. */
13489 row = row_containing_pos (w, PT, r0, NULL, 0);
13490 if (row)
13491 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13492 else
13493 abort ();
13494 return 1;
13495 }
13496 }
13497
13498 /* Handle the case that changes are all below what is displayed in
13499 the window, and that PT is in the window. This shortcut cannot
13500 be taken if ZV is visible in the window, and text has been added
13501 there that is visible in the window. */
13502 if (first_changed_charpos >= MATRIX_ROW_END_CHARPOS (row)
13503 /* ZV is not visible in the window, or there are no
13504 changes at ZV, actually. */
13505 && (current_matrix->zv > MATRIX_ROW_END_CHARPOS (row)
13506 || first_changed_charpos == last_changed_charpos))
13507 {
13508 struct glyph_row *r0;
13509
13510 /* Give up if PT is not in the window. Note that it already has
13511 been checked at the start of try_window_id that PT is not in
13512 front of the window start. */
13513 if (PT >= MATRIX_ROW_END_CHARPOS (row))
13514 GIVE_UP (14);
13515
13516 /* If window start is unchanged, we can reuse the whole matrix
13517 as is, without changing glyph positions since no text has
13518 been added/removed in front of the window end. */
13519 r0 = MATRIX_FIRST_TEXT_ROW (current_matrix);
13520 if (TEXT_POS_EQUAL_P (start, r0->start.pos)
13521 /* PT must not be in a partially visible line. */
13522 && !(PT >= MATRIX_ROW_START_CHARPOS (row)
13523 && MATRIX_ROW_BOTTOM_Y (row) > window_text_bottom_y (w)))
13524 {
13525 /* We have to compute the window end anew since text
13526 can have been added/removed after it. */
13527 w->window_end_pos
13528 = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13529 w->window_end_bytepos
13530 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13531
13532 /* Set the cursor. */
13533 row = row_containing_pos (w, PT, r0, NULL, 0);
13534 if (row)
13535 set_cursor_from_row (w, row, current_matrix, 0, 0, 0, 0);
13536 else
13537 abort ();
13538 return 2;
13539 }
13540 }
13541
13542 /* Give up if window start is in the changed area.
13543
13544 The condition used to read
13545
13546 (BEG_UNCHANGED + END_UNCHANGED != Z - BEG && ...)
13547
13548 but why that was tested escapes me at the moment. */
13549 if (CHARPOS (start) >= first_changed_charpos
13550 && CHARPOS (start) <= last_changed_charpos)
13551 GIVE_UP (15);
13552
13553 /* Check that window start agrees with the start of the first glyph
13554 row in its current matrix. Check this after we know the window
13555 start is not in changed text, otherwise positions would not be
13556 comparable. */
13557 row = MATRIX_FIRST_TEXT_ROW (current_matrix);
13558 if (!TEXT_POS_EQUAL_P (start, row->start.pos))
13559 GIVE_UP (16);
13560
13561 /* Give up if the window ends in strings. Overlay strings
13562 at the end are difficult to handle, so don't try. */
13563 row = MATRIX_ROW (current_matrix, XFASTINT (w->window_end_vpos));
13564 if (MATRIX_ROW_START_CHARPOS (row) == MATRIX_ROW_END_CHARPOS (row))
13565 GIVE_UP (20);
13566
13567 /* Compute the position at which we have to start displaying new
13568 lines. Some of the lines at the top of the window might be
13569 reusable because they are not displaying changed text. Find the
13570 last row in W's current matrix not affected by changes at the
13571 start of current_buffer. Value is null if changes start in the
13572 first line of window. */
13573 last_unchanged_at_beg_row = find_last_unchanged_at_beg_row (w);
13574 if (last_unchanged_at_beg_row)
13575 {
13576 /* Avoid starting to display in the moddle of a character, a TAB
13577 for instance. This is easier than to set up the iterator
13578 exactly, and it's not a frequent case, so the additional
13579 effort wouldn't really pay off. */
13580 while ((MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row)
13581 || last_unchanged_at_beg_row->ends_in_newline_from_string_p)
13582 && last_unchanged_at_beg_row > w->current_matrix->rows)
13583 --last_unchanged_at_beg_row;
13584
13585 if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (last_unchanged_at_beg_row))
13586 GIVE_UP (17);
13587
13588 if (init_to_row_end (&it, w, last_unchanged_at_beg_row) == 0)
13589 GIVE_UP (18);
13590 start_pos = it.current.pos;
13591
13592 /* Start displaying new lines in the desired matrix at the same
13593 vpos we would use in the current matrix, i.e. below
13594 last_unchanged_at_beg_row. */
13595 it.vpos = 1 + MATRIX_ROW_VPOS (last_unchanged_at_beg_row,
13596 current_matrix);
13597 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13598 it.current_y = MATRIX_ROW_BOTTOM_Y (last_unchanged_at_beg_row);
13599
13600 xassert (it.hpos == 0 && it.current_x == 0);
13601 }
13602 else
13603 {
13604 /* There are no reusable lines at the start of the window.
13605 Start displaying in the first text line. */
13606 start_display (&it, w, start);
13607 it.vpos = it.first_vpos;
13608 start_pos = it.current.pos;
13609 }
13610
13611 /* Find the first row that is not affected by changes at the end of
13612 the buffer. Value will be null if there is no unchanged row, in
13613 which case we must redisplay to the end of the window. delta
13614 will be set to the value by which buffer positions beginning with
13615 first_unchanged_at_end_row have to be adjusted due to text
13616 changes. */
13617 first_unchanged_at_end_row
13618 = find_first_unchanged_at_end_row (w, &delta, &delta_bytes);
13619 IF_DEBUG (debug_delta = delta);
13620 IF_DEBUG (debug_delta_bytes = delta_bytes);
13621
13622 /* Set stop_pos to the buffer position up to which we will have to
13623 display new lines. If first_unchanged_at_end_row != NULL, this
13624 is the buffer position of the start of the line displayed in that
13625 row. For first_unchanged_at_end_row == NULL, use 0 to indicate
13626 that we don't stop at a buffer position. */
13627 stop_pos = 0;
13628 if (first_unchanged_at_end_row)
13629 {
13630 xassert (last_unchanged_at_beg_row == NULL
13631 || first_unchanged_at_end_row >= last_unchanged_at_beg_row);
13632
13633 /* If this is a continuation line, move forward to the next one
13634 that isn't. Changes in lines above affect this line.
13635 Caution: this may move first_unchanged_at_end_row to a row
13636 not displaying text. */
13637 while (MATRIX_ROW_CONTINUATION_LINE_P (first_unchanged_at_end_row)
13638 && MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13639 && (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13640 < it.last_visible_y))
13641 ++first_unchanged_at_end_row;
13642
13643 if (!MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row)
13644 || (MATRIX_ROW_BOTTOM_Y (first_unchanged_at_end_row)
13645 >= it.last_visible_y))
13646 first_unchanged_at_end_row = NULL;
13647 else
13648 {
13649 stop_pos = (MATRIX_ROW_START_CHARPOS (first_unchanged_at_end_row)
13650 + delta);
13651 first_unchanged_at_end_vpos
13652 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, current_matrix);
13653 xassert (stop_pos >= Z - END_UNCHANGED);
13654 }
13655 }
13656 else if (last_unchanged_at_beg_row == NULL)
13657 GIVE_UP (19);
13658
13659
13660 #if GLYPH_DEBUG
13661
13662 /* Either there is no unchanged row at the end, or the one we have
13663 now displays text. This is a necessary condition for the window
13664 end pos calculation at the end of this function. */
13665 xassert (first_unchanged_at_end_row == NULL
13666 || MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row));
13667
13668 debug_last_unchanged_at_beg_vpos
13669 = (last_unchanged_at_beg_row
13670 ? MATRIX_ROW_VPOS (last_unchanged_at_beg_row, current_matrix)
13671 : -1);
13672 debug_first_unchanged_at_end_vpos = first_unchanged_at_end_vpos;
13673
13674 #endif /* GLYPH_DEBUG != 0 */
13675
13676
13677 /* Display new lines. Set last_text_row to the last new line
13678 displayed which has text on it, i.e. might end up as being the
13679 line where the window_end_vpos is. */
13680 w->cursor.vpos = -1;
13681 last_text_row = NULL;
13682 overlay_arrow_seen = 0;
13683 while (it.current_y < it.last_visible_y
13684 && !fonts_changed_p
13685 && (first_unchanged_at_end_row == NULL
13686 || IT_CHARPOS (it) < stop_pos))
13687 {
13688 if (display_line (&it))
13689 last_text_row = it.glyph_row - 1;
13690 }
13691
13692 if (fonts_changed_p)
13693 return -1;
13694
13695
13696 /* Compute differences in buffer positions, y-positions etc. for
13697 lines reused at the bottom of the window. Compute what we can
13698 scroll. */
13699 if (first_unchanged_at_end_row
13700 /* No lines reused because we displayed everything up to the
13701 bottom of the window. */
13702 && it.current_y < it.last_visible_y)
13703 {
13704 dvpos = (it.vpos
13705 - MATRIX_ROW_VPOS (first_unchanged_at_end_row,
13706 current_matrix));
13707 dy = it.current_y - first_unchanged_at_end_row->y;
13708 run.current_y = first_unchanged_at_end_row->y;
13709 run.desired_y = run.current_y + dy;
13710 run.height = it.last_visible_y - max (run.current_y, run.desired_y);
13711 }
13712 else
13713 {
13714 delta = dvpos = dy = run.current_y = run.desired_y = run.height = 0;
13715 first_unchanged_at_end_row = NULL;
13716 }
13717 IF_DEBUG (debug_dvpos = dvpos; debug_dy = dy);
13718
13719
13720 /* Find the cursor if not already found. We have to decide whether
13721 PT will appear on this window (it sometimes doesn't, but this is
13722 not a very frequent case.) This decision has to be made before
13723 the current matrix is altered. A value of cursor.vpos < 0 means
13724 that PT is either in one of the lines beginning at
13725 first_unchanged_at_end_row or below the window. Don't care for
13726 lines that might be displayed later at the window end; as
13727 mentioned, this is not a frequent case. */
13728 if (w->cursor.vpos < 0)
13729 {
13730 /* Cursor in unchanged rows at the top? */
13731 if (PT < CHARPOS (start_pos)
13732 && last_unchanged_at_beg_row)
13733 {
13734 row = row_containing_pos (w, PT,
13735 MATRIX_FIRST_TEXT_ROW (w->current_matrix),
13736 last_unchanged_at_beg_row + 1, 0);
13737 if (row)
13738 set_cursor_from_row (w, row, w->current_matrix, 0, 0, 0, 0);
13739 }
13740
13741 /* Start from first_unchanged_at_end_row looking for PT. */
13742 else if (first_unchanged_at_end_row)
13743 {
13744 row = row_containing_pos (w, PT - delta,
13745 first_unchanged_at_end_row, NULL, 0);
13746 if (row)
13747 set_cursor_from_row (w, row, w->current_matrix, delta,
13748 delta_bytes, dy, dvpos);
13749 }
13750
13751 /* Give up if cursor was not found. */
13752 if (w->cursor.vpos < 0)
13753 {
13754 clear_glyph_matrix (w->desired_matrix);
13755 return -1;
13756 }
13757 }
13758
13759 /* Don't let the cursor end in the scroll margins. */
13760 {
13761 int this_scroll_margin, cursor_height;
13762
13763 this_scroll_margin = max (0, scroll_margin);
13764 this_scroll_margin = min (this_scroll_margin, WINDOW_TOTAL_LINES (w) / 4);
13765 this_scroll_margin *= FRAME_LINE_HEIGHT (it.f);
13766 cursor_height = MATRIX_ROW (w->desired_matrix, w->cursor.vpos)->height;
13767
13768 if ((w->cursor.y < this_scroll_margin
13769 && CHARPOS (start) > BEGV)
13770 /* Old redisplay didn't take scroll margin into account at the bottom,
13771 but then global-hl-line-mode doesn't scroll. KFS 2004-06-14 */
13772 || (w->cursor.y + (make_cursor_line_fully_visible_p
13773 ? cursor_height + this_scroll_margin
13774 : 1)) > it.last_visible_y)
13775 {
13776 w->cursor.vpos = -1;
13777 clear_glyph_matrix (w->desired_matrix);
13778 return -1;
13779 }
13780 }
13781
13782 /* Scroll the display. Do it before changing the current matrix so
13783 that xterm.c doesn't get confused about where the cursor glyph is
13784 found. */
13785 if (dy && run.height)
13786 {
13787 update_begin (f);
13788
13789 if (FRAME_WINDOW_P (f))
13790 {
13791 rif->update_window_begin_hook (w);
13792 rif->clear_window_mouse_face (w);
13793 rif->scroll_run_hook (w, &run);
13794 rif->update_window_end_hook (w, 0, 0);
13795 }
13796 else
13797 {
13798 /* Terminal frame. In this case, dvpos gives the number of
13799 lines to scroll by; dvpos < 0 means scroll up. */
13800 int first_unchanged_at_end_vpos
13801 = MATRIX_ROW_VPOS (first_unchanged_at_end_row, w->current_matrix);
13802 int from = WINDOW_TOP_EDGE_LINE (w) + first_unchanged_at_end_vpos;
13803 int end = (WINDOW_TOP_EDGE_LINE (w)
13804 + (WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0)
13805 + window_internal_height (w));
13806
13807 /* Perform the operation on the screen. */
13808 if (dvpos > 0)
13809 {
13810 /* Scroll last_unchanged_at_beg_row to the end of the
13811 window down dvpos lines. */
13812 set_terminal_window (end);
13813
13814 /* On dumb terminals delete dvpos lines at the end
13815 before inserting dvpos empty lines. */
13816 if (!scroll_region_ok)
13817 ins_del_lines (end - dvpos, -dvpos);
13818
13819 /* Insert dvpos empty lines in front of
13820 last_unchanged_at_beg_row. */
13821 ins_del_lines (from, dvpos);
13822 }
13823 else if (dvpos < 0)
13824 {
13825 /* Scroll up last_unchanged_at_beg_vpos to the end of
13826 the window to last_unchanged_at_beg_vpos - |dvpos|. */
13827 set_terminal_window (end);
13828
13829 /* Delete dvpos lines in front of
13830 last_unchanged_at_beg_vpos. ins_del_lines will set
13831 the cursor to the given vpos and emit |dvpos| delete
13832 line sequences. */
13833 ins_del_lines (from + dvpos, dvpos);
13834
13835 /* On a dumb terminal insert dvpos empty lines at the
13836 end. */
13837 if (!scroll_region_ok)
13838 ins_del_lines (end + dvpos, -dvpos);
13839 }
13840
13841 set_terminal_window (0);
13842 }
13843
13844 update_end (f);
13845 }
13846
13847 /* Shift reused rows of the current matrix to the right position.
13848 BOTTOM_ROW is the last + 1 row in the current matrix reserved for
13849 text. */
13850 bottom_row = MATRIX_BOTTOM_TEXT_ROW (current_matrix, w);
13851 bottom_vpos = MATRIX_ROW_VPOS (bottom_row, current_matrix);
13852 if (dvpos < 0)
13853 {
13854 rotate_matrix (current_matrix, first_unchanged_at_end_vpos + dvpos,
13855 bottom_vpos, dvpos);
13856 enable_glyph_matrix_rows (current_matrix, bottom_vpos + dvpos,
13857 bottom_vpos, 0);
13858 }
13859 else if (dvpos > 0)
13860 {
13861 rotate_matrix (current_matrix, first_unchanged_at_end_vpos,
13862 bottom_vpos, dvpos);
13863 enable_glyph_matrix_rows (current_matrix, first_unchanged_at_end_vpos,
13864 first_unchanged_at_end_vpos + dvpos, 0);
13865 }
13866
13867 /* For frame-based redisplay, make sure that current frame and window
13868 matrix are in sync with respect to glyph memory. */
13869 if (!FRAME_WINDOW_P (f))
13870 sync_frame_with_window_matrix_rows (w);
13871
13872 /* Adjust buffer positions in reused rows. */
13873 if (delta)
13874 increment_matrix_positions (current_matrix,
13875 first_unchanged_at_end_vpos + dvpos,
13876 bottom_vpos, delta, delta_bytes);
13877
13878 /* Adjust Y positions. */
13879 if (dy)
13880 shift_glyph_matrix (w, current_matrix,
13881 first_unchanged_at_end_vpos + dvpos,
13882 bottom_vpos, dy);
13883
13884 if (first_unchanged_at_end_row)
13885 {
13886 first_unchanged_at_end_row += dvpos;
13887 if (first_unchanged_at_end_row->y >= it.last_visible_y
13888 || !MATRIX_ROW_DISPLAYS_TEXT_P (first_unchanged_at_end_row))
13889 first_unchanged_at_end_row = NULL;
13890 }
13891
13892 /* If scrolling up, there may be some lines to display at the end of
13893 the window. */
13894 last_text_row_at_end = NULL;
13895 if (dy < 0)
13896 {
13897 /* Scrolling up can leave for example a partially visible line
13898 at the end of the window to be redisplayed. */
13899 /* Set last_row to the glyph row in the current matrix where the
13900 window end line is found. It has been moved up or down in
13901 the matrix by dvpos. */
13902 int last_vpos = XFASTINT (w->window_end_vpos) + dvpos;
13903 struct glyph_row *last_row = MATRIX_ROW (current_matrix, last_vpos);
13904
13905 /* If last_row is the window end line, it should display text. */
13906 xassert (last_row->displays_text_p);
13907
13908 /* If window end line was partially visible before, begin
13909 displaying at that line. Otherwise begin displaying with the
13910 line following it. */
13911 if (MATRIX_ROW_BOTTOM_Y (last_row) - dy >= it.last_visible_y)
13912 {
13913 init_to_row_start (&it, w, last_row);
13914 it.vpos = last_vpos;
13915 it.current_y = last_row->y;
13916 }
13917 else
13918 {
13919 init_to_row_end (&it, w, last_row);
13920 it.vpos = 1 + last_vpos;
13921 it.current_y = MATRIX_ROW_BOTTOM_Y (last_row);
13922 ++last_row;
13923 }
13924
13925 /* We may start in a continuation line. If so, we have to
13926 get the right continuation_lines_width and current_x. */
13927 it.continuation_lines_width = last_row->continuation_lines_width;
13928 it.hpos = it.current_x = 0;
13929
13930 /* Display the rest of the lines at the window end. */
13931 it.glyph_row = MATRIX_ROW (desired_matrix, it.vpos);
13932 while (it.current_y < it.last_visible_y
13933 && !fonts_changed_p)
13934 {
13935 /* Is it always sure that the display agrees with lines in
13936 the current matrix? I don't think so, so we mark rows
13937 displayed invalid in the current matrix by setting their
13938 enabled_p flag to zero. */
13939 MATRIX_ROW (w->current_matrix, it.vpos)->enabled_p = 0;
13940 if (display_line (&it))
13941 last_text_row_at_end = it.glyph_row - 1;
13942 }
13943 }
13944
13945 /* Update window_end_pos and window_end_vpos. */
13946 if (first_unchanged_at_end_row
13947 && !last_text_row_at_end)
13948 {
13949 /* Window end line if one of the preserved rows from the current
13950 matrix. Set row to the last row displaying text in current
13951 matrix starting at first_unchanged_at_end_row, after
13952 scrolling. */
13953 xassert (first_unchanged_at_end_row->displays_text_p);
13954 row = find_last_row_displaying_text (w->current_matrix, &it,
13955 first_unchanged_at_end_row);
13956 xassert (row && MATRIX_ROW_DISPLAYS_TEXT_P (row));
13957
13958 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
13959 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
13960 w->window_end_vpos
13961 = make_number (MATRIX_ROW_VPOS (row, w->current_matrix));
13962 xassert (w->window_end_bytepos >= 0);
13963 IF_DEBUG (debug_method_add (w, "A"));
13964 }
13965 else if (last_text_row_at_end)
13966 {
13967 w->window_end_pos
13968 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row_at_end));
13969 w->window_end_bytepos
13970 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row_at_end);
13971 w->window_end_vpos
13972 = make_number (MATRIX_ROW_VPOS (last_text_row_at_end, desired_matrix));
13973 xassert (w->window_end_bytepos >= 0);
13974 IF_DEBUG (debug_method_add (w, "B"));
13975 }
13976 else if (last_text_row)
13977 {
13978 /* We have displayed either to the end of the window or at the
13979 end of the window, i.e. the last row with text is to be found
13980 in the desired matrix. */
13981 w->window_end_pos
13982 = make_number (Z - MATRIX_ROW_END_CHARPOS (last_text_row));
13983 w->window_end_bytepos
13984 = Z_BYTE - MATRIX_ROW_END_BYTEPOS (last_text_row);
13985 w->window_end_vpos
13986 = make_number (MATRIX_ROW_VPOS (last_text_row, desired_matrix));
13987 xassert (w->window_end_bytepos >= 0);
13988 }
13989 else if (first_unchanged_at_end_row == NULL
13990 && last_text_row == NULL
13991 && last_text_row_at_end == NULL)
13992 {
13993 /* Displayed to end of window, but no line containing text was
13994 displayed. Lines were deleted at the end of the window. */
13995 int first_vpos = WINDOW_WANTS_HEADER_LINE_P (w) ? 1 : 0;
13996 int vpos = XFASTINT (w->window_end_vpos);
13997 struct glyph_row *current_row = current_matrix->rows + vpos;
13998 struct glyph_row *desired_row = desired_matrix->rows + vpos;
13999
14000 for (row = NULL;
14001 row == NULL && vpos >= first_vpos;
14002 --vpos, --current_row, --desired_row)
14003 {
14004 if (desired_row->enabled_p)
14005 {
14006 if (desired_row->displays_text_p)
14007 row = desired_row;
14008 }
14009 else if (current_row->displays_text_p)
14010 row = current_row;
14011 }
14012
14013 xassert (row != NULL);
14014 w->window_end_vpos = make_number (vpos + 1);
14015 w->window_end_pos = make_number (Z - MATRIX_ROW_END_CHARPOS (row));
14016 w->window_end_bytepos = Z_BYTE - MATRIX_ROW_END_BYTEPOS (row);
14017 xassert (w->window_end_bytepos >= 0);
14018 IF_DEBUG (debug_method_add (w, "C"));
14019 }
14020 else
14021 abort ();
14022
14023 #if 0 /* This leads to problems, for instance when the cursor is
14024 at ZV, and the cursor line displays no text. */
14025 /* Disable rows below what's displayed in the window. This makes
14026 debugging easier. */
14027 enable_glyph_matrix_rows (current_matrix,
14028 XFASTINT (w->window_end_vpos) + 1,
14029 bottom_vpos, 0);
14030 #endif
14031
14032 IF_DEBUG (debug_end_pos = XFASTINT (w->window_end_pos);
14033 debug_end_vpos = XFASTINT (w->window_end_vpos));
14034
14035 /* Record that display has not been completed. */
14036 w->window_end_valid = Qnil;
14037 w->desired_matrix->no_scrolling_p = 1;
14038 return 3;
14039
14040 #undef GIVE_UP
14041 }
14042
14043
14044 \f
14045 /***********************************************************************
14046 More debugging support
14047 ***********************************************************************/
14048
14049 #if GLYPH_DEBUG
14050
14051 void dump_glyph_row P_ ((struct glyph_row *, int, int));
14052 void dump_glyph_matrix P_ ((struct glyph_matrix *, int));
14053 void dump_glyph P_ ((struct glyph_row *, struct glyph *, int));
14054
14055
14056 /* Dump the contents of glyph matrix MATRIX on stderr.
14057
14058 GLYPHS 0 means don't show glyph contents.
14059 GLYPHS 1 means show glyphs in short form
14060 GLYPHS > 1 means show glyphs in long form. */
14061
14062 void
14063 dump_glyph_matrix (matrix, glyphs)
14064 struct glyph_matrix *matrix;
14065 int glyphs;
14066 {
14067 int i;
14068 for (i = 0; i < matrix->nrows; ++i)
14069 dump_glyph_row (MATRIX_ROW (matrix, i), i, glyphs);
14070 }
14071
14072
14073 /* Dump contents of glyph GLYPH to stderr. ROW and AREA are
14074 the glyph row and area where the glyph comes from. */
14075
14076 void
14077 dump_glyph (row, glyph, area)
14078 struct glyph_row *row;
14079 struct glyph *glyph;
14080 int area;
14081 {
14082 if (glyph->type == CHAR_GLYPH)
14083 {
14084 fprintf (stderr,
14085 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14086 glyph - row->glyphs[TEXT_AREA],
14087 'C',
14088 glyph->charpos,
14089 (BUFFERP (glyph->object)
14090 ? 'B'
14091 : (STRINGP (glyph->object)
14092 ? 'S'
14093 : '-')),
14094 glyph->pixel_width,
14095 glyph->u.ch,
14096 (glyph->u.ch < 0x80 && glyph->u.ch >= ' '
14097 ? glyph->u.ch
14098 : '.'),
14099 glyph->face_id,
14100 glyph->left_box_line_p,
14101 glyph->right_box_line_p);
14102 }
14103 else if (glyph->type == STRETCH_GLYPH)
14104 {
14105 fprintf (stderr,
14106 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14107 glyph - row->glyphs[TEXT_AREA],
14108 'S',
14109 glyph->charpos,
14110 (BUFFERP (glyph->object)
14111 ? 'B'
14112 : (STRINGP (glyph->object)
14113 ? 'S'
14114 : '-')),
14115 glyph->pixel_width,
14116 0,
14117 '.',
14118 glyph->face_id,
14119 glyph->left_box_line_p,
14120 glyph->right_box_line_p);
14121 }
14122 else if (glyph->type == IMAGE_GLYPH)
14123 {
14124 fprintf (stderr,
14125 " %5d %4c %6d %c %3d 0x%05x %c %4d %1.1d%1.1d\n",
14126 glyph - row->glyphs[TEXT_AREA],
14127 'I',
14128 glyph->charpos,
14129 (BUFFERP (glyph->object)
14130 ? 'B'
14131 : (STRINGP (glyph->object)
14132 ? 'S'
14133 : '-')),
14134 glyph->pixel_width,
14135 glyph->u.img_id,
14136 '.',
14137 glyph->face_id,
14138 glyph->left_box_line_p,
14139 glyph->right_box_line_p);
14140 }
14141 }
14142
14143
14144 /* Dump the contents of glyph row at VPOS in MATRIX to stderr.
14145 GLYPHS 0 means don't show glyph contents.
14146 GLYPHS 1 means show glyphs in short form
14147 GLYPHS > 1 means show glyphs in long form. */
14148
14149 void
14150 dump_glyph_row (row, vpos, glyphs)
14151 struct glyph_row *row;
14152 int vpos, glyphs;
14153 {
14154 if (glyphs != 1)
14155 {
14156 fprintf (stderr, "Row Start End Used oEI><\\CTZFesm X Y W H V A P\n");
14157 fprintf (stderr, "======================================================================\n");
14158
14159 fprintf (stderr, "%3d %5d %5d %4d %1.1d%1.1d%1.1d%1.1d\
14160 %1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d%1.1d %4d %4d %4d %4d %4d %4d %4d\n",
14161 vpos,
14162 MATRIX_ROW_START_CHARPOS (row),
14163 MATRIX_ROW_END_CHARPOS (row),
14164 row->used[TEXT_AREA],
14165 row->contains_overlapping_glyphs_p,
14166 row->enabled_p,
14167 row->truncated_on_left_p,
14168 row->truncated_on_right_p,
14169 row->continued_p,
14170 MATRIX_ROW_CONTINUATION_LINE_P (row),
14171 row->displays_text_p,
14172 row->ends_at_zv_p,
14173 row->fill_line_p,
14174 row->ends_in_middle_of_char_p,
14175 row->starts_in_middle_of_char_p,
14176 row->mouse_face_p,
14177 row->x,
14178 row->y,
14179 row->pixel_width,
14180 row->height,
14181 row->visible_height,
14182 row->ascent,
14183 row->phys_ascent);
14184 fprintf (stderr, "%9d %5d\t%5d\n", row->start.overlay_string_index,
14185 row->end.overlay_string_index,
14186 row->continuation_lines_width);
14187 fprintf (stderr, "%9d %5d\n",
14188 CHARPOS (row->start.string_pos),
14189 CHARPOS (row->end.string_pos));
14190 fprintf (stderr, "%9d %5d\n", row->start.dpvec_index,
14191 row->end.dpvec_index);
14192 }
14193
14194 if (glyphs > 1)
14195 {
14196 int area;
14197
14198 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14199 {
14200 struct glyph *glyph = row->glyphs[area];
14201 struct glyph *glyph_end = glyph + row->used[area];
14202
14203 /* Glyph for a line end in text. */
14204 if (area == TEXT_AREA && glyph == glyph_end && glyph->charpos > 0)
14205 ++glyph_end;
14206
14207 if (glyph < glyph_end)
14208 fprintf (stderr, " Glyph Type Pos O W Code C Face LR\n");
14209
14210 for (; glyph < glyph_end; ++glyph)
14211 dump_glyph (row, glyph, area);
14212 }
14213 }
14214 else if (glyphs == 1)
14215 {
14216 int area;
14217
14218 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14219 {
14220 char *s = (char *) alloca (row->used[area] + 1);
14221 int i;
14222
14223 for (i = 0; i < row->used[area]; ++i)
14224 {
14225 struct glyph *glyph = row->glyphs[area] + i;
14226 if (glyph->type == CHAR_GLYPH
14227 && glyph->u.ch < 0x80
14228 && glyph->u.ch >= ' ')
14229 s[i] = glyph->u.ch;
14230 else
14231 s[i] = '.';
14232 }
14233
14234 s[i] = '\0';
14235 fprintf (stderr, "%3d: (%d) '%s'\n", vpos, row->enabled_p, s);
14236 }
14237 }
14238 }
14239
14240
14241 DEFUN ("dump-glyph-matrix", Fdump_glyph_matrix,
14242 Sdump_glyph_matrix, 0, 1, "p",
14243 doc: /* Dump the current matrix of the selected window to stderr.
14244 Shows contents of glyph row structures. With non-nil
14245 parameter GLYPHS, dump glyphs as well. If GLYPHS is 1 show
14246 glyphs in short form, otherwise show glyphs in long form. */)
14247 (glyphs)
14248 Lisp_Object glyphs;
14249 {
14250 struct window *w = XWINDOW (selected_window);
14251 struct buffer *buffer = XBUFFER (w->buffer);
14252
14253 fprintf (stderr, "PT = %d, BEGV = %d. ZV = %d\n",
14254 BUF_PT (buffer), BUF_BEGV (buffer), BUF_ZV (buffer));
14255 fprintf (stderr, "Cursor x = %d, y = %d, hpos = %d, vpos = %d\n",
14256 w->cursor.x, w->cursor.y, w->cursor.hpos, w->cursor.vpos);
14257 fprintf (stderr, "=============================================\n");
14258 dump_glyph_matrix (w->current_matrix,
14259 NILP (glyphs) ? 0 : XINT (glyphs));
14260 return Qnil;
14261 }
14262
14263
14264 DEFUN ("dump-frame-glyph-matrix", Fdump_frame_glyph_matrix,
14265 Sdump_frame_glyph_matrix, 0, 0, "", doc: /* */)
14266 ()
14267 {
14268 struct frame *f = XFRAME (selected_frame);
14269 dump_glyph_matrix (f->current_matrix, 1);
14270 return Qnil;
14271 }
14272
14273
14274 DEFUN ("dump-glyph-row", Fdump_glyph_row, Sdump_glyph_row, 1, 2, "",
14275 doc: /* Dump glyph row ROW to stderr.
14276 GLYPH 0 means don't dump glyphs.
14277 GLYPH 1 means dump glyphs in short form.
14278 GLYPH > 1 or omitted means dump glyphs in long form. */)
14279 (row, glyphs)
14280 Lisp_Object row, glyphs;
14281 {
14282 struct glyph_matrix *matrix;
14283 int vpos;
14284
14285 CHECK_NUMBER (row);
14286 matrix = XWINDOW (selected_window)->current_matrix;
14287 vpos = XINT (row);
14288 if (vpos >= 0 && vpos < matrix->nrows)
14289 dump_glyph_row (MATRIX_ROW (matrix, vpos),
14290 vpos,
14291 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14292 return Qnil;
14293 }
14294
14295
14296 DEFUN ("dump-tool-bar-row", Fdump_tool_bar_row, Sdump_tool_bar_row, 1, 2, "",
14297 doc: /* Dump glyph row ROW of the tool-bar of the current frame to stderr.
14298 GLYPH 0 means don't dump glyphs.
14299 GLYPH 1 means dump glyphs in short form.
14300 GLYPH > 1 or omitted means dump glyphs in long form. */)
14301 (row, glyphs)
14302 Lisp_Object row, glyphs;
14303 {
14304 struct frame *sf = SELECTED_FRAME ();
14305 struct glyph_matrix *m = XWINDOW (sf->tool_bar_window)->current_matrix;
14306 int vpos;
14307
14308 CHECK_NUMBER (row);
14309 vpos = XINT (row);
14310 if (vpos >= 0 && vpos < m->nrows)
14311 dump_glyph_row (MATRIX_ROW (m, vpos), vpos,
14312 INTEGERP (glyphs) ? XINT (glyphs) : 2);
14313 return Qnil;
14314 }
14315
14316
14317 DEFUN ("trace-redisplay", Ftrace_redisplay, Strace_redisplay, 0, 1, "P",
14318 doc: /* Toggle tracing of redisplay.
14319 With ARG, turn tracing on if and only if ARG is positive. */)
14320 (arg)
14321 Lisp_Object arg;
14322 {
14323 if (NILP (arg))
14324 trace_redisplay_p = !trace_redisplay_p;
14325 else
14326 {
14327 arg = Fprefix_numeric_value (arg);
14328 trace_redisplay_p = XINT (arg) > 0;
14329 }
14330
14331 return Qnil;
14332 }
14333
14334
14335 DEFUN ("trace-to-stderr", Ftrace_to_stderr, Strace_to_stderr, 1, MANY, "",
14336 doc: /* Like `format', but print result to stderr.
14337 usage: (trace-to-stderr STRING &rest OBJECTS) */)
14338 (nargs, args)
14339 int nargs;
14340 Lisp_Object *args;
14341 {
14342 Lisp_Object s = Fformat (nargs, args);
14343 fprintf (stderr, "%s", SDATA (s));
14344 return Qnil;
14345 }
14346
14347 #endif /* GLYPH_DEBUG */
14348
14349
14350 \f
14351 /***********************************************************************
14352 Building Desired Matrix Rows
14353 ***********************************************************************/
14354
14355 /* Return a temporary glyph row holding the glyphs of an overlay arrow.
14356 Used for non-window-redisplay windows, and for windows w/o left fringe. */
14357
14358 static struct glyph_row *
14359 get_overlay_arrow_glyph_row (w, overlay_arrow_string)
14360 struct window *w;
14361 Lisp_Object overlay_arrow_string;
14362 {
14363 struct frame *f = XFRAME (WINDOW_FRAME (w));
14364 struct buffer *buffer = XBUFFER (w->buffer);
14365 struct buffer *old = current_buffer;
14366 const unsigned char *arrow_string = SDATA (overlay_arrow_string);
14367 int arrow_len = SCHARS (overlay_arrow_string);
14368 const unsigned char *arrow_end = arrow_string + arrow_len;
14369 const unsigned char *p;
14370 struct it it;
14371 int multibyte_p;
14372 int n_glyphs_before;
14373
14374 set_buffer_temp (buffer);
14375 init_iterator (&it, w, -1, -1, &scratch_glyph_row, DEFAULT_FACE_ID);
14376 it.glyph_row->used[TEXT_AREA] = 0;
14377 SET_TEXT_POS (it.position, 0, 0);
14378
14379 multibyte_p = !NILP (buffer->enable_multibyte_characters);
14380 p = arrow_string;
14381 while (p < arrow_end)
14382 {
14383 Lisp_Object face, ilisp;
14384
14385 /* Get the next character. */
14386 if (multibyte_p)
14387 it.c = string_char_and_length (p, arrow_len, &it.len);
14388 else
14389 it.c = *p, it.len = 1;
14390 p += it.len;
14391
14392 /* Get its face. */
14393 ilisp = make_number (p - arrow_string);
14394 face = Fget_text_property (ilisp, Qface, overlay_arrow_string);
14395 it.face_id = compute_char_face (f, it.c, face);
14396
14397 /* Compute its width, get its glyphs. */
14398 n_glyphs_before = it.glyph_row->used[TEXT_AREA];
14399 SET_TEXT_POS (it.position, -1, -1);
14400 PRODUCE_GLYPHS (&it);
14401
14402 /* If this character doesn't fit any more in the line, we have
14403 to remove some glyphs. */
14404 if (it.current_x > it.last_visible_x)
14405 {
14406 it.glyph_row->used[TEXT_AREA] = n_glyphs_before;
14407 break;
14408 }
14409 }
14410
14411 set_buffer_temp (old);
14412 return it.glyph_row;
14413 }
14414
14415
14416 /* Insert truncation glyphs at the start of IT->glyph_row. Truncation
14417 glyphs are only inserted for terminal frames since we can't really
14418 win with truncation glyphs when partially visible glyphs are
14419 involved. Which glyphs to insert is determined by
14420 produce_special_glyphs. */
14421
14422 static void
14423 insert_left_trunc_glyphs (it)
14424 struct it *it;
14425 {
14426 struct it truncate_it;
14427 struct glyph *from, *end, *to, *toend;
14428
14429 xassert (!FRAME_WINDOW_P (it->f));
14430
14431 /* Get the truncation glyphs. */
14432 truncate_it = *it;
14433 truncate_it.current_x = 0;
14434 truncate_it.face_id = DEFAULT_FACE_ID;
14435 truncate_it.glyph_row = &scratch_glyph_row;
14436 truncate_it.glyph_row->used[TEXT_AREA] = 0;
14437 CHARPOS (truncate_it.position) = BYTEPOS (truncate_it.position) = -1;
14438 truncate_it.object = make_number (0);
14439 produce_special_glyphs (&truncate_it, IT_TRUNCATION);
14440
14441 /* Overwrite glyphs from IT with truncation glyphs. */
14442 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14443 end = from + truncate_it.glyph_row->used[TEXT_AREA];
14444 to = it->glyph_row->glyphs[TEXT_AREA];
14445 toend = to + it->glyph_row->used[TEXT_AREA];
14446
14447 while (from < end)
14448 *to++ = *from++;
14449
14450 /* There may be padding glyphs left over. Overwrite them too. */
14451 while (to < toend && CHAR_GLYPH_PADDING_P (*to))
14452 {
14453 from = truncate_it.glyph_row->glyphs[TEXT_AREA];
14454 while (from < end)
14455 *to++ = *from++;
14456 }
14457
14458 if (to > toend)
14459 it->glyph_row->used[TEXT_AREA] = to - it->glyph_row->glyphs[TEXT_AREA];
14460 }
14461
14462
14463 /* Compute the pixel height and width of IT->glyph_row.
14464
14465 Most of the time, ascent and height of a display line will be equal
14466 to the max_ascent and max_height values of the display iterator
14467 structure. This is not the case if
14468
14469 1. We hit ZV without displaying anything. In this case, max_ascent
14470 and max_height will be zero.
14471
14472 2. We have some glyphs that don't contribute to the line height.
14473 (The glyph row flag contributes_to_line_height_p is for future
14474 pixmap extensions).
14475
14476 The first case is easily covered by using default values because in
14477 these cases, the line height does not really matter, except that it
14478 must not be zero. */
14479
14480 static void
14481 compute_line_metrics (it)
14482 struct it *it;
14483 {
14484 struct glyph_row *row = it->glyph_row;
14485 int area, i;
14486
14487 if (FRAME_WINDOW_P (it->f))
14488 {
14489 int i, min_y, max_y;
14490
14491 /* The line may consist of one space only, that was added to
14492 place the cursor on it. If so, the row's height hasn't been
14493 computed yet. */
14494 if (row->height == 0)
14495 {
14496 if (it->max_ascent + it->max_descent == 0)
14497 it->max_descent = it->max_phys_descent = FRAME_LINE_HEIGHT (it->f);
14498 row->ascent = it->max_ascent;
14499 row->height = it->max_ascent + it->max_descent;
14500 row->phys_ascent = it->max_phys_ascent;
14501 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14502 row->extra_line_spacing = it->max_extra_line_spacing;
14503 }
14504
14505 /* Compute the width of this line. */
14506 row->pixel_width = row->x;
14507 for (i = 0; i < row->used[TEXT_AREA]; ++i)
14508 row->pixel_width += row->glyphs[TEXT_AREA][i].pixel_width;
14509
14510 xassert (row->pixel_width >= 0);
14511 xassert (row->ascent >= 0 && row->height > 0);
14512
14513 row->overlapping_p = (MATRIX_ROW_OVERLAPS_SUCC_P (row)
14514 || MATRIX_ROW_OVERLAPS_PRED_P (row));
14515
14516 /* If first line's physical ascent is larger than its logical
14517 ascent, use the physical ascent, and make the row taller.
14518 This makes accented characters fully visible. */
14519 if (row == MATRIX_FIRST_TEXT_ROW (it->w->desired_matrix)
14520 && row->phys_ascent > row->ascent)
14521 {
14522 row->height += row->phys_ascent - row->ascent;
14523 row->ascent = row->phys_ascent;
14524 }
14525
14526 /* Compute how much of the line is visible. */
14527 row->visible_height = row->height;
14528
14529 min_y = WINDOW_HEADER_LINE_HEIGHT (it->w);
14530 max_y = WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w);
14531
14532 if (row->y < min_y)
14533 row->visible_height -= min_y - row->y;
14534 if (row->y + row->height > max_y)
14535 row->visible_height -= row->y + row->height - max_y;
14536 }
14537 else
14538 {
14539 row->pixel_width = row->used[TEXT_AREA];
14540 if (row->continued_p)
14541 row->pixel_width -= it->continuation_pixel_width;
14542 else if (row->truncated_on_right_p)
14543 row->pixel_width -= it->truncation_pixel_width;
14544 row->ascent = row->phys_ascent = 0;
14545 row->height = row->phys_height = row->visible_height = 1;
14546 row->extra_line_spacing = 0;
14547 }
14548
14549 /* Compute a hash code for this row. */
14550 row->hash = 0;
14551 for (area = LEFT_MARGIN_AREA; area < LAST_AREA; ++area)
14552 for (i = 0; i < row->used[area]; ++i)
14553 row->hash = ((((row->hash << 4) + (row->hash >> 24)) & 0x0fffffff)
14554 + row->glyphs[area][i].u.val
14555 + row->glyphs[area][i].face_id
14556 + row->glyphs[area][i].padding_p
14557 + (row->glyphs[area][i].type << 2));
14558
14559 it->max_ascent = it->max_descent = 0;
14560 it->max_phys_ascent = it->max_phys_descent = 0;
14561 }
14562
14563
14564 /* Append one space to the glyph row of iterator IT if doing a
14565 window-based redisplay. The space has the same face as
14566 IT->face_id. Value is non-zero if a space was added.
14567
14568 This function is called to make sure that there is always one glyph
14569 at the end of a glyph row that the cursor can be set on under
14570 window-systems. (If there weren't such a glyph we would not know
14571 how wide and tall a box cursor should be displayed).
14572
14573 At the same time this space let's a nicely handle clearing to the
14574 end of the line if the row ends in italic text. */
14575
14576 static int
14577 append_space_for_newline (it, default_face_p)
14578 struct it *it;
14579 int default_face_p;
14580 {
14581 if (FRAME_WINDOW_P (it->f))
14582 {
14583 int n = it->glyph_row->used[TEXT_AREA];
14584
14585 if (it->glyph_row->glyphs[TEXT_AREA] + n
14586 < it->glyph_row->glyphs[1 + TEXT_AREA])
14587 {
14588 /* Save some values that must not be changed.
14589 Must save IT->c and IT->len because otherwise
14590 ITERATOR_AT_END_P wouldn't work anymore after
14591 append_space_for_newline has been called. */
14592 enum display_element_type saved_what = it->what;
14593 int saved_c = it->c, saved_len = it->len;
14594 int saved_x = it->current_x;
14595 int saved_face_id = it->face_id;
14596 struct text_pos saved_pos;
14597 Lisp_Object saved_object;
14598 struct face *face;
14599
14600 saved_object = it->object;
14601 saved_pos = it->position;
14602
14603 it->what = IT_CHARACTER;
14604 bzero (&it->position, sizeof it->position);
14605 it->object = make_number (0);
14606 it->c = ' ';
14607 it->len = 1;
14608
14609 if (default_face_p)
14610 it->face_id = DEFAULT_FACE_ID;
14611 else if (it->face_before_selective_p)
14612 it->face_id = it->saved_face_id;
14613 face = FACE_FROM_ID (it->f, it->face_id);
14614 it->face_id = FACE_FOR_CHAR (it->f, face, 0);
14615
14616 PRODUCE_GLYPHS (it);
14617
14618 it->override_ascent = -1;
14619 it->constrain_row_ascent_descent_p = 0;
14620 it->current_x = saved_x;
14621 it->object = saved_object;
14622 it->position = saved_pos;
14623 it->what = saved_what;
14624 it->face_id = saved_face_id;
14625 it->len = saved_len;
14626 it->c = saved_c;
14627 return 1;
14628 }
14629 }
14630
14631 return 0;
14632 }
14633
14634
14635 /* Extend the face of the last glyph in the text area of IT->glyph_row
14636 to the end of the display line. Called from display_line.
14637 If the glyph row is empty, add a space glyph to it so that we
14638 know the face to draw. Set the glyph row flag fill_line_p. */
14639
14640 static void
14641 extend_face_to_end_of_line (it)
14642 struct it *it;
14643 {
14644 struct face *face;
14645 struct frame *f = it->f;
14646
14647 /* If line is already filled, do nothing. */
14648 if (it->current_x >= it->last_visible_x)
14649 return;
14650
14651 /* Face extension extends the background and box of IT->face_id
14652 to the end of the line. If the background equals the background
14653 of the frame, we don't have to do anything. */
14654 if (it->face_before_selective_p)
14655 face = FACE_FROM_ID (it->f, it->saved_face_id);
14656 else
14657 face = FACE_FROM_ID (f, it->face_id);
14658
14659 if (FRAME_WINDOW_P (f)
14660 && face->box == FACE_NO_BOX
14661 && face->background == FRAME_BACKGROUND_PIXEL (f)
14662 && !face->stipple)
14663 return;
14664
14665 /* Set the glyph row flag indicating that the face of the last glyph
14666 in the text area has to be drawn to the end of the text area. */
14667 it->glyph_row->fill_line_p = 1;
14668
14669 /* If current character of IT is not ASCII, make sure we have the
14670 ASCII face. This will be automatically undone the next time
14671 get_next_display_element returns a multibyte character. Note
14672 that the character will always be single byte in unibyte text. */
14673 if (!SINGLE_BYTE_CHAR_P (it->c))
14674 {
14675 it->face_id = FACE_FOR_CHAR (f, face, 0);
14676 }
14677
14678 if (FRAME_WINDOW_P (f))
14679 {
14680 /* If the row is empty, add a space with the current face of IT,
14681 so that we know which face to draw. */
14682 if (it->glyph_row->used[TEXT_AREA] == 0)
14683 {
14684 it->glyph_row->glyphs[TEXT_AREA][0] = space_glyph;
14685 it->glyph_row->glyphs[TEXT_AREA][0].face_id = it->face_id;
14686 it->glyph_row->used[TEXT_AREA] = 1;
14687 }
14688 }
14689 else
14690 {
14691 /* Save some values that must not be changed. */
14692 int saved_x = it->current_x;
14693 struct text_pos saved_pos;
14694 Lisp_Object saved_object;
14695 enum display_element_type saved_what = it->what;
14696 int saved_face_id = it->face_id;
14697
14698 saved_object = it->object;
14699 saved_pos = it->position;
14700
14701 it->what = IT_CHARACTER;
14702 bzero (&it->position, sizeof it->position);
14703 it->object = make_number (0);
14704 it->c = ' ';
14705 it->len = 1;
14706 it->face_id = face->id;
14707
14708 PRODUCE_GLYPHS (it);
14709
14710 while (it->current_x <= it->last_visible_x)
14711 PRODUCE_GLYPHS (it);
14712
14713 /* Don't count these blanks really. It would let us insert a left
14714 truncation glyph below and make us set the cursor on them, maybe. */
14715 it->current_x = saved_x;
14716 it->object = saved_object;
14717 it->position = saved_pos;
14718 it->what = saved_what;
14719 it->face_id = saved_face_id;
14720 }
14721 }
14722
14723
14724 /* Value is non-zero if text starting at CHARPOS in current_buffer is
14725 trailing whitespace. */
14726
14727 static int
14728 trailing_whitespace_p (charpos)
14729 int charpos;
14730 {
14731 int bytepos = CHAR_TO_BYTE (charpos);
14732 int c = 0;
14733
14734 while (bytepos < ZV_BYTE
14735 && (c = FETCH_CHAR (bytepos),
14736 c == ' ' || c == '\t'))
14737 ++bytepos;
14738
14739 if (bytepos >= ZV_BYTE || c == '\n' || c == '\r')
14740 {
14741 if (bytepos != PT_BYTE)
14742 return 1;
14743 }
14744 return 0;
14745 }
14746
14747
14748 /* Highlight trailing whitespace, if any, in ROW. */
14749
14750 void
14751 highlight_trailing_whitespace (f, row)
14752 struct frame *f;
14753 struct glyph_row *row;
14754 {
14755 int used = row->used[TEXT_AREA];
14756
14757 if (used)
14758 {
14759 struct glyph *start = row->glyphs[TEXT_AREA];
14760 struct glyph *glyph = start + used - 1;
14761
14762 /* Skip over glyphs inserted to display the cursor at the
14763 end of a line, for extending the face of the last glyph
14764 to the end of the line on terminals, and for truncation
14765 and continuation glyphs. */
14766 while (glyph >= start
14767 && glyph->type == CHAR_GLYPH
14768 && INTEGERP (glyph->object))
14769 --glyph;
14770
14771 /* If last glyph is a space or stretch, and it's trailing
14772 whitespace, set the face of all trailing whitespace glyphs in
14773 IT->glyph_row to `trailing-whitespace'. */
14774 if (glyph >= start
14775 && BUFFERP (glyph->object)
14776 && (glyph->type == STRETCH_GLYPH
14777 || (glyph->type == CHAR_GLYPH
14778 && glyph->u.ch == ' '))
14779 && trailing_whitespace_p (glyph->charpos))
14780 {
14781 int face_id = lookup_named_face (f, Qtrailing_whitespace, 0, 0);
14782 if (face_id < 0)
14783 return;
14784
14785 while (glyph >= start
14786 && BUFFERP (glyph->object)
14787 && (glyph->type == STRETCH_GLYPH
14788 || (glyph->type == CHAR_GLYPH
14789 && glyph->u.ch == ' ')))
14790 (glyph--)->face_id = face_id;
14791 }
14792 }
14793 }
14794
14795
14796 /* Value is non-zero if glyph row ROW in window W should be
14797 used to hold the cursor. */
14798
14799 static int
14800 cursor_row_p (w, row)
14801 struct window *w;
14802 struct glyph_row *row;
14803 {
14804 int cursor_row_p = 1;
14805
14806 if (PT == MATRIX_ROW_END_CHARPOS (row))
14807 {
14808 /* If the row ends with a newline from a string, we don't want
14809 the cursor there (if the row is continued it doesn't end in a
14810 newline). */
14811 if (CHARPOS (row->end.string_pos) >= 0)
14812 cursor_row_p = row->continued_p;
14813 else if (MATRIX_ROW_ENDS_IN_MIDDLE_OF_CHAR_P (row))
14814 {
14815 /* If the row ends in middle of a real character,
14816 and the line is continued, we want the cursor here.
14817 That's because MATRIX_ROW_END_CHARPOS would equal
14818 PT if PT is before the character. */
14819 if (!row->ends_in_ellipsis_p)
14820 cursor_row_p = row->continued_p;
14821 else
14822 /* If the row ends in an ellipsis, then
14823 MATRIX_ROW_END_CHARPOS will equal point after the invisible text.
14824 We want that position to be displayed after the ellipsis. */
14825 cursor_row_p = 0;
14826 }
14827 /* If the row ends at ZV, display the cursor at the end of that
14828 row instead of at the start of the row below. */
14829 else if (row->ends_at_zv_p)
14830 cursor_row_p = 1;
14831 else
14832 cursor_row_p = 0;
14833 }
14834
14835 return cursor_row_p;
14836 }
14837
14838
14839 /* Construct the glyph row IT->glyph_row in the desired matrix of
14840 IT->w from text at the current position of IT. See dispextern.h
14841 for an overview of struct it. Value is non-zero if
14842 IT->glyph_row displays text, as opposed to a line displaying ZV
14843 only. */
14844
14845 static int
14846 display_line (it)
14847 struct it *it;
14848 {
14849 struct glyph_row *row = it->glyph_row;
14850 Lisp_Object overlay_arrow_string;
14851
14852 /* We always start displaying at hpos zero even if hscrolled. */
14853 xassert (it->hpos == 0 && it->current_x == 0);
14854
14855 if (MATRIX_ROW_VPOS (row, it->w->desired_matrix)
14856 >= it->w->desired_matrix->nrows)
14857 {
14858 it->w->nrows_scale_factor++;
14859 fonts_changed_p = 1;
14860 return 0;
14861 }
14862
14863 /* Is IT->w showing the region? */
14864 it->w->region_showing = it->region_beg_charpos > 0 ? Qt : Qnil;
14865
14866 /* Clear the result glyph row and enable it. */
14867 prepare_desired_row (row);
14868
14869 row->y = it->current_y;
14870 row->start = it->start;
14871 row->continuation_lines_width = it->continuation_lines_width;
14872 row->displays_text_p = 1;
14873 row->starts_in_middle_of_char_p = it->starts_in_middle_of_char_p;
14874 it->starts_in_middle_of_char_p = 0;
14875
14876 /* Arrange the overlays nicely for our purposes. Usually, we call
14877 display_line on only one line at a time, in which case this
14878 can't really hurt too much, or we call it on lines which appear
14879 one after another in the buffer, in which case all calls to
14880 recenter_overlay_lists but the first will be pretty cheap. */
14881 recenter_overlay_lists (current_buffer, IT_CHARPOS (*it));
14882
14883 /* Move over display elements that are not visible because we are
14884 hscrolled. This may stop at an x-position < IT->first_visible_x
14885 if the first glyph is partially visible or if we hit a line end. */
14886 if (it->current_x < it->first_visible_x)
14887 {
14888 move_it_in_display_line_to (it, ZV, it->first_visible_x,
14889 MOVE_TO_POS | MOVE_TO_X);
14890 }
14891
14892 /* Get the initial row height. This is either the height of the
14893 text hscrolled, if there is any, or zero. */
14894 row->ascent = it->max_ascent;
14895 row->height = it->max_ascent + it->max_descent;
14896 row->phys_ascent = it->max_phys_ascent;
14897 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
14898 row->extra_line_spacing = it->max_extra_line_spacing;
14899
14900 /* Loop generating characters. The loop is left with IT on the next
14901 character to display. */
14902 while (1)
14903 {
14904 int n_glyphs_before, hpos_before, x_before;
14905 int x, i, nglyphs;
14906 int ascent = 0, descent = 0, phys_ascent = 0, phys_descent = 0;
14907
14908 /* Retrieve the next thing to display. Value is zero if end of
14909 buffer reached. */
14910 if (!get_next_display_element (it))
14911 {
14912 /* Maybe add a space at the end of this line that is used to
14913 display the cursor there under X. Set the charpos of the
14914 first glyph of blank lines not corresponding to any text
14915 to -1. */
14916 #ifdef HAVE_WINDOW_SYSTEM
14917 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
14918 row->exact_window_width_line_p = 1;
14919 else
14920 #endif /* HAVE_WINDOW_SYSTEM */
14921 if ((append_space_for_newline (it, 1) && row->used[TEXT_AREA] == 1)
14922 || row->used[TEXT_AREA] == 0)
14923 {
14924 row->glyphs[TEXT_AREA]->charpos = -1;
14925 row->displays_text_p = 0;
14926
14927 if (!NILP (XBUFFER (it->w->buffer)->indicate_empty_lines)
14928 && (!MINI_WINDOW_P (it->w)
14929 || (minibuf_level && EQ (it->window, minibuf_window))))
14930 row->indicate_empty_line_p = 1;
14931 }
14932
14933 it->continuation_lines_width = 0;
14934 row->ends_at_zv_p = 1;
14935 break;
14936 }
14937
14938 /* Now, get the metrics of what we want to display. This also
14939 generates glyphs in `row' (which is IT->glyph_row). */
14940 n_glyphs_before = row->used[TEXT_AREA];
14941 x = it->current_x;
14942
14943 /* Remember the line height so far in case the next element doesn't
14944 fit on the line. */
14945 if (!it->truncate_lines_p)
14946 {
14947 ascent = it->max_ascent;
14948 descent = it->max_descent;
14949 phys_ascent = it->max_phys_ascent;
14950 phys_descent = it->max_phys_descent;
14951 }
14952
14953 PRODUCE_GLYPHS (it);
14954
14955 /* If this display element was in marginal areas, continue with
14956 the next one. */
14957 if (it->area != TEXT_AREA)
14958 {
14959 row->ascent = max (row->ascent, it->max_ascent);
14960 row->height = max (row->height, it->max_ascent + it->max_descent);
14961 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14962 row->phys_height = max (row->phys_height,
14963 it->max_phys_ascent + it->max_phys_descent);
14964 row->extra_line_spacing = max (row->extra_line_spacing,
14965 it->max_extra_line_spacing);
14966 set_iterator_to_next (it, 1);
14967 continue;
14968 }
14969
14970 /* Does the display element fit on the line? If we truncate
14971 lines, we should draw past the right edge of the window. If
14972 we don't truncate, we want to stop so that we can display the
14973 continuation glyph before the right margin. If lines are
14974 continued, there are two possible strategies for characters
14975 resulting in more than 1 glyph (e.g. tabs): Display as many
14976 glyphs as possible in this line and leave the rest for the
14977 continuation line, or display the whole element in the next
14978 line. Original redisplay did the former, so we do it also. */
14979 nglyphs = row->used[TEXT_AREA] - n_glyphs_before;
14980 hpos_before = it->hpos;
14981 x_before = x;
14982
14983 if (/* Not a newline. */
14984 nglyphs > 0
14985 /* Glyphs produced fit entirely in the line. */
14986 && it->current_x < it->last_visible_x)
14987 {
14988 it->hpos += nglyphs;
14989 row->ascent = max (row->ascent, it->max_ascent);
14990 row->height = max (row->height, it->max_ascent + it->max_descent);
14991 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
14992 row->phys_height = max (row->phys_height,
14993 it->max_phys_ascent + it->max_phys_descent);
14994 row->extra_line_spacing = max (row->extra_line_spacing,
14995 it->max_extra_line_spacing);
14996 if (it->current_x - it->pixel_width < it->first_visible_x)
14997 row->x = x - it->first_visible_x;
14998 }
14999 else
15000 {
15001 int new_x;
15002 struct glyph *glyph;
15003
15004 for (i = 0; i < nglyphs; ++i, x = new_x)
15005 {
15006 glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
15007 new_x = x + glyph->pixel_width;
15008
15009 if (/* Lines are continued. */
15010 !it->truncate_lines_p
15011 && (/* Glyph doesn't fit on the line. */
15012 new_x > it->last_visible_x
15013 /* Or it fits exactly on a window system frame. */
15014 || (new_x == it->last_visible_x
15015 && FRAME_WINDOW_P (it->f))))
15016 {
15017 /* End of a continued line. */
15018
15019 if (it->hpos == 0
15020 || (new_x == it->last_visible_x
15021 && FRAME_WINDOW_P (it->f)))
15022 {
15023 /* Current glyph is the only one on the line or
15024 fits exactly on the line. We must continue
15025 the line because we can't draw the cursor
15026 after the glyph. */
15027 row->continued_p = 1;
15028 it->current_x = new_x;
15029 it->continuation_lines_width += new_x;
15030 ++it->hpos;
15031 if (i == nglyphs - 1)
15032 {
15033 set_iterator_to_next (it, 1);
15034 #ifdef HAVE_WINDOW_SYSTEM
15035 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15036 {
15037 if (!get_next_display_element (it))
15038 {
15039 row->exact_window_width_line_p = 1;
15040 it->continuation_lines_width = 0;
15041 row->continued_p = 0;
15042 row->ends_at_zv_p = 1;
15043 }
15044 else if (ITERATOR_AT_END_OF_LINE_P (it))
15045 {
15046 row->continued_p = 0;
15047 row->exact_window_width_line_p = 1;
15048 }
15049 }
15050 #endif /* HAVE_WINDOW_SYSTEM */
15051 }
15052 }
15053 else if (CHAR_GLYPH_PADDING_P (*glyph)
15054 && !FRAME_WINDOW_P (it->f))
15055 {
15056 /* A padding glyph that doesn't fit on this line.
15057 This means the whole character doesn't fit
15058 on the line. */
15059 row->used[TEXT_AREA] = n_glyphs_before;
15060
15061 /* Fill the rest of the row with continuation
15062 glyphs like in 20.x. */
15063 while (row->glyphs[TEXT_AREA] + row->used[TEXT_AREA]
15064 < row->glyphs[1 + TEXT_AREA])
15065 produce_special_glyphs (it, IT_CONTINUATION);
15066
15067 row->continued_p = 1;
15068 it->current_x = x_before;
15069 it->continuation_lines_width += x_before;
15070
15071 /* Restore the height to what it was before the
15072 element not fitting on the line. */
15073 it->max_ascent = ascent;
15074 it->max_descent = descent;
15075 it->max_phys_ascent = phys_ascent;
15076 it->max_phys_descent = phys_descent;
15077 }
15078 else if (it->c == '\t' && FRAME_WINDOW_P (it->f))
15079 {
15080 /* A TAB that extends past the right edge of the
15081 window. This produces a single glyph on
15082 window system frames. We leave the glyph in
15083 this row and let it fill the row, but don't
15084 consume the TAB. */
15085 it->continuation_lines_width += it->last_visible_x;
15086 row->ends_in_middle_of_char_p = 1;
15087 row->continued_p = 1;
15088 glyph->pixel_width = it->last_visible_x - x;
15089 it->starts_in_middle_of_char_p = 1;
15090 }
15091 else
15092 {
15093 /* Something other than a TAB that draws past
15094 the right edge of the window. Restore
15095 positions to values before the element. */
15096 row->used[TEXT_AREA] = n_glyphs_before + i;
15097
15098 /* Display continuation glyphs. */
15099 if (!FRAME_WINDOW_P (it->f))
15100 produce_special_glyphs (it, IT_CONTINUATION);
15101 row->continued_p = 1;
15102
15103 it->continuation_lines_width += x;
15104
15105 if (nglyphs > 1 && i > 0)
15106 {
15107 row->ends_in_middle_of_char_p = 1;
15108 it->starts_in_middle_of_char_p = 1;
15109 }
15110
15111 /* Restore the height to what it was before the
15112 element not fitting on the line. */
15113 it->max_ascent = ascent;
15114 it->max_descent = descent;
15115 it->max_phys_ascent = phys_ascent;
15116 it->max_phys_descent = phys_descent;
15117 }
15118
15119 break;
15120 }
15121 else if (new_x > it->first_visible_x)
15122 {
15123 /* Increment number of glyphs actually displayed. */
15124 ++it->hpos;
15125
15126 if (x < it->first_visible_x)
15127 /* Glyph is partially visible, i.e. row starts at
15128 negative X position. */
15129 row->x = x - it->first_visible_x;
15130 }
15131 else
15132 {
15133 /* Glyph is completely off the left margin of the
15134 window. This should not happen because of the
15135 move_it_in_display_line at the start of this
15136 function, unless the text display area of the
15137 window is empty. */
15138 xassert (it->first_visible_x <= it->last_visible_x);
15139 }
15140 }
15141
15142 row->ascent = max (row->ascent, it->max_ascent);
15143 row->height = max (row->height, it->max_ascent + it->max_descent);
15144 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
15145 row->phys_height = max (row->phys_height,
15146 it->max_phys_ascent + it->max_phys_descent);
15147 row->extra_line_spacing = max (row->extra_line_spacing,
15148 it->max_extra_line_spacing);
15149
15150 /* End of this display line if row is continued. */
15151 if (row->continued_p || row->ends_at_zv_p)
15152 break;
15153 }
15154
15155 at_end_of_line:
15156 /* Is this a line end? If yes, we're also done, after making
15157 sure that a non-default face is extended up to the right
15158 margin of the window. */
15159 if (ITERATOR_AT_END_OF_LINE_P (it))
15160 {
15161 int used_before = row->used[TEXT_AREA];
15162
15163 row->ends_in_newline_from_string_p = STRINGP (it->object);
15164
15165 #ifdef HAVE_WINDOW_SYSTEM
15166 /* Add a space at the end of the line that is used to
15167 display the cursor there. */
15168 if (!IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15169 append_space_for_newline (it, 0);
15170 #endif /* HAVE_WINDOW_SYSTEM */
15171
15172 /* Extend the face to the end of the line. */
15173 extend_face_to_end_of_line (it);
15174
15175 /* Make sure we have the position. */
15176 if (used_before == 0)
15177 row->glyphs[TEXT_AREA]->charpos = CHARPOS (it->position);
15178
15179 /* Consume the line end. This skips over invisible lines. */
15180 set_iterator_to_next (it, 1);
15181 it->continuation_lines_width = 0;
15182 break;
15183 }
15184
15185 /* Proceed with next display element. Note that this skips
15186 over lines invisible because of selective display. */
15187 set_iterator_to_next (it, 1);
15188
15189 /* If we truncate lines, we are done when the last displayed
15190 glyphs reach past the right margin of the window. */
15191 if (it->truncate_lines_p
15192 && (FRAME_WINDOW_P (it->f)
15193 ? (it->current_x >= it->last_visible_x)
15194 : (it->current_x > it->last_visible_x)))
15195 {
15196 /* Maybe add truncation glyphs. */
15197 if (!FRAME_WINDOW_P (it->f))
15198 {
15199 int i, n;
15200
15201 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
15202 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
15203 break;
15204
15205 for (n = row->used[TEXT_AREA]; i < n; ++i)
15206 {
15207 row->used[TEXT_AREA] = i;
15208 produce_special_glyphs (it, IT_TRUNCATION);
15209 }
15210 }
15211 #ifdef HAVE_WINDOW_SYSTEM
15212 else
15213 {
15214 /* Don't truncate if we can overflow newline into fringe. */
15215 if (IT_OVERFLOW_NEWLINE_INTO_FRINGE (it))
15216 {
15217 if (!get_next_display_element (it))
15218 {
15219 it->continuation_lines_width = 0;
15220 row->ends_at_zv_p = 1;
15221 row->exact_window_width_line_p = 1;
15222 break;
15223 }
15224 if (ITERATOR_AT_END_OF_LINE_P (it))
15225 {
15226 row->exact_window_width_line_p = 1;
15227 goto at_end_of_line;
15228 }
15229 }
15230 }
15231 #endif /* HAVE_WINDOW_SYSTEM */
15232
15233 row->truncated_on_right_p = 1;
15234 it->continuation_lines_width = 0;
15235 reseat_at_next_visible_line_start (it, 0);
15236 row->ends_at_zv_p = FETCH_BYTE (IT_BYTEPOS (*it) - 1) != '\n';
15237 it->hpos = hpos_before;
15238 it->current_x = x_before;
15239 break;
15240 }
15241 }
15242
15243 /* If line is not empty and hscrolled, maybe insert truncation glyphs
15244 at the left window margin. */
15245 if (it->first_visible_x
15246 && IT_CHARPOS (*it) != MATRIX_ROW_START_CHARPOS (row))
15247 {
15248 if (!FRAME_WINDOW_P (it->f))
15249 insert_left_trunc_glyphs (it);
15250 row->truncated_on_left_p = 1;
15251 }
15252
15253 /* If the start of this line is the overlay arrow-position, then
15254 mark this glyph row as the one containing the overlay arrow.
15255 This is clearly a mess with variable size fonts. It would be
15256 better to let it be displayed like cursors under X. */
15257 if ((row->displays_text_p || !overlay_arrow_seen)
15258 && (overlay_arrow_string = overlay_arrow_at_row (it, row),
15259 !NILP (overlay_arrow_string)))
15260 {
15261 /* Overlay arrow in window redisplay is a fringe bitmap. */
15262 if (STRINGP (overlay_arrow_string))
15263 {
15264 struct glyph_row *arrow_row
15265 = get_overlay_arrow_glyph_row (it->w, overlay_arrow_string);
15266 struct glyph *glyph = arrow_row->glyphs[TEXT_AREA];
15267 struct glyph *arrow_end = glyph + arrow_row->used[TEXT_AREA];
15268 struct glyph *p = row->glyphs[TEXT_AREA];
15269 struct glyph *p2, *end;
15270
15271 /* Copy the arrow glyphs. */
15272 while (glyph < arrow_end)
15273 *p++ = *glyph++;
15274
15275 /* Throw away padding glyphs. */
15276 p2 = p;
15277 end = row->glyphs[TEXT_AREA] + row->used[TEXT_AREA];
15278 while (p2 < end && CHAR_GLYPH_PADDING_P (*p2))
15279 ++p2;
15280 if (p2 > p)
15281 {
15282 while (p2 < end)
15283 *p++ = *p2++;
15284 row->used[TEXT_AREA] = p2 - row->glyphs[TEXT_AREA];
15285 }
15286 }
15287 else
15288 {
15289 xassert (INTEGERP (overlay_arrow_string));
15290 row->overlay_arrow_bitmap = XINT (overlay_arrow_string);
15291 }
15292 overlay_arrow_seen = 1;
15293 }
15294
15295 /* Compute pixel dimensions of this line. */
15296 compute_line_metrics (it);
15297
15298 /* Remember the position at which this line ends. */
15299 row->end = it->current;
15300
15301 /* Record whether this row ends inside an ellipsis. */
15302 row->ends_in_ellipsis_p
15303 = (it->method == GET_FROM_DISPLAY_VECTOR
15304 && it->ellipsis_p);
15305
15306 /* Save fringe bitmaps in this row. */
15307 row->left_user_fringe_bitmap = it->left_user_fringe_bitmap;
15308 row->left_user_fringe_face_id = it->left_user_fringe_face_id;
15309 row->right_user_fringe_bitmap = it->right_user_fringe_bitmap;
15310 row->right_user_fringe_face_id = it->right_user_fringe_face_id;
15311
15312 it->left_user_fringe_bitmap = 0;
15313 it->left_user_fringe_face_id = 0;
15314 it->right_user_fringe_bitmap = 0;
15315 it->right_user_fringe_face_id = 0;
15316
15317 /* Maybe set the cursor. */
15318 if (it->w->cursor.vpos < 0
15319 && PT >= MATRIX_ROW_START_CHARPOS (row)
15320 && PT <= MATRIX_ROW_END_CHARPOS (row)
15321 && cursor_row_p (it->w, row))
15322 set_cursor_from_row (it->w, row, it->w->desired_matrix, 0, 0, 0, 0);
15323
15324 /* Highlight trailing whitespace. */
15325 if (!NILP (Vshow_trailing_whitespace))
15326 highlight_trailing_whitespace (it->f, it->glyph_row);
15327
15328 /* Prepare for the next line. This line starts horizontally at (X
15329 HPOS) = (0 0). Vertical positions are incremented. As a
15330 convenience for the caller, IT->glyph_row is set to the next
15331 row to be used. */
15332 it->current_x = it->hpos = 0;
15333 it->current_y += row->height;
15334 ++it->vpos;
15335 ++it->glyph_row;
15336 it->start = it->current;
15337 return row->displays_text_p;
15338 }
15339
15340
15341 \f
15342 /***********************************************************************
15343 Menu Bar
15344 ***********************************************************************/
15345
15346 /* Redisplay the menu bar in the frame for window W.
15347
15348 The menu bar of X frames that don't have X toolkit support is
15349 displayed in a special window W->frame->menu_bar_window.
15350
15351 The menu bar of terminal frames is treated specially as far as
15352 glyph matrices are concerned. Menu bar lines are not part of
15353 windows, so the update is done directly on the frame matrix rows
15354 for the menu bar. */
15355
15356 static void
15357 display_menu_bar (w)
15358 struct window *w;
15359 {
15360 struct frame *f = XFRAME (WINDOW_FRAME (w));
15361 struct it it;
15362 Lisp_Object items;
15363 int i;
15364
15365 /* Don't do all this for graphical frames. */
15366 #ifdef HAVE_NTGUI
15367 if (!NILP (Vwindow_system))
15368 return;
15369 #endif
15370 #if defined (USE_X_TOOLKIT) || defined (USE_GTK)
15371 if (FRAME_X_P (f))
15372 return;
15373 #endif
15374 #ifdef MAC_OS
15375 if (FRAME_MAC_P (f))
15376 return;
15377 #endif
15378
15379 #ifdef USE_X_TOOLKIT
15380 xassert (!FRAME_WINDOW_P (f));
15381 init_iterator (&it, w, -1, -1, f->desired_matrix->rows, MENU_FACE_ID);
15382 it.first_visible_x = 0;
15383 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15384 #else /* not USE_X_TOOLKIT */
15385 if (FRAME_WINDOW_P (f))
15386 {
15387 /* Menu bar lines are displayed in the desired matrix of the
15388 dummy window menu_bar_window. */
15389 struct window *menu_w;
15390 xassert (WINDOWP (f->menu_bar_window));
15391 menu_w = XWINDOW (f->menu_bar_window);
15392 init_iterator (&it, menu_w, -1, -1, menu_w->desired_matrix->rows,
15393 MENU_FACE_ID);
15394 it.first_visible_x = 0;
15395 it.last_visible_x = FRAME_TOTAL_COLS (f) * FRAME_COLUMN_WIDTH (f);
15396 }
15397 else
15398 {
15399 /* This is a TTY frame, i.e. character hpos/vpos are used as
15400 pixel x/y. */
15401 init_iterator (&it, w, -1, -1, f->desired_matrix->rows,
15402 MENU_FACE_ID);
15403 it.first_visible_x = 0;
15404 it.last_visible_x = FRAME_COLS (f);
15405 }
15406 #endif /* not USE_X_TOOLKIT */
15407
15408 if (! mode_line_inverse_video)
15409 /* Force the menu-bar to be displayed in the default face. */
15410 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15411
15412 /* Clear all rows of the menu bar. */
15413 for (i = 0; i < FRAME_MENU_BAR_LINES (f); ++i)
15414 {
15415 struct glyph_row *row = it.glyph_row + i;
15416 clear_glyph_row (row);
15417 row->enabled_p = 1;
15418 row->full_width_p = 1;
15419 }
15420
15421 /* Display all items of the menu bar. */
15422 items = FRAME_MENU_BAR_ITEMS (it.f);
15423 for (i = 0; i < XVECTOR (items)->size; i += 4)
15424 {
15425 Lisp_Object string;
15426
15427 /* Stop at nil string. */
15428 string = AREF (items, i + 1);
15429 if (NILP (string))
15430 break;
15431
15432 /* Remember where item was displayed. */
15433 AREF (items, i + 3) = make_number (it.hpos);
15434
15435 /* Display the item, pad with one space. */
15436 if (it.current_x < it.last_visible_x)
15437 display_string (NULL, string, Qnil, 0, 0, &it,
15438 SCHARS (string) + 1, 0, 0, -1);
15439 }
15440
15441 /* Fill out the line with spaces. */
15442 if (it.current_x < it.last_visible_x)
15443 display_string ("", Qnil, Qnil, 0, 0, &it, -1, 0, 0, -1);
15444
15445 /* Compute the total height of the lines. */
15446 compute_line_metrics (&it);
15447 }
15448
15449
15450 \f
15451 /***********************************************************************
15452 Mode Line
15453 ***********************************************************************/
15454
15455 /* Redisplay mode lines in the window tree whose root is WINDOW. If
15456 FORCE is non-zero, redisplay mode lines unconditionally.
15457 Otherwise, redisplay only mode lines that are garbaged. Value is
15458 the number of windows whose mode lines were redisplayed. */
15459
15460 static int
15461 redisplay_mode_lines (window, force)
15462 Lisp_Object window;
15463 int force;
15464 {
15465 int nwindows = 0;
15466
15467 while (!NILP (window))
15468 {
15469 struct window *w = XWINDOW (window);
15470
15471 if (WINDOWP (w->hchild))
15472 nwindows += redisplay_mode_lines (w->hchild, force);
15473 else if (WINDOWP (w->vchild))
15474 nwindows += redisplay_mode_lines (w->vchild, force);
15475 else if (force
15476 || FRAME_GARBAGED_P (XFRAME (w->frame))
15477 || !MATRIX_MODE_LINE_ROW (w->current_matrix)->enabled_p)
15478 {
15479 struct text_pos lpoint;
15480 struct buffer *old = current_buffer;
15481
15482 /* Set the window's buffer for the mode line display. */
15483 SET_TEXT_POS (lpoint, PT, PT_BYTE);
15484 set_buffer_internal_1 (XBUFFER (w->buffer));
15485
15486 /* Point refers normally to the selected window. For any
15487 other window, set up appropriate value. */
15488 if (!EQ (window, selected_window))
15489 {
15490 struct text_pos pt;
15491
15492 SET_TEXT_POS_FROM_MARKER (pt, w->pointm);
15493 if (CHARPOS (pt) < BEGV)
15494 TEMP_SET_PT_BOTH (BEGV, BEGV_BYTE);
15495 else if (CHARPOS (pt) > (ZV - 1))
15496 TEMP_SET_PT_BOTH (ZV, ZV_BYTE);
15497 else
15498 TEMP_SET_PT_BOTH (CHARPOS (pt), BYTEPOS (pt));
15499 }
15500
15501 /* Display mode lines. */
15502 clear_glyph_matrix (w->desired_matrix);
15503 if (display_mode_lines (w))
15504 {
15505 ++nwindows;
15506 w->must_be_updated_p = 1;
15507 }
15508
15509 /* Restore old settings. */
15510 set_buffer_internal_1 (old);
15511 TEMP_SET_PT_BOTH (CHARPOS (lpoint), BYTEPOS (lpoint));
15512 }
15513
15514 window = w->next;
15515 }
15516
15517 return nwindows;
15518 }
15519
15520
15521 /* Display the mode and/or top line of window W. Value is the number
15522 of mode lines displayed. */
15523
15524 static int
15525 display_mode_lines (w)
15526 struct window *w;
15527 {
15528 Lisp_Object old_selected_window, old_selected_frame;
15529 int n = 0;
15530
15531 old_selected_frame = selected_frame;
15532 selected_frame = w->frame;
15533 old_selected_window = selected_window;
15534 XSETWINDOW (selected_window, w);
15535
15536 /* These will be set while the mode line specs are processed. */
15537 line_number_displayed = 0;
15538 w->column_number_displayed = Qnil;
15539
15540 if (WINDOW_WANTS_MODELINE_P (w))
15541 {
15542 struct window *sel_w = XWINDOW (old_selected_window);
15543
15544 /* Select mode line face based on the real selected window. */
15545 display_mode_line (w, CURRENT_MODE_LINE_FACE_ID_3 (sel_w, sel_w, w),
15546 current_buffer->mode_line_format);
15547 ++n;
15548 }
15549
15550 if (WINDOW_WANTS_HEADER_LINE_P (w))
15551 {
15552 display_mode_line (w, HEADER_LINE_FACE_ID,
15553 current_buffer->header_line_format);
15554 ++n;
15555 }
15556
15557 selected_frame = old_selected_frame;
15558 selected_window = old_selected_window;
15559 return n;
15560 }
15561
15562
15563 /* Display mode or top line of window W. FACE_ID specifies which line
15564 to display; it is either MODE_LINE_FACE_ID or HEADER_LINE_FACE_ID.
15565 FORMAT is the mode line format to display. Value is the pixel
15566 height of the mode line displayed. */
15567
15568 static int
15569 display_mode_line (w, face_id, format)
15570 struct window *w;
15571 enum face_id face_id;
15572 Lisp_Object format;
15573 {
15574 struct it it;
15575 struct face *face;
15576
15577 init_iterator (&it, w, -1, -1, NULL, face_id);
15578 prepare_desired_row (it.glyph_row);
15579
15580 it.glyph_row->mode_line_p = 1;
15581
15582 if (! mode_line_inverse_video)
15583 /* Force the mode-line to be displayed in the default face. */
15584 it.base_face_id = it.face_id = DEFAULT_FACE_ID;
15585
15586 /* Temporarily make frame's keyboard the current kboard so that
15587 kboard-local variables in the mode_line_format will get the right
15588 values. */
15589 push_frame_kboard (it.f);
15590 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
15591 pop_frame_kboard ();
15592
15593 /* Fill up with spaces. */
15594 display_string (" ", Qnil, Qnil, 0, 0, &it, 10000, -1, -1, 0);
15595
15596 compute_line_metrics (&it);
15597 it.glyph_row->full_width_p = 1;
15598 it.glyph_row->continued_p = 0;
15599 it.glyph_row->truncated_on_left_p = 0;
15600 it.glyph_row->truncated_on_right_p = 0;
15601
15602 /* Make a 3D mode-line have a shadow at its right end. */
15603 face = FACE_FROM_ID (it.f, face_id);
15604 extend_face_to_end_of_line (&it);
15605 if (face->box != FACE_NO_BOX)
15606 {
15607 struct glyph *last = (it.glyph_row->glyphs[TEXT_AREA]
15608 + it.glyph_row->used[TEXT_AREA] - 1);
15609 last->right_box_line_p = 1;
15610 }
15611
15612 return it.glyph_row->height;
15613 }
15614
15615 /* Alist that caches the results of :propertize.
15616 Each element is (PROPERTIZED-STRING . PROPERTY-LIST). */
15617 Lisp_Object mode_line_proptrans_alist;
15618
15619 /* List of strings making up the mode-line. */
15620 Lisp_Object mode_line_string_list;
15621
15622 /* Base face property when building propertized mode line string. */
15623 static Lisp_Object mode_line_string_face;
15624 static Lisp_Object mode_line_string_face_prop;
15625
15626
15627 /* Contribute ELT to the mode line for window IT->w. How it
15628 translates into text depends on its data type.
15629
15630 IT describes the display environment in which we display, as usual.
15631
15632 DEPTH is the depth in recursion. It is used to prevent
15633 infinite recursion here.
15634
15635 FIELD_WIDTH is the number of characters the display of ELT should
15636 occupy in the mode line, and PRECISION is the maximum number of
15637 characters to display from ELT's representation. See
15638 display_string for details.
15639
15640 Returns the hpos of the end of the text generated by ELT.
15641
15642 PROPS is a property list to add to any string we encounter.
15643
15644 If RISKY is nonzero, remove (disregard) any properties in any string
15645 we encounter, and ignore :eval and :propertize.
15646
15647 If the global variable `frame_title_ptr' is non-NULL, then the output
15648 is passed to `store_frame_title' instead of `display_string'. */
15649
15650 static int
15651 display_mode_element (it, depth, field_width, precision, elt, props, risky)
15652 struct it *it;
15653 int depth;
15654 int field_width, precision;
15655 Lisp_Object elt, props;
15656 int risky;
15657 {
15658 int n = 0, field, prec;
15659 int literal = 0;
15660
15661 tail_recurse:
15662 if (depth > 100)
15663 elt = build_string ("*too-deep*");
15664
15665 depth++;
15666
15667 switch (SWITCH_ENUM_CAST (XTYPE (elt)))
15668 {
15669 case Lisp_String:
15670 {
15671 /* A string: output it and check for %-constructs within it. */
15672 unsigned char c;
15673 const unsigned char *this, *lisp_string;
15674
15675 if (!NILP (props) || risky)
15676 {
15677 Lisp_Object oprops, aelt;
15678 oprops = Ftext_properties_at (make_number (0), elt);
15679
15680 /* If the starting string's properties are not what
15681 we want, translate the string. Also, if the string
15682 is risky, do that anyway. */
15683
15684 if (NILP (Fequal (props, oprops)) || risky)
15685 {
15686 /* If the starting string has properties,
15687 merge the specified ones onto the existing ones. */
15688 if (! NILP (oprops) && !risky)
15689 {
15690 Lisp_Object tem;
15691
15692 oprops = Fcopy_sequence (oprops);
15693 tem = props;
15694 while (CONSP (tem))
15695 {
15696 oprops = Fplist_put (oprops, XCAR (tem),
15697 XCAR (XCDR (tem)));
15698 tem = XCDR (XCDR (tem));
15699 }
15700 props = oprops;
15701 }
15702
15703 aelt = Fassoc (elt, mode_line_proptrans_alist);
15704 if (! NILP (aelt) && !NILP (Fequal (props, XCDR (aelt))))
15705 {
15706 mode_line_proptrans_alist
15707 = Fcons (aelt, Fdelq (aelt, mode_line_proptrans_alist));
15708 elt = XCAR (aelt);
15709 }
15710 else
15711 {
15712 Lisp_Object tem;
15713
15714 elt = Fcopy_sequence (elt);
15715 Fset_text_properties (make_number (0), Flength (elt),
15716 props, elt);
15717 /* Add this item to mode_line_proptrans_alist. */
15718 mode_line_proptrans_alist
15719 = Fcons (Fcons (elt, props),
15720 mode_line_proptrans_alist);
15721 /* Truncate mode_line_proptrans_alist
15722 to at most 50 elements. */
15723 tem = Fnthcdr (make_number (50),
15724 mode_line_proptrans_alist);
15725 if (! NILP (tem))
15726 XSETCDR (tem, Qnil);
15727 }
15728 }
15729 }
15730
15731 this = SDATA (elt);
15732 lisp_string = this;
15733
15734 if (literal)
15735 {
15736 prec = precision - n;
15737 if (frame_title_ptr)
15738 n += store_frame_title (SDATA (elt), -1, prec);
15739 else if (!NILP (mode_line_string_list))
15740 n += store_mode_line_string (NULL, elt, 1, 0, prec, Qnil);
15741 else
15742 n += display_string (NULL, elt, Qnil, 0, 0, it,
15743 0, prec, 0, STRING_MULTIBYTE (elt));
15744
15745 break;
15746 }
15747
15748 while ((precision <= 0 || n < precision)
15749 && *this
15750 && (frame_title_ptr
15751 || !NILP (mode_line_string_list)
15752 || it->current_x < it->last_visible_x))
15753 {
15754 const unsigned char *last = this;
15755
15756 /* Advance to end of string or next format specifier. */
15757 while ((c = *this++) != '\0' && c != '%')
15758 ;
15759
15760 if (this - 1 != last)
15761 {
15762 int nchars, nbytes;
15763
15764 /* Output to end of string or up to '%'. Field width
15765 is length of string. Don't output more than
15766 PRECISION allows us. */
15767 --this;
15768
15769 prec = c_string_width (last, this - last, precision - n,
15770 &nchars, &nbytes);
15771
15772 if (frame_title_ptr)
15773 n += store_frame_title (last, 0, prec);
15774 else if (!NILP (mode_line_string_list))
15775 {
15776 int bytepos = last - lisp_string;
15777 int charpos = string_byte_to_char (elt, bytepos);
15778 int endpos = (precision <= 0
15779 ? string_byte_to_char (elt,
15780 this - lisp_string)
15781 : charpos + nchars);
15782
15783 n += store_mode_line_string (NULL,
15784 Fsubstring (elt, make_number (charpos),
15785 make_number (endpos)),
15786 0, 0, 0, Qnil);
15787 }
15788 else
15789 {
15790 int bytepos = last - lisp_string;
15791 int charpos = string_byte_to_char (elt, bytepos);
15792 n += display_string (NULL, elt, Qnil, 0, charpos,
15793 it, 0, prec, 0,
15794 STRING_MULTIBYTE (elt));
15795 }
15796 }
15797 else /* c == '%' */
15798 {
15799 const unsigned char *percent_position = this;
15800
15801 /* Get the specified minimum width. Zero means
15802 don't pad. */
15803 field = 0;
15804 while ((c = *this++) >= '0' && c <= '9')
15805 field = field * 10 + c - '0';
15806
15807 /* Don't pad beyond the total padding allowed. */
15808 if (field_width - n > 0 && field > field_width - n)
15809 field = field_width - n;
15810
15811 /* Note that either PRECISION <= 0 or N < PRECISION. */
15812 prec = precision - n;
15813
15814 if (c == 'M')
15815 n += display_mode_element (it, depth, field, prec,
15816 Vglobal_mode_string, props,
15817 risky);
15818 else if (c != 0)
15819 {
15820 int multibyte;
15821 int bytepos, charpos;
15822 unsigned char *spec;
15823
15824 bytepos = percent_position - lisp_string;
15825 charpos = (STRING_MULTIBYTE (elt)
15826 ? string_byte_to_char (elt, bytepos)
15827 : bytepos);
15828
15829 spec
15830 = decode_mode_spec (it->w, c, field, prec, &multibyte);
15831
15832 if (frame_title_ptr)
15833 n += store_frame_title (spec, field, prec);
15834 else if (!NILP (mode_line_string_list))
15835 {
15836 int len = strlen (spec);
15837 Lisp_Object tem = make_string (spec, len);
15838 props = Ftext_properties_at (make_number (charpos), elt);
15839 /* Should only keep face property in props */
15840 n += store_mode_line_string (NULL, tem, 0, field, prec, props);
15841 }
15842 else
15843 {
15844 int nglyphs_before, nwritten;
15845
15846 nglyphs_before = it->glyph_row->used[TEXT_AREA];
15847 nwritten = display_string (spec, Qnil, elt,
15848 charpos, 0, it,
15849 field, prec, 0,
15850 multibyte);
15851
15852 /* Assign to the glyphs written above the
15853 string where the `%x' came from, position
15854 of the `%'. */
15855 if (nwritten > 0)
15856 {
15857 struct glyph *glyph
15858 = (it->glyph_row->glyphs[TEXT_AREA]
15859 + nglyphs_before);
15860 int i;
15861
15862 for (i = 0; i < nwritten; ++i)
15863 {
15864 glyph[i].object = elt;
15865 glyph[i].charpos = charpos;
15866 }
15867
15868 n += nwritten;
15869 }
15870 }
15871 }
15872 else /* c == 0 */
15873 break;
15874 }
15875 }
15876 }
15877 break;
15878
15879 case Lisp_Symbol:
15880 /* A symbol: process the value of the symbol recursively
15881 as if it appeared here directly. Avoid error if symbol void.
15882 Special case: if value of symbol is a string, output the string
15883 literally. */
15884 {
15885 register Lisp_Object tem;
15886
15887 /* If the variable is not marked as risky to set
15888 then its contents are risky to use. */
15889 if (NILP (Fget (elt, Qrisky_local_variable)))
15890 risky = 1;
15891
15892 tem = Fboundp (elt);
15893 if (!NILP (tem))
15894 {
15895 tem = Fsymbol_value (elt);
15896 /* If value is a string, output that string literally:
15897 don't check for % within it. */
15898 if (STRINGP (tem))
15899 literal = 1;
15900
15901 if (!EQ (tem, elt))
15902 {
15903 /* Give up right away for nil or t. */
15904 elt = tem;
15905 goto tail_recurse;
15906 }
15907 }
15908 }
15909 break;
15910
15911 case Lisp_Cons:
15912 {
15913 register Lisp_Object car, tem;
15914
15915 /* A cons cell: five distinct cases.
15916 If first element is :eval or :propertize, do something special.
15917 If first element is a string or a cons, process all the elements
15918 and effectively concatenate them.
15919 If first element is a negative number, truncate displaying cdr to
15920 at most that many characters. If positive, pad (with spaces)
15921 to at least that many characters.
15922 If first element is a symbol, process the cadr or caddr recursively
15923 according to whether the symbol's value is non-nil or nil. */
15924 car = XCAR (elt);
15925 if (EQ (car, QCeval))
15926 {
15927 /* An element of the form (:eval FORM) means evaluate FORM
15928 and use the result as mode line elements. */
15929
15930 if (risky)
15931 break;
15932
15933 if (CONSP (XCDR (elt)))
15934 {
15935 Lisp_Object spec;
15936 spec = safe_eval (XCAR (XCDR (elt)));
15937 n += display_mode_element (it, depth, field_width - n,
15938 precision - n, spec, props,
15939 risky);
15940 }
15941 }
15942 else if (EQ (car, QCpropertize))
15943 {
15944 /* An element of the form (:propertize ELT PROPS...)
15945 means display ELT but applying properties PROPS. */
15946
15947 if (risky)
15948 break;
15949
15950 if (CONSP (XCDR (elt)))
15951 n += display_mode_element (it, depth, field_width - n,
15952 precision - n, XCAR (XCDR (elt)),
15953 XCDR (XCDR (elt)), risky);
15954 }
15955 else if (SYMBOLP (car))
15956 {
15957 tem = Fboundp (car);
15958 elt = XCDR (elt);
15959 if (!CONSP (elt))
15960 goto invalid;
15961 /* elt is now the cdr, and we know it is a cons cell.
15962 Use its car if CAR has a non-nil value. */
15963 if (!NILP (tem))
15964 {
15965 tem = Fsymbol_value (car);
15966 if (!NILP (tem))
15967 {
15968 elt = XCAR (elt);
15969 goto tail_recurse;
15970 }
15971 }
15972 /* Symbol's value is nil (or symbol is unbound)
15973 Get the cddr of the original list
15974 and if possible find the caddr and use that. */
15975 elt = XCDR (elt);
15976 if (NILP (elt))
15977 break;
15978 else if (!CONSP (elt))
15979 goto invalid;
15980 elt = XCAR (elt);
15981 goto tail_recurse;
15982 }
15983 else if (INTEGERP (car))
15984 {
15985 register int lim = XINT (car);
15986 elt = XCDR (elt);
15987 if (lim < 0)
15988 {
15989 /* Negative int means reduce maximum width. */
15990 if (precision <= 0)
15991 precision = -lim;
15992 else
15993 precision = min (precision, -lim);
15994 }
15995 else if (lim > 0)
15996 {
15997 /* Padding specified. Don't let it be more than
15998 current maximum. */
15999 if (precision > 0)
16000 lim = min (precision, lim);
16001
16002 /* If that's more padding than already wanted, queue it.
16003 But don't reduce padding already specified even if
16004 that is beyond the current truncation point. */
16005 field_width = max (lim, field_width);
16006 }
16007 goto tail_recurse;
16008 }
16009 else if (STRINGP (car) || CONSP (car))
16010 {
16011 register int limit = 50;
16012 /* Limit is to protect against circular lists. */
16013 while (CONSP (elt)
16014 && --limit > 0
16015 && (precision <= 0 || n < precision))
16016 {
16017 n += display_mode_element (it, depth, field_width - n,
16018 precision - n, XCAR (elt),
16019 props, risky);
16020 elt = XCDR (elt);
16021 }
16022 }
16023 }
16024 break;
16025
16026 default:
16027 invalid:
16028 elt = build_string ("*invalid*");
16029 goto tail_recurse;
16030 }
16031
16032 /* Pad to FIELD_WIDTH. */
16033 if (field_width > 0 && n < field_width)
16034 {
16035 if (frame_title_ptr)
16036 n += store_frame_title ("", field_width - n, 0);
16037 else if (!NILP (mode_line_string_list))
16038 n += store_mode_line_string ("", Qnil, 0, field_width - n, 0, Qnil);
16039 else
16040 n += display_string ("", Qnil, Qnil, 0, 0, it, field_width - n,
16041 0, 0, 0);
16042 }
16043
16044 return n;
16045 }
16046
16047 /* Store a mode-line string element in mode_line_string_list.
16048
16049 If STRING is non-null, display that C string. Otherwise, the Lisp
16050 string LISP_STRING is displayed.
16051
16052 FIELD_WIDTH is the minimum number of output glyphs to produce.
16053 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16054 with spaces. FIELD_WIDTH <= 0 means don't pad.
16055
16056 PRECISION is the maximum number of characters to output from
16057 STRING. PRECISION <= 0 means don't truncate the string.
16058
16059 If COPY_STRING is non-zero, make a copy of LISP_STRING before adding
16060 properties to the string.
16061
16062 PROPS are the properties to add to the string.
16063 The mode_line_string_face face property is always added to the string.
16064 */
16065
16066 static int
16067 store_mode_line_string (string, lisp_string, copy_string, field_width, precision, props)
16068 char *string;
16069 Lisp_Object lisp_string;
16070 int copy_string;
16071 int field_width;
16072 int precision;
16073 Lisp_Object props;
16074 {
16075 int len;
16076 int n = 0;
16077
16078 if (string != NULL)
16079 {
16080 len = strlen (string);
16081 if (precision > 0 && len > precision)
16082 len = precision;
16083 lisp_string = make_string (string, len);
16084 if (NILP (props))
16085 props = mode_line_string_face_prop;
16086 else if (!NILP (mode_line_string_face))
16087 {
16088 Lisp_Object face = Fplist_get (props, Qface);
16089 props = Fcopy_sequence (props);
16090 if (NILP (face))
16091 face = mode_line_string_face;
16092 else
16093 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16094 props = Fplist_put (props, Qface, face);
16095 }
16096 Fadd_text_properties (make_number (0), make_number (len),
16097 props, lisp_string);
16098 }
16099 else
16100 {
16101 len = XFASTINT (Flength (lisp_string));
16102 if (precision > 0 && len > precision)
16103 {
16104 len = precision;
16105 lisp_string = Fsubstring (lisp_string, make_number (0), make_number (len));
16106 precision = -1;
16107 }
16108 if (!NILP (mode_line_string_face))
16109 {
16110 Lisp_Object face;
16111 if (NILP (props))
16112 props = Ftext_properties_at (make_number (0), lisp_string);
16113 face = Fplist_get (props, Qface);
16114 if (NILP (face))
16115 face = mode_line_string_face;
16116 else
16117 face = Fcons (face, Fcons (mode_line_string_face, Qnil));
16118 props = Fcons (Qface, Fcons (face, Qnil));
16119 if (copy_string)
16120 lisp_string = Fcopy_sequence (lisp_string);
16121 }
16122 if (!NILP (props))
16123 Fadd_text_properties (make_number (0), make_number (len),
16124 props, lisp_string);
16125 }
16126
16127 if (len > 0)
16128 {
16129 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16130 n += len;
16131 }
16132
16133 if (field_width > len)
16134 {
16135 field_width -= len;
16136 lisp_string = Fmake_string (make_number (field_width), make_number (' '));
16137 if (!NILP (props))
16138 Fadd_text_properties (make_number (0), make_number (field_width),
16139 props, lisp_string);
16140 mode_line_string_list = Fcons (lisp_string, mode_line_string_list);
16141 n += field_width;
16142 }
16143
16144 return n;
16145 }
16146
16147
16148 DEFUN ("format-mode-line", Fformat_mode_line, Sformat_mode_line,
16149 1, 4, 0,
16150 doc: /* Format a string out of a mode line format specification.
16151 First arg FORMAT specifies the mode line format (see `mode-line-format'
16152 for details) to use.
16153
16154 Optional second arg FACE specifies the face property to put
16155 on all characters for which no face is specified.
16156 t means whatever face the window's mode line currently uses
16157 \(either `mode-line' or `mode-line-inactive', depending).
16158 nil means the default is no face property.
16159 If FACE is an integer, the value string has no text properties.
16160
16161 Optional third and fourth args WINDOW and BUFFER specify the window
16162 and buffer to use as the context for the formatting (defaults
16163 are the selected window and the window's buffer). */)
16164 (format, face, window, buffer)
16165 Lisp_Object format, face, window, buffer;
16166 {
16167 struct it it;
16168 int len;
16169 struct window *w;
16170 struct buffer *old_buffer = NULL;
16171 int face_id = -1;
16172 int no_props = INTEGERP (face);
16173
16174 if (NILP (window))
16175 window = selected_window;
16176 CHECK_WINDOW (window);
16177 w = XWINDOW (window);
16178
16179 if (NILP (buffer))
16180 buffer = w->buffer;
16181 CHECK_BUFFER (buffer);
16182
16183 if (NILP (format))
16184 return build_string ("");
16185
16186 if (no_props)
16187 face = Qnil;
16188
16189 if (!NILP (face))
16190 {
16191 if (EQ (face, Qt))
16192 face = (EQ (window, selected_window) ? Qmode_line : Qmode_line_inactive);
16193 face_id = lookup_named_face (XFRAME (WINDOW_FRAME (w)), face, 0, 0);
16194 }
16195
16196 if (face_id < 0)
16197 face_id = DEFAULT_FACE_ID;
16198
16199 if (XBUFFER (buffer) != current_buffer)
16200 {
16201 old_buffer = current_buffer;
16202 set_buffer_internal_1 (XBUFFER (buffer));
16203 }
16204
16205 init_iterator (&it, w, -1, -1, NULL, face_id);
16206
16207 if (!no_props)
16208 {
16209 mode_line_string_face = face;
16210 mode_line_string_face_prop
16211 = (NILP (face) ? Qnil : Fcons (Qface, Fcons (face, Qnil)));
16212
16213 /* We need a dummy last element in mode_line_string_list to
16214 indicate we are building the propertized mode-line string.
16215 Using mode_line_string_face_prop here GC protects it. */
16216 mode_line_string_list
16217 = Fcons (mode_line_string_face_prop, Qnil);
16218 frame_title_ptr = NULL;
16219 }
16220 else
16221 {
16222 mode_line_string_face_prop = Qnil;
16223 mode_line_string_list = Qnil;
16224 frame_title_ptr = frame_title_buf;
16225 }
16226
16227 push_frame_kboard (it.f);
16228 display_mode_element (&it, 0, 0, 0, format, Qnil, 0);
16229 pop_frame_kboard ();
16230
16231 if (old_buffer)
16232 set_buffer_internal_1 (old_buffer);
16233
16234 if (!no_props)
16235 {
16236 Lisp_Object str;
16237 mode_line_string_list = Fnreverse (mode_line_string_list);
16238 str = Fmapconcat (intern ("identity"), XCDR (mode_line_string_list),
16239 make_string ("", 0));
16240 mode_line_string_face_prop = Qnil;
16241 mode_line_string_list = Qnil;
16242 return str;
16243 }
16244
16245 len = frame_title_ptr - frame_title_buf;
16246 if (len > 0 && frame_title_ptr[-1] == '-')
16247 {
16248 /* Mode lines typically ends with numerous dashes; reduce to two dashes. */
16249 while (frame_title_ptr > frame_title_buf && *--frame_title_ptr == '-')
16250 ;
16251 frame_title_ptr += 3; /* restore last non-dash + two dashes */
16252 if (len > frame_title_ptr - frame_title_buf)
16253 len = frame_title_ptr - frame_title_buf;
16254 }
16255
16256 frame_title_ptr = NULL;
16257 return make_string (frame_title_buf, len);
16258 }
16259
16260 /* Write a null-terminated, right justified decimal representation of
16261 the positive integer D to BUF using a minimal field width WIDTH. */
16262
16263 static void
16264 pint2str (buf, width, d)
16265 register char *buf;
16266 register int width;
16267 register int d;
16268 {
16269 register char *p = buf;
16270
16271 if (d <= 0)
16272 *p++ = '0';
16273 else
16274 {
16275 while (d > 0)
16276 {
16277 *p++ = d % 10 + '0';
16278 d /= 10;
16279 }
16280 }
16281
16282 for (width -= (int) (p - buf); width > 0; --width)
16283 *p++ = ' ';
16284 *p-- = '\0';
16285 while (p > buf)
16286 {
16287 d = *buf;
16288 *buf++ = *p;
16289 *p-- = d;
16290 }
16291 }
16292
16293 /* Write a null-terminated, right justified decimal and "human
16294 readable" representation of the nonnegative integer D to BUF using
16295 a minimal field width WIDTH. D should be smaller than 999.5e24. */
16296
16297 static const char power_letter[] =
16298 {
16299 0, /* not used */
16300 'k', /* kilo */
16301 'M', /* mega */
16302 'G', /* giga */
16303 'T', /* tera */
16304 'P', /* peta */
16305 'E', /* exa */
16306 'Z', /* zetta */
16307 'Y' /* yotta */
16308 };
16309
16310 static void
16311 pint2hrstr (buf, width, d)
16312 char *buf;
16313 int width;
16314 int d;
16315 {
16316 /* We aim to represent the nonnegative integer D as
16317 QUOTIENT.TENTHS * 10 ^ (3 * EXPONENT). */
16318 int quotient = d;
16319 int remainder = 0;
16320 /* -1 means: do not use TENTHS. */
16321 int tenths = -1;
16322 int exponent = 0;
16323
16324 /* Length of QUOTIENT.TENTHS as a string. */
16325 int length;
16326
16327 char * psuffix;
16328 char * p;
16329
16330 if (1000 <= quotient)
16331 {
16332 /* Scale to the appropriate EXPONENT. */
16333 do
16334 {
16335 remainder = quotient % 1000;
16336 quotient /= 1000;
16337 exponent++;
16338 }
16339 while (1000 <= quotient);
16340
16341 /* Round to nearest and decide whether to use TENTHS or not. */
16342 if (quotient <= 9)
16343 {
16344 tenths = remainder / 100;
16345 if (50 <= remainder % 100)
16346 {
16347 if (tenths < 9)
16348 tenths++;
16349 else
16350 {
16351 quotient++;
16352 if (quotient == 10)
16353 tenths = -1;
16354 else
16355 tenths = 0;
16356 }
16357 }
16358 }
16359 else
16360 if (500 <= remainder)
16361 {
16362 if (quotient < 999)
16363 quotient++;
16364 else
16365 {
16366 quotient = 1;
16367 exponent++;
16368 tenths = 0;
16369 }
16370 }
16371 }
16372
16373 /* Calculate the LENGTH of QUOTIENT.TENTHS as a string. */
16374 if (tenths == -1 && quotient <= 99)
16375 if (quotient <= 9)
16376 length = 1;
16377 else
16378 length = 2;
16379 else
16380 length = 3;
16381 p = psuffix = buf + max (width, length);
16382
16383 /* Print EXPONENT. */
16384 if (exponent)
16385 *psuffix++ = power_letter[exponent];
16386 *psuffix = '\0';
16387
16388 /* Print TENTHS. */
16389 if (tenths >= 0)
16390 {
16391 *--p = '0' + tenths;
16392 *--p = '.';
16393 }
16394
16395 /* Print QUOTIENT. */
16396 do
16397 {
16398 int digit = quotient % 10;
16399 *--p = '0' + digit;
16400 }
16401 while ((quotient /= 10) != 0);
16402
16403 /* Print leading spaces. */
16404 while (buf < p)
16405 *--p = ' ';
16406 }
16407
16408 /* Set a mnemonic character for coding_system (Lisp symbol) in BUF.
16409 If EOL_FLAG is 1, set also a mnemonic character for end-of-line
16410 type of CODING_SYSTEM. Return updated pointer into BUF. */
16411
16412 static unsigned char invalid_eol_type[] = "(*invalid*)";
16413
16414 static char *
16415 decode_mode_spec_coding (coding_system, buf, eol_flag)
16416 Lisp_Object coding_system;
16417 register char *buf;
16418 int eol_flag;
16419 {
16420 Lisp_Object val;
16421 int multibyte = !NILP (current_buffer->enable_multibyte_characters);
16422 const unsigned char *eol_str;
16423 int eol_str_len;
16424 /* The EOL conversion we are using. */
16425 Lisp_Object eoltype;
16426
16427 val = Fget (coding_system, Qcoding_system);
16428 eoltype = Qnil;
16429
16430 if (!VECTORP (val)) /* Not yet decided. */
16431 {
16432 if (multibyte)
16433 *buf++ = '-';
16434 if (eol_flag)
16435 eoltype = eol_mnemonic_undecided;
16436 /* Don't mention EOL conversion if it isn't decided. */
16437 }
16438 else
16439 {
16440 Lisp_Object eolvalue;
16441
16442 eolvalue = Fget (coding_system, Qeol_type);
16443
16444 if (multibyte)
16445 *buf++ = XFASTINT (AREF (val, 1));
16446
16447 if (eol_flag)
16448 {
16449 /* The EOL conversion that is normal on this system. */
16450
16451 if (NILP (eolvalue)) /* Not yet decided. */
16452 eoltype = eol_mnemonic_undecided;
16453 else if (VECTORP (eolvalue)) /* Not yet decided. */
16454 eoltype = eol_mnemonic_undecided;
16455 else /* INTEGERP (eolvalue) -- 0:LF, 1:CRLF, 2:CR */
16456 eoltype = (XFASTINT (eolvalue) == 0
16457 ? eol_mnemonic_unix
16458 : (XFASTINT (eolvalue) == 1
16459 ? eol_mnemonic_dos : eol_mnemonic_mac));
16460 }
16461 }
16462
16463 if (eol_flag)
16464 {
16465 /* Mention the EOL conversion if it is not the usual one. */
16466 if (STRINGP (eoltype))
16467 {
16468 eol_str = SDATA (eoltype);
16469 eol_str_len = SBYTES (eoltype);
16470 }
16471 else if (INTEGERP (eoltype)
16472 && CHAR_VALID_P (XINT (eoltype), 0))
16473 {
16474 unsigned char *tmp = (unsigned char *) alloca (MAX_MULTIBYTE_LENGTH);
16475 eol_str_len = CHAR_STRING (XINT (eoltype), tmp);
16476 eol_str = tmp;
16477 }
16478 else
16479 {
16480 eol_str = invalid_eol_type;
16481 eol_str_len = sizeof (invalid_eol_type) - 1;
16482 }
16483 bcopy (eol_str, buf, eol_str_len);
16484 buf += eol_str_len;
16485 }
16486
16487 return buf;
16488 }
16489
16490 /* Return a string for the output of a mode line %-spec for window W,
16491 generated by character C. PRECISION >= 0 means don't return a
16492 string longer than that value. FIELD_WIDTH > 0 means pad the
16493 string returned with spaces to that value. Return 1 in *MULTIBYTE
16494 if the result is multibyte text.
16495
16496 Note we operate on the current buffer for most purposes,
16497 the exception being w->base_line_pos. */
16498
16499 static char lots_of_dashes[] = "--------------------------------------------------------------------------------------------------------------------------------------------";
16500
16501 static char *
16502 decode_mode_spec (w, c, field_width, precision, multibyte)
16503 struct window *w;
16504 register int c;
16505 int field_width, precision;
16506 int *multibyte;
16507 {
16508 Lisp_Object obj;
16509 struct frame *f = XFRAME (WINDOW_FRAME (w));
16510 char *decode_mode_spec_buf = f->decode_mode_spec_buffer;
16511 struct buffer *b = current_buffer;
16512
16513 obj = Qnil;
16514 *multibyte = 0;
16515
16516 switch (c)
16517 {
16518 case '*':
16519 if (!NILP (b->read_only))
16520 return "%";
16521 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16522 return "*";
16523 return "-";
16524
16525 case '+':
16526 /* This differs from %* only for a modified read-only buffer. */
16527 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16528 return "*";
16529 if (!NILP (b->read_only))
16530 return "%";
16531 return "-";
16532
16533 case '&':
16534 /* This differs from %* in ignoring read-only-ness. */
16535 if (BUF_MODIFF (b) > BUF_SAVE_MODIFF (b))
16536 return "*";
16537 return "-";
16538
16539 case '%':
16540 return "%";
16541
16542 case '[':
16543 {
16544 int i;
16545 char *p;
16546
16547 if (command_loop_level > 5)
16548 return "[[[... ";
16549 p = decode_mode_spec_buf;
16550 for (i = 0; i < command_loop_level; i++)
16551 *p++ = '[';
16552 *p = 0;
16553 return decode_mode_spec_buf;
16554 }
16555
16556 case ']':
16557 {
16558 int i;
16559 char *p;
16560
16561 if (command_loop_level > 5)
16562 return " ...]]]";
16563 p = decode_mode_spec_buf;
16564 for (i = 0; i < command_loop_level; i++)
16565 *p++ = ']';
16566 *p = 0;
16567 return decode_mode_spec_buf;
16568 }
16569
16570 case '-':
16571 {
16572 register int i;
16573
16574 /* Let lots_of_dashes be a string of infinite length. */
16575 if (!NILP (mode_line_string_list))
16576 return "--";
16577 if (field_width <= 0
16578 || field_width > sizeof (lots_of_dashes))
16579 {
16580 for (i = 0; i < FRAME_MESSAGE_BUF_SIZE (f) - 1; ++i)
16581 decode_mode_spec_buf[i] = '-';
16582 decode_mode_spec_buf[i] = '\0';
16583 return decode_mode_spec_buf;
16584 }
16585 else
16586 return lots_of_dashes;
16587 }
16588
16589 case 'b':
16590 obj = b->name;
16591 break;
16592
16593 case 'c':
16594 {
16595 int col = (int) current_column (); /* iftc */
16596 w->column_number_displayed = make_number (col);
16597 pint2str (decode_mode_spec_buf, field_width, col);
16598 return decode_mode_spec_buf;
16599 }
16600
16601 case 'F':
16602 /* %F displays the frame name. */
16603 if (!NILP (f->title))
16604 return (char *) SDATA (f->title);
16605 if (f->explicit_name || ! FRAME_WINDOW_P (f))
16606 return (char *) SDATA (f->name);
16607 return "Emacs";
16608
16609 case 'f':
16610 obj = b->filename;
16611 break;
16612
16613 case 'i':
16614 {
16615 int size = ZV - BEGV;
16616 pint2str (decode_mode_spec_buf, field_width, size);
16617 return decode_mode_spec_buf;
16618 }
16619
16620 case 'I':
16621 {
16622 int size = ZV - BEGV;
16623 pint2hrstr (decode_mode_spec_buf, field_width, size);
16624 return decode_mode_spec_buf;
16625 }
16626
16627 case 'l':
16628 {
16629 int startpos = XMARKER (w->start)->charpos;
16630 int startpos_byte = marker_byte_position (w->start);
16631 int line, linepos, linepos_byte, topline;
16632 int nlines, junk;
16633 int height = WINDOW_TOTAL_LINES (w);
16634
16635 /* If we decided that this buffer isn't suitable for line numbers,
16636 don't forget that too fast. */
16637 if (EQ (w->base_line_pos, w->buffer))
16638 goto no_value;
16639 /* But do forget it, if the window shows a different buffer now. */
16640 else if (BUFFERP (w->base_line_pos))
16641 w->base_line_pos = Qnil;
16642
16643 /* If the buffer is very big, don't waste time. */
16644 if (INTEGERP (Vline_number_display_limit)
16645 && BUF_ZV (b) - BUF_BEGV (b) > XINT (Vline_number_display_limit))
16646 {
16647 w->base_line_pos = Qnil;
16648 w->base_line_number = Qnil;
16649 goto no_value;
16650 }
16651
16652 if (!NILP (w->base_line_number)
16653 && !NILP (w->base_line_pos)
16654 && XFASTINT (w->base_line_pos) <= startpos)
16655 {
16656 line = XFASTINT (w->base_line_number);
16657 linepos = XFASTINT (w->base_line_pos);
16658 linepos_byte = buf_charpos_to_bytepos (b, linepos);
16659 }
16660 else
16661 {
16662 line = 1;
16663 linepos = BUF_BEGV (b);
16664 linepos_byte = BUF_BEGV_BYTE (b);
16665 }
16666
16667 /* Count lines from base line to window start position. */
16668 nlines = display_count_lines (linepos, linepos_byte,
16669 startpos_byte,
16670 startpos, &junk);
16671
16672 topline = nlines + line;
16673
16674 /* Determine a new base line, if the old one is too close
16675 or too far away, or if we did not have one.
16676 "Too close" means it's plausible a scroll-down would
16677 go back past it. */
16678 if (startpos == BUF_BEGV (b))
16679 {
16680 w->base_line_number = make_number (topline);
16681 w->base_line_pos = make_number (BUF_BEGV (b));
16682 }
16683 else if (nlines < height + 25 || nlines > height * 3 + 50
16684 || linepos == BUF_BEGV (b))
16685 {
16686 int limit = BUF_BEGV (b);
16687 int limit_byte = BUF_BEGV_BYTE (b);
16688 int position;
16689 int distance = (height * 2 + 30) * line_number_display_limit_width;
16690
16691 if (startpos - distance > limit)
16692 {
16693 limit = startpos - distance;
16694 limit_byte = CHAR_TO_BYTE (limit);
16695 }
16696
16697 nlines = display_count_lines (startpos, startpos_byte,
16698 limit_byte,
16699 - (height * 2 + 30),
16700 &position);
16701 /* If we couldn't find the lines we wanted within
16702 line_number_display_limit_width chars per line,
16703 give up on line numbers for this window. */
16704 if (position == limit_byte && limit == startpos - distance)
16705 {
16706 w->base_line_pos = w->buffer;
16707 w->base_line_number = Qnil;
16708 goto no_value;
16709 }
16710
16711 w->base_line_number = make_number (topline - nlines);
16712 w->base_line_pos = make_number (BYTE_TO_CHAR (position));
16713 }
16714
16715 /* Now count lines from the start pos to point. */
16716 nlines = display_count_lines (startpos, startpos_byte,
16717 PT_BYTE, PT, &junk);
16718
16719 /* Record that we did display the line number. */
16720 line_number_displayed = 1;
16721
16722 /* Make the string to show. */
16723 pint2str (decode_mode_spec_buf, field_width, topline + nlines);
16724 return decode_mode_spec_buf;
16725 no_value:
16726 {
16727 char* p = decode_mode_spec_buf;
16728 int pad = field_width - 2;
16729 while (pad-- > 0)
16730 *p++ = ' ';
16731 *p++ = '?';
16732 *p++ = '?';
16733 *p = '\0';
16734 return decode_mode_spec_buf;
16735 }
16736 }
16737 break;
16738
16739 case 'm':
16740 obj = b->mode_name;
16741 break;
16742
16743 case 'n':
16744 if (BUF_BEGV (b) > BUF_BEG (b) || BUF_ZV (b) < BUF_Z (b))
16745 return " Narrow";
16746 break;
16747
16748 case 'p':
16749 {
16750 int pos = marker_position (w->start);
16751 int total = BUF_ZV (b) - BUF_BEGV (b);
16752
16753 if (XFASTINT (w->window_end_pos) <= BUF_Z (b) - BUF_ZV (b))
16754 {
16755 if (pos <= BUF_BEGV (b))
16756 return "All";
16757 else
16758 return "Bottom";
16759 }
16760 else if (pos <= BUF_BEGV (b))
16761 return "Top";
16762 else
16763 {
16764 if (total > 1000000)
16765 /* Do it differently for a large value, to avoid overflow. */
16766 total = ((pos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16767 else
16768 total = ((pos - BUF_BEGV (b)) * 100 + total - 1) / total;
16769 /* We can't normally display a 3-digit number,
16770 so get us a 2-digit number that is close. */
16771 if (total == 100)
16772 total = 99;
16773 sprintf (decode_mode_spec_buf, "%2d%%", total);
16774 return decode_mode_spec_buf;
16775 }
16776 }
16777
16778 /* Display percentage of size above the bottom of the screen. */
16779 case 'P':
16780 {
16781 int toppos = marker_position (w->start);
16782 int botpos = BUF_Z (b) - XFASTINT (w->window_end_pos);
16783 int total = BUF_ZV (b) - BUF_BEGV (b);
16784
16785 if (botpos >= BUF_ZV (b))
16786 {
16787 if (toppos <= BUF_BEGV (b))
16788 return "All";
16789 else
16790 return "Bottom";
16791 }
16792 else
16793 {
16794 if (total > 1000000)
16795 /* Do it differently for a large value, to avoid overflow. */
16796 total = ((botpos - BUF_BEGV (b)) + (total / 100) - 1) / (total / 100);
16797 else
16798 total = ((botpos - BUF_BEGV (b)) * 100 + total - 1) / total;
16799 /* We can't normally display a 3-digit number,
16800 so get us a 2-digit number that is close. */
16801 if (total == 100)
16802 total = 99;
16803 if (toppos <= BUF_BEGV (b))
16804 sprintf (decode_mode_spec_buf, "Top%2d%%", total);
16805 else
16806 sprintf (decode_mode_spec_buf, "%2d%%", total);
16807 return decode_mode_spec_buf;
16808 }
16809 }
16810
16811 case 's':
16812 /* status of process */
16813 obj = Fget_buffer_process (Fcurrent_buffer ());
16814 if (NILP (obj))
16815 return "no process";
16816 #ifdef subprocesses
16817 obj = Fsymbol_name (Fprocess_status (obj));
16818 #endif
16819 break;
16820
16821 case 't': /* indicate TEXT or BINARY */
16822 #ifdef MODE_LINE_BINARY_TEXT
16823 return MODE_LINE_BINARY_TEXT (b);
16824 #else
16825 return "T";
16826 #endif
16827
16828 case 'z':
16829 /* coding-system (not including end-of-line format) */
16830 case 'Z':
16831 /* coding-system (including end-of-line type) */
16832 {
16833 int eol_flag = (c == 'Z');
16834 char *p = decode_mode_spec_buf;
16835
16836 if (! FRAME_WINDOW_P (f))
16837 {
16838 /* No need to mention EOL here--the terminal never needs
16839 to do EOL conversion. */
16840 p = decode_mode_spec_coding (keyboard_coding.symbol, p, 0);
16841 p = decode_mode_spec_coding (terminal_coding.symbol, p, 0);
16842 }
16843 p = decode_mode_spec_coding (b->buffer_file_coding_system,
16844 p, eol_flag);
16845
16846 #if 0 /* This proves to be annoying; I think we can do without. -- rms. */
16847 #ifdef subprocesses
16848 obj = Fget_buffer_process (Fcurrent_buffer ());
16849 if (PROCESSP (obj))
16850 {
16851 p = decode_mode_spec_coding (XPROCESS (obj)->decode_coding_system,
16852 p, eol_flag);
16853 p = decode_mode_spec_coding (XPROCESS (obj)->encode_coding_system,
16854 p, eol_flag);
16855 }
16856 #endif /* subprocesses */
16857 #endif /* 0 */
16858 *p = 0;
16859 return decode_mode_spec_buf;
16860 }
16861 }
16862
16863 if (STRINGP (obj))
16864 {
16865 *multibyte = STRING_MULTIBYTE (obj);
16866 return (char *) SDATA (obj);
16867 }
16868 else
16869 return "";
16870 }
16871
16872
16873 /* Count up to COUNT lines starting from START / START_BYTE.
16874 But don't go beyond LIMIT_BYTE.
16875 Return the number of lines thus found (always nonnegative).
16876
16877 Set *BYTE_POS_PTR to 1 if we found COUNT lines, 0 if we hit LIMIT. */
16878
16879 static int
16880 display_count_lines (start, start_byte, limit_byte, count, byte_pos_ptr)
16881 int start, start_byte, limit_byte, count;
16882 int *byte_pos_ptr;
16883 {
16884 register unsigned char *cursor;
16885 unsigned char *base;
16886
16887 register int ceiling;
16888 register unsigned char *ceiling_addr;
16889 int orig_count = count;
16890
16891 /* If we are not in selective display mode,
16892 check only for newlines. */
16893 int selective_display = (!NILP (current_buffer->selective_display)
16894 && !INTEGERP (current_buffer->selective_display));
16895
16896 if (count > 0)
16897 {
16898 while (start_byte < limit_byte)
16899 {
16900 ceiling = BUFFER_CEILING_OF (start_byte);
16901 ceiling = min (limit_byte - 1, ceiling);
16902 ceiling_addr = BYTE_POS_ADDR (ceiling) + 1;
16903 base = (cursor = BYTE_POS_ADDR (start_byte));
16904 while (1)
16905 {
16906 if (selective_display)
16907 while (*cursor != '\n' && *cursor != 015 && ++cursor != ceiling_addr)
16908 ;
16909 else
16910 while (*cursor != '\n' && ++cursor != ceiling_addr)
16911 ;
16912
16913 if (cursor != ceiling_addr)
16914 {
16915 if (--count == 0)
16916 {
16917 start_byte += cursor - base + 1;
16918 *byte_pos_ptr = start_byte;
16919 return orig_count;
16920 }
16921 else
16922 if (++cursor == ceiling_addr)
16923 break;
16924 }
16925 else
16926 break;
16927 }
16928 start_byte += cursor - base;
16929 }
16930 }
16931 else
16932 {
16933 while (start_byte > limit_byte)
16934 {
16935 ceiling = BUFFER_FLOOR_OF (start_byte - 1);
16936 ceiling = max (limit_byte, ceiling);
16937 ceiling_addr = BYTE_POS_ADDR (ceiling) - 1;
16938 base = (cursor = BYTE_POS_ADDR (start_byte - 1) + 1);
16939 while (1)
16940 {
16941 if (selective_display)
16942 while (--cursor != ceiling_addr
16943 && *cursor != '\n' && *cursor != 015)
16944 ;
16945 else
16946 while (--cursor != ceiling_addr && *cursor != '\n')
16947 ;
16948
16949 if (cursor != ceiling_addr)
16950 {
16951 if (++count == 0)
16952 {
16953 start_byte += cursor - base + 1;
16954 *byte_pos_ptr = start_byte;
16955 /* When scanning backwards, we should
16956 not count the newline posterior to which we stop. */
16957 return - orig_count - 1;
16958 }
16959 }
16960 else
16961 break;
16962 }
16963 /* Here we add 1 to compensate for the last decrement
16964 of CURSOR, which took it past the valid range. */
16965 start_byte += cursor - base + 1;
16966 }
16967 }
16968
16969 *byte_pos_ptr = limit_byte;
16970
16971 if (count < 0)
16972 return - orig_count + count;
16973 return orig_count - count;
16974
16975 }
16976
16977
16978 \f
16979 /***********************************************************************
16980 Displaying strings
16981 ***********************************************************************/
16982
16983 /* Display a NUL-terminated string, starting with index START.
16984
16985 If STRING is non-null, display that C string. Otherwise, the Lisp
16986 string LISP_STRING is displayed.
16987
16988 If FACE_STRING is not nil, FACE_STRING_POS is a position in
16989 FACE_STRING. Display STRING or LISP_STRING with the face at
16990 FACE_STRING_POS in FACE_STRING:
16991
16992 Display the string in the environment given by IT, but use the
16993 standard display table, temporarily.
16994
16995 FIELD_WIDTH is the minimum number of output glyphs to produce.
16996 If STRING has fewer characters than FIELD_WIDTH, pad to the right
16997 with spaces. If STRING has more characters, more than FIELD_WIDTH
16998 glyphs will be produced. FIELD_WIDTH <= 0 means don't pad.
16999
17000 PRECISION is the maximum number of characters to output from
17001 STRING. PRECISION < 0 means don't truncate the string.
17002
17003 This is roughly equivalent to printf format specifiers:
17004
17005 FIELD_WIDTH PRECISION PRINTF
17006 ----------------------------------------
17007 -1 -1 %s
17008 -1 10 %.10s
17009 10 -1 %10s
17010 20 10 %20.10s
17011
17012 MULTIBYTE zero means do not display multibyte chars, > 0 means do
17013 display them, and < 0 means obey the current buffer's value of
17014 enable_multibyte_characters.
17015
17016 Value is the number of glyphs produced. */
17017
17018 static int
17019 display_string (string, lisp_string, face_string, face_string_pos,
17020 start, it, field_width, precision, max_x, multibyte)
17021 unsigned char *string;
17022 Lisp_Object lisp_string;
17023 Lisp_Object face_string;
17024 int face_string_pos;
17025 int start;
17026 struct it *it;
17027 int field_width, precision, max_x;
17028 int multibyte;
17029 {
17030 int hpos_at_start = it->hpos;
17031 int saved_face_id = it->face_id;
17032 struct glyph_row *row = it->glyph_row;
17033
17034 /* Initialize the iterator IT for iteration over STRING beginning
17035 with index START. */
17036 reseat_to_string (it, string, lisp_string, start,
17037 precision, field_width, multibyte);
17038
17039 /* If displaying STRING, set up the face of the iterator
17040 from LISP_STRING, if that's given. */
17041 if (STRINGP (face_string))
17042 {
17043 int endptr;
17044 struct face *face;
17045
17046 it->face_id
17047 = face_at_string_position (it->w, face_string, face_string_pos,
17048 0, it->region_beg_charpos,
17049 it->region_end_charpos,
17050 &endptr, it->base_face_id, 0);
17051 face = FACE_FROM_ID (it->f, it->face_id);
17052 it->face_box_p = face->box != FACE_NO_BOX;
17053 }
17054
17055 /* Set max_x to the maximum allowed X position. Don't let it go
17056 beyond the right edge of the window. */
17057 if (max_x <= 0)
17058 max_x = it->last_visible_x;
17059 else
17060 max_x = min (max_x, it->last_visible_x);
17061
17062 /* Skip over display elements that are not visible. because IT->w is
17063 hscrolled. */
17064 if (it->current_x < it->first_visible_x)
17065 move_it_in_display_line_to (it, 100000, it->first_visible_x,
17066 MOVE_TO_POS | MOVE_TO_X);
17067
17068 row->ascent = it->max_ascent;
17069 row->height = it->max_ascent + it->max_descent;
17070 row->phys_ascent = it->max_phys_ascent;
17071 row->phys_height = it->max_phys_ascent + it->max_phys_descent;
17072 row->extra_line_spacing = it->max_extra_line_spacing;
17073
17074 /* This condition is for the case that we are called with current_x
17075 past last_visible_x. */
17076 while (it->current_x < max_x)
17077 {
17078 int x_before, x, n_glyphs_before, i, nglyphs;
17079
17080 /* Get the next display element. */
17081 if (!get_next_display_element (it))
17082 break;
17083
17084 /* Produce glyphs. */
17085 x_before = it->current_x;
17086 n_glyphs_before = it->glyph_row->used[TEXT_AREA];
17087 PRODUCE_GLYPHS (it);
17088
17089 nglyphs = it->glyph_row->used[TEXT_AREA] - n_glyphs_before;
17090 i = 0;
17091 x = x_before;
17092 while (i < nglyphs)
17093 {
17094 struct glyph *glyph = row->glyphs[TEXT_AREA] + n_glyphs_before + i;
17095
17096 if (!it->truncate_lines_p
17097 && x + glyph->pixel_width > max_x)
17098 {
17099 /* End of continued line or max_x reached. */
17100 if (CHAR_GLYPH_PADDING_P (*glyph))
17101 {
17102 /* A wide character is unbreakable. */
17103 it->glyph_row->used[TEXT_AREA] = n_glyphs_before;
17104 it->current_x = x_before;
17105 }
17106 else
17107 {
17108 it->glyph_row->used[TEXT_AREA] = n_glyphs_before + i;
17109 it->current_x = x;
17110 }
17111 break;
17112 }
17113 else if (x + glyph->pixel_width > it->first_visible_x)
17114 {
17115 /* Glyph is at least partially visible. */
17116 ++it->hpos;
17117 if (x < it->first_visible_x)
17118 it->glyph_row->x = x - it->first_visible_x;
17119 }
17120 else
17121 {
17122 /* Glyph is off the left margin of the display area.
17123 Should not happen. */
17124 abort ();
17125 }
17126
17127 row->ascent = max (row->ascent, it->max_ascent);
17128 row->height = max (row->height, it->max_ascent + it->max_descent);
17129 row->phys_ascent = max (row->phys_ascent, it->max_phys_ascent);
17130 row->phys_height = max (row->phys_height,
17131 it->max_phys_ascent + it->max_phys_descent);
17132 row->extra_line_spacing = max (row->extra_line_spacing,
17133 it->max_extra_line_spacing);
17134 x += glyph->pixel_width;
17135 ++i;
17136 }
17137
17138 /* Stop if max_x reached. */
17139 if (i < nglyphs)
17140 break;
17141
17142 /* Stop at line ends. */
17143 if (ITERATOR_AT_END_OF_LINE_P (it))
17144 {
17145 it->continuation_lines_width = 0;
17146 break;
17147 }
17148
17149 set_iterator_to_next (it, 1);
17150
17151 /* Stop if truncating at the right edge. */
17152 if (it->truncate_lines_p
17153 && it->current_x >= it->last_visible_x)
17154 {
17155 /* Add truncation mark, but don't do it if the line is
17156 truncated at a padding space. */
17157 if (IT_CHARPOS (*it) < it->string_nchars)
17158 {
17159 if (!FRAME_WINDOW_P (it->f))
17160 {
17161 int i, n;
17162
17163 if (it->current_x > it->last_visible_x)
17164 {
17165 for (i = row->used[TEXT_AREA] - 1; i > 0; --i)
17166 if (!CHAR_GLYPH_PADDING_P (row->glyphs[TEXT_AREA][i]))
17167 break;
17168 for (n = row->used[TEXT_AREA]; i < n; ++i)
17169 {
17170 row->used[TEXT_AREA] = i;
17171 produce_special_glyphs (it, IT_TRUNCATION);
17172 }
17173 }
17174 produce_special_glyphs (it, IT_TRUNCATION);
17175 }
17176 it->glyph_row->truncated_on_right_p = 1;
17177 }
17178 break;
17179 }
17180 }
17181
17182 /* Maybe insert a truncation at the left. */
17183 if (it->first_visible_x
17184 && IT_CHARPOS (*it) > 0)
17185 {
17186 if (!FRAME_WINDOW_P (it->f))
17187 insert_left_trunc_glyphs (it);
17188 it->glyph_row->truncated_on_left_p = 1;
17189 }
17190
17191 it->face_id = saved_face_id;
17192
17193 /* Value is number of columns displayed. */
17194 return it->hpos - hpos_at_start;
17195 }
17196
17197
17198 \f
17199 /* This is like a combination of memq and assq. Return 1/2 if PROPVAL
17200 appears as an element of LIST or as the car of an element of LIST.
17201 If PROPVAL is a list, compare each element against LIST in that
17202 way, and return 1/2 if any element of PROPVAL is found in LIST.
17203 Otherwise return 0. This function cannot quit.
17204 The return value is 2 if the text is invisible but with an ellipsis
17205 and 1 if it's invisible and without an ellipsis. */
17206
17207 int
17208 invisible_p (propval, list)
17209 register Lisp_Object propval;
17210 Lisp_Object list;
17211 {
17212 register Lisp_Object tail, proptail;
17213
17214 for (tail = list; CONSP (tail); tail = XCDR (tail))
17215 {
17216 register Lisp_Object tem;
17217 tem = XCAR (tail);
17218 if (EQ (propval, tem))
17219 return 1;
17220 if (CONSP (tem) && EQ (propval, XCAR (tem)))
17221 return NILP (XCDR (tem)) ? 1 : 2;
17222 }
17223
17224 if (CONSP (propval))
17225 {
17226 for (proptail = propval; CONSP (proptail); proptail = XCDR (proptail))
17227 {
17228 Lisp_Object propelt;
17229 propelt = XCAR (proptail);
17230 for (tail = list; CONSP (tail); tail = XCDR (tail))
17231 {
17232 register Lisp_Object tem;
17233 tem = XCAR (tail);
17234 if (EQ (propelt, tem))
17235 return 1;
17236 if (CONSP (tem) && EQ (propelt, XCAR (tem)))
17237 return NILP (XCDR (tem)) ? 1 : 2;
17238 }
17239 }
17240 }
17241
17242 return 0;
17243 }
17244
17245 /* Calculate a width or height in pixels from a specification using
17246 the following elements:
17247
17248 SPEC ::=
17249 NUM - a (fractional) multiple of the default font width/height
17250 (NUM) - specifies exactly NUM pixels
17251 UNIT - a fixed number of pixels, see below.
17252 ELEMENT - size of a display element in pixels, see below.
17253 (NUM . SPEC) - equals NUM * SPEC
17254 (+ SPEC SPEC ...) - add pixel values
17255 (- SPEC SPEC ...) - subtract pixel values
17256 (- SPEC) - negate pixel value
17257
17258 NUM ::=
17259 INT or FLOAT - a number constant
17260 SYMBOL - use symbol's (buffer local) variable binding.
17261
17262 UNIT ::=
17263 in - pixels per inch *)
17264 mm - pixels per 1/1000 meter *)
17265 cm - pixels per 1/100 meter *)
17266 width - width of current font in pixels.
17267 height - height of current font in pixels.
17268
17269 *) using the ratio(s) defined in display-pixels-per-inch.
17270
17271 ELEMENT ::=
17272
17273 left-fringe - left fringe width in pixels
17274 right-fringe - right fringe width in pixels
17275
17276 left-margin - left margin width in pixels
17277 right-margin - right margin width in pixels
17278
17279 scroll-bar - scroll-bar area width in pixels
17280
17281 Examples:
17282
17283 Pixels corresponding to 5 inches:
17284 (5 . in)
17285
17286 Total width of non-text areas on left side of window (if scroll-bar is on left):
17287 '(space :width (+ left-fringe left-margin scroll-bar))
17288
17289 Align to first text column (in header line):
17290 '(space :align-to 0)
17291
17292 Align to middle of text area minus half the width of variable `my-image'
17293 containing a loaded image:
17294 '(space :align-to (0.5 . (- text my-image)))
17295
17296 Width of left margin minus width of 1 character in the default font:
17297 '(space :width (- left-margin 1))
17298
17299 Width of left margin minus width of 2 characters in the current font:
17300 '(space :width (- left-margin (2 . width)))
17301
17302 Center 1 character over left-margin (in header line):
17303 '(space :align-to (+ left-margin (0.5 . left-margin) -0.5))
17304
17305 Different ways to express width of left fringe plus left margin minus one pixel:
17306 '(space :width (- (+ left-fringe left-margin) (1)))
17307 '(space :width (+ left-fringe left-margin (- (1))))
17308 '(space :width (+ left-fringe left-margin (-1)))
17309
17310 */
17311
17312 #define NUMVAL(X) \
17313 ((INTEGERP (X) || FLOATP (X)) \
17314 ? XFLOATINT (X) \
17315 : - 1)
17316
17317 int
17318 calc_pixel_width_or_height (res, it, prop, font, width_p, align_to)
17319 double *res;
17320 struct it *it;
17321 Lisp_Object prop;
17322 void *font;
17323 int width_p, *align_to;
17324 {
17325 double pixels;
17326
17327 #define OK_PIXELS(val) ((*res = (double)(val)), 1)
17328 #define OK_ALIGN_TO(val) ((*align_to = (int)(val)), 1)
17329
17330 if (NILP (prop))
17331 return OK_PIXELS (0);
17332
17333 if (SYMBOLP (prop))
17334 {
17335 if (SCHARS (SYMBOL_NAME (prop)) == 2)
17336 {
17337 char *unit = SDATA (SYMBOL_NAME (prop));
17338
17339 if (unit[0] == 'i' && unit[1] == 'n')
17340 pixels = 1.0;
17341 else if (unit[0] == 'm' && unit[1] == 'm')
17342 pixels = 25.4;
17343 else if (unit[0] == 'c' && unit[1] == 'm')
17344 pixels = 2.54;
17345 else
17346 pixels = 0;
17347 if (pixels > 0)
17348 {
17349 double ppi;
17350 if ((ppi = NUMVAL (Vdisplay_pixels_per_inch), ppi > 0)
17351 || (CONSP (Vdisplay_pixels_per_inch)
17352 && (ppi = (width_p
17353 ? NUMVAL (XCAR (Vdisplay_pixels_per_inch))
17354 : NUMVAL (XCDR (Vdisplay_pixels_per_inch))),
17355 ppi > 0)))
17356 return OK_PIXELS (ppi / pixels);
17357
17358 return 0;
17359 }
17360 }
17361
17362 #ifdef HAVE_WINDOW_SYSTEM
17363 if (EQ (prop, Qheight))
17364 return OK_PIXELS (font ? FONT_HEIGHT ((XFontStruct *)font) : FRAME_LINE_HEIGHT (it->f));
17365 if (EQ (prop, Qwidth))
17366 return OK_PIXELS (font ? FONT_WIDTH ((XFontStruct *)font) : FRAME_COLUMN_WIDTH (it->f));
17367 #else
17368 if (EQ (prop, Qheight) || EQ (prop, Qwidth))
17369 return OK_PIXELS (1);
17370 #endif
17371
17372 if (EQ (prop, Qtext))
17373 return OK_PIXELS (width_p
17374 ? window_box_width (it->w, TEXT_AREA)
17375 : WINDOW_BOX_HEIGHT_NO_MODE_LINE (it->w));
17376
17377 if (align_to && *align_to < 0)
17378 {
17379 *res = 0;
17380 if (EQ (prop, Qleft))
17381 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA));
17382 if (EQ (prop, Qright))
17383 return OK_ALIGN_TO (window_box_right_offset (it->w, TEXT_AREA));
17384 if (EQ (prop, Qcenter))
17385 return OK_ALIGN_TO (window_box_left_offset (it->w, TEXT_AREA)
17386 + window_box_width (it->w, TEXT_AREA) / 2);
17387 if (EQ (prop, Qleft_fringe))
17388 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17389 ? WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (it->w)
17390 : window_box_right_offset (it->w, LEFT_MARGIN_AREA));
17391 if (EQ (prop, Qright_fringe))
17392 return OK_ALIGN_TO (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17393 ? window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17394 : window_box_right_offset (it->w, TEXT_AREA));
17395 if (EQ (prop, Qleft_margin))
17396 return OK_ALIGN_TO (window_box_left_offset (it->w, LEFT_MARGIN_AREA));
17397 if (EQ (prop, Qright_margin))
17398 return OK_ALIGN_TO (window_box_left_offset (it->w, RIGHT_MARGIN_AREA));
17399 if (EQ (prop, Qscroll_bar))
17400 return OK_ALIGN_TO (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (it->w)
17401 ? 0
17402 : (window_box_right_offset (it->w, RIGHT_MARGIN_AREA)
17403 + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (it->w)
17404 ? WINDOW_RIGHT_FRINGE_WIDTH (it->w)
17405 : 0)));
17406 }
17407 else
17408 {
17409 if (EQ (prop, Qleft_fringe))
17410 return OK_PIXELS (WINDOW_LEFT_FRINGE_WIDTH (it->w));
17411 if (EQ (prop, Qright_fringe))
17412 return OK_PIXELS (WINDOW_RIGHT_FRINGE_WIDTH (it->w));
17413 if (EQ (prop, Qleft_margin))
17414 return OK_PIXELS (WINDOW_LEFT_MARGIN_WIDTH (it->w));
17415 if (EQ (prop, Qright_margin))
17416 return OK_PIXELS (WINDOW_RIGHT_MARGIN_WIDTH (it->w));
17417 if (EQ (prop, Qscroll_bar))
17418 return OK_PIXELS (WINDOW_SCROLL_BAR_AREA_WIDTH (it->w));
17419 }
17420
17421 prop = Fbuffer_local_value (prop, it->w->buffer);
17422 }
17423
17424 if (INTEGERP (prop) || FLOATP (prop))
17425 {
17426 int base_unit = (width_p
17427 ? FRAME_COLUMN_WIDTH (it->f)
17428 : FRAME_LINE_HEIGHT (it->f));
17429 return OK_PIXELS (XFLOATINT (prop) * base_unit);
17430 }
17431
17432 if (CONSP (prop))
17433 {
17434 Lisp_Object car = XCAR (prop);
17435 Lisp_Object cdr = XCDR (prop);
17436
17437 if (SYMBOLP (car))
17438 {
17439 #ifdef HAVE_WINDOW_SYSTEM
17440 if (valid_image_p (prop))
17441 {
17442 int id = lookup_image (it->f, prop);
17443 struct image *img = IMAGE_FROM_ID (it->f, id);
17444
17445 return OK_PIXELS (width_p ? img->width : img->height);
17446 }
17447 #endif
17448 if (EQ (car, Qplus) || EQ (car, Qminus))
17449 {
17450 int first = 1;
17451 double px;
17452
17453 pixels = 0;
17454 while (CONSP (cdr))
17455 {
17456 if (!calc_pixel_width_or_height (&px, it, XCAR (cdr),
17457 font, width_p, align_to))
17458 return 0;
17459 if (first)
17460 pixels = (EQ (car, Qplus) ? px : -px), first = 0;
17461 else
17462 pixels += px;
17463 cdr = XCDR (cdr);
17464 }
17465 if (EQ (car, Qminus))
17466 pixels = -pixels;
17467 return OK_PIXELS (pixels);
17468 }
17469
17470 car = Fbuffer_local_value (car, it->w->buffer);
17471 }
17472
17473 if (INTEGERP (car) || FLOATP (car))
17474 {
17475 double fact;
17476 pixels = XFLOATINT (car);
17477 if (NILP (cdr))
17478 return OK_PIXELS (pixels);
17479 if (calc_pixel_width_or_height (&fact, it, cdr,
17480 font, width_p, align_to))
17481 return OK_PIXELS (pixels * fact);
17482 return 0;
17483 }
17484
17485 return 0;
17486 }
17487
17488 return 0;
17489 }
17490
17491 \f
17492 /***********************************************************************
17493 Glyph Display
17494 ***********************************************************************/
17495
17496 #ifdef HAVE_WINDOW_SYSTEM
17497
17498 #if GLYPH_DEBUG
17499
17500 void
17501 dump_glyph_string (s)
17502 struct glyph_string *s;
17503 {
17504 fprintf (stderr, "glyph string\n");
17505 fprintf (stderr, " x, y, w, h = %d, %d, %d, %d\n",
17506 s->x, s->y, s->width, s->height);
17507 fprintf (stderr, " ybase = %d\n", s->ybase);
17508 fprintf (stderr, " hl = %d\n", s->hl);
17509 fprintf (stderr, " left overhang = %d, right = %d\n",
17510 s->left_overhang, s->right_overhang);
17511 fprintf (stderr, " nchars = %d\n", s->nchars);
17512 fprintf (stderr, " extends to end of line = %d\n",
17513 s->extends_to_end_of_line_p);
17514 fprintf (stderr, " font height = %d\n", FONT_HEIGHT (s->font));
17515 fprintf (stderr, " bg width = %d\n", s->background_width);
17516 }
17517
17518 #endif /* GLYPH_DEBUG */
17519
17520 /* Initialize glyph string S. CHAR2B is a suitably allocated vector
17521 of XChar2b structures for S; it can't be allocated in
17522 init_glyph_string because it must be allocated via `alloca'. W
17523 is the window on which S is drawn. ROW and AREA are the glyph row
17524 and area within the row from which S is constructed. START is the
17525 index of the first glyph structure covered by S. HL is a
17526 face-override for drawing S. */
17527
17528 #ifdef HAVE_NTGUI
17529 #define OPTIONAL_HDC(hdc) hdc,
17530 #define DECLARE_HDC(hdc) HDC hdc;
17531 #define ALLOCATE_HDC(hdc, f) hdc = get_frame_dc ((f))
17532 #define RELEASE_HDC(hdc, f) release_frame_dc ((f), (hdc))
17533 #endif
17534
17535 #ifndef OPTIONAL_HDC
17536 #define OPTIONAL_HDC(hdc)
17537 #define DECLARE_HDC(hdc)
17538 #define ALLOCATE_HDC(hdc, f)
17539 #define RELEASE_HDC(hdc, f)
17540 #endif
17541
17542 static void
17543 init_glyph_string (s, OPTIONAL_HDC (hdc) char2b, w, row, area, start, hl)
17544 struct glyph_string *s;
17545 DECLARE_HDC (hdc)
17546 XChar2b *char2b;
17547 struct window *w;
17548 struct glyph_row *row;
17549 enum glyph_row_area area;
17550 int start;
17551 enum draw_glyphs_face hl;
17552 {
17553 bzero (s, sizeof *s);
17554 s->w = w;
17555 s->f = XFRAME (w->frame);
17556 #ifdef HAVE_NTGUI
17557 s->hdc = hdc;
17558 #endif
17559 s->display = FRAME_X_DISPLAY (s->f);
17560 s->window = FRAME_X_WINDOW (s->f);
17561 s->char2b = char2b;
17562 s->hl = hl;
17563 s->row = row;
17564 s->area = area;
17565 s->first_glyph = row->glyphs[area] + start;
17566 s->height = row->height;
17567 s->y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
17568
17569 /* Display the internal border below the tool-bar window. */
17570 if (WINDOWP (s->f->tool_bar_window)
17571 && s->w == XWINDOW (s->f->tool_bar_window))
17572 s->y -= FRAME_INTERNAL_BORDER_WIDTH (s->f);
17573
17574 s->ybase = s->y + row->ascent;
17575 }
17576
17577
17578 /* Append the list of glyph strings with head H and tail T to the list
17579 with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the result. */
17580
17581 static INLINE void
17582 append_glyph_string_lists (head, tail, h, t)
17583 struct glyph_string **head, **tail;
17584 struct glyph_string *h, *t;
17585 {
17586 if (h)
17587 {
17588 if (*head)
17589 (*tail)->next = h;
17590 else
17591 *head = h;
17592 h->prev = *tail;
17593 *tail = t;
17594 }
17595 }
17596
17597
17598 /* Prepend the list of glyph strings with head H and tail T to the
17599 list with head *HEAD and tail *TAIL. Set *HEAD and *TAIL to the
17600 result. */
17601
17602 static INLINE void
17603 prepend_glyph_string_lists (head, tail, h, t)
17604 struct glyph_string **head, **tail;
17605 struct glyph_string *h, *t;
17606 {
17607 if (h)
17608 {
17609 if (*head)
17610 (*head)->prev = t;
17611 else
17612 *tail = t;
17613 t->next = *head;
17614 *head = h;
17615 }
17616 }
17617
17618
17619 /* Append glyph string S to the list with head *HEAD and tail *TAIL.
17620 Set *HEAD and *TAIL to the resulting list. */
17621
17622 static INLINE void
17623 append_glyph_string (head, tail, s)
17624 struct glyph_string **head, **tail;
17625 struct glyph_string *s;
17626 {
17627 s->next = s->prev = NULL;
17628 append_glyph_string_lists (head, tail, s, s);
17629 }
17630
17631
17632 /* Get face and two-byte form of character glyph GLYPH on frame F.
17633 The encoding of GLYPH->u.ch is returned in *CHAR2B. Value is
17634 a pointer to a realized face that is ready for display. */
17635
17636 static INLINE struct face *
17637 get_glyph_face_and_encoding (f, glyph, char2b, two_byte_p)
17638 struct frame *f;
17639 struct glyph *glyph;
17640 XChar2b *char2b;
17641 int *two_byte_p;
17642 {
17643 struct face *face;
17644
17645 xassert (glyph->type == CHAR_GLYPH);
17646 face = FACE_FROM_ID (f, glyph->face_id);
17647
17648 if (two_byte_p)
17649 *two_byte_p = 0;
17650
17651 if (!glyph->multibyte_p)
17652 {
17653 /* Unibyte case. We don't have to encode, but we have to make
17654 sure to use a face suitable for unibyte. */
17655 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17656 }
17657 else if (glyph->u.ch < 128
17658 && glyph->face_id < BASIC_FACE_ID_SENTINEL)
17659 {
17660 /* Case of ASCII in a face known to fit ASCII. */
17661 STORE_XCHAR2B (char2b, 0, glyph->u.ch);
17662 }
17663 else
17664 {
17665 int c1, c2, charset;
17666
17667 /* Split characters into bytes. If c2 is -1 afterwards, C is
17668 really a one-byte character so that byte1 is zero. */
17669 SPLIT_CHAR (glyph->u.ch, charset, c1, c2);
17670 if (c2 > 0)
17671 STORE_XCHAR2B (char2b, c1, c2);
17672 else
17673 STORE_XCHAR2B (char2b, 0, c1);
17674
17675 /* Maybe encode the character in *CHAR2B. */
17676 if (charset != CHARSET_ASCII)
17677 {
17678 struct font_info *font_info
17679 = FONT_INFO_FROM_ID (f, face->font_info_id);
17680 if (font_info)
17681 glyph->font_type
17682 = rif->encode_char (glyph->u.ch, char2b, font_info, two_byte_p);
17683 }
17684 }
17685
17686 /* Make sure X resources of the face are allocated. */
17687 xassert (face != NULL);
17688 PREPARE_FACE_FOR_DISPLAY (f, face);
17689 return face;
17690 }
17691
17692
17693 /* Fill glyph string S with composition components specified by S->cmp.
17694
17695 FACES is an array of faces for all components of this composition.
17696 S->gidx is the index of the first component for S.
17697 OVERLAPS_P non-zero means S should draw the foreground only, and
17698 use its physical height for clipping.
17699
17700 Value is the index of a component not in S. */
17701
17702 static int
17703 fill_composite_glyph_string (s, faces, overlaps_p)
17704 struct glyph_string *s;
17705 struct face **faces;
17706 int overlaps_p;
17707 {
17708 int i;
17709
17710 xassert (s);
17711
17712 s->for_overlaps_p = overlaps_p;
17713
17714 s->face = faces[s->gidx];
17715 s->font = s->face->font;
17716 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17717
17718 /* For all glyphs of this composition, starting at the offset
17719 S->gidx, until we reach the end of the definition or encounter a
17720 glyph that requires the different face, add it to S. */
17721 ++s->nchars;
17722 for (i = s->gidx + 1; i < s->cmp->glyph_len && faces[i] == s->face; ++i)
17723 ++s->nchars;
17724
17725 /* All glyph strings for the same composition has the same width,
17726 i.e. the width set for the first component of the composition. */
17727
17728 s->width = s->first_glyph->pixel_width;
17729
17730 /* If the specified font could not be loaded, use the frame's
17731 default font, but record the fact that we couldn't load it in
17732 the glyph string so that we can draw rectangles for the
17733 characters of the glyph string. */
17734 if (s->font == NULL)
17735 {
17736 s->font_not_found_p = 1;
17737 s->font = FRAME_FONT (s->f);
17738 }
17739
17740 /* Adjust base line for subscript/superscript text. */
17741 s->ybase += s->first_glyph->voffset;
17742
17743 xassert (s->face && s->face->gc);
17744
17745 /* This glyph string must always be drawn with 16-bit functions. */
17746 s->two_byte_p = 1;
17747
17748 return s->gidx + s->nchars;
17749 }
17750
17751
17752 /* Fill glyph string S from a sequence of character glyphs.
17753
17754 FACE_ID is the face id of the string. START is the index of the
17755 first glyph to consider, END is the index of the last + 1.
17756 OVERLAPS_P non-zero means S should draw the foreground only, and
17757 use its physical height for clipping.
17758
17759 Value is the index of the first glyph not in S. */
17760
17761 static int
17762 fill_glyph_string (s, face_id, start, end, overlaps_p)
17763 struct glyph_string *s;
17764 int face_id;
17765 int start, end, overlaps_p;
17766 {
17767 struct glyph *glyph, *last;
17768 int voffset;
17769 int glyph_not_available_p;
17770
17771 xassert (s->f == XFRAME (s->w->frame));
17772 xassert (s->nchars == 0);
17773 xassert (start >= 0 && end > start);
17774
17775 s->for_overlaps_p = overlaps_p,
17776 glyph = s->row->glyphs[s->area] + start;
17777 last = s->row->glyphs[s->area] + end;
17778 voffset = glyph->voffset;
17779
17780 glyph_not_available_p = glyph->glyph_not_available_p;
17781
17782 while (glyph < last
17783 && glyph->type == CHAR_GLYPH
17784 && glyph->voffset == voffset
17785 /* Same face id implies same font, nowadays. */
17786 && glyph->face_id == face_id
17787 && glyph->glyph_not_available_p == glyph_not_available_p)
17788 {
17789 int two_byte_p;
17790
17791 s->face = get_glyph_face_and_encoding (s->f, glyph,
17792 s->char2b + s->nchars,
17793 &two_byte_p);
17794 s->two_byte_p = two_byte_p;
17795 ++s->nchars;
17796 xassert (s->nchars <= end - start);
17797 s->width += glyph->pixel_width;
17798 ++glyph;
17799 }
17800
17801 s->font = s->face->font;
17802 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17803
17804 /* If the specified font could not be loaded, use the frame's font,
17805 but record the fact that we couldn't load it in
17806 S->font_not_found_p so that we can draw rectangles for the
17807 characters of the glyph string. */
17808 if (s->font == NULL || glyph_not_available_p)
17809 {
17810 s->font_not_found_p = 1;
17811 s->font = FRAME_FONT (s->f);
17812 }
17813
17814 /* Adjust base line for subscript/superscript text. */
17815 s->ybase += voffset;
17816
17817 xassert (s->face && s->face->gc);
17818 return glyph - s->row->glyphs[s->area];
17819 }
17820
17821
17822 /* Fill glyph string S from image glyph S->first_glyph. */
17823
17824 static void
17825 fill_image_glyph_string (s)
17826 struct glyph_string *s;
17827 {
17828 xassert (s->first_glyph->type == IMAGE_GLYPH);
17829 s->img = IMAGE_FROM_ID (s->f, s->first_glyph->u.img_id);
17830 xassert (s->img);
17831 s->slice = s->first_glyph->slice;
17832 s->face = FACE_FROM_ID (s->f, s->first_glyph->face_id);
17833 s->font = s->face->font;
17834 s->width = s->first_glyph->pixel_width;
17835
17836 /* Adjust base line for subscript/superscript text. */
17837 s->ybase += s->first_glyph->voffset;
17838 }
17839
17840
17841 /* Fill glyph string S from a sequence of stretch glyphs.
17842
17843 ROW is the glyph row in which the glyphs are found, AREA is the
17844 area within the row. START is the index of the first glyph to
17845 consider, END is the index of the last + 1.
17846
17847 Value is the index of the first glyph not in S. */
17848
17849 static int
17850 fill_stretch_glyph_string (s, row, area, start, end)
17851 struct glyph_string *s;
17852 struct glyph_row *row;
17853 enum glyph_row_area area;
17854 int start, end;
17855 {
17856 struct glyph *glyph, *last;
17857 int voffset, face_id;
17858
17859 xassert (s->first_glyph->type == STRETCH_GLYPH);
17860
17861 glyph = s->row->glyphs[s->area] + start;
17862 last = s->row->glyphs[s->area] + end;
17863 face_id = glyph->face_id;
17864 s->face = FACE_FROM_ID (s->f, face_id);
17865 s->font = s->face->font;
17866 s->font_info = FONT_INFO_FROM_ID (s->f, s->face->font_info_id);
17867 s->width = glyph->pixel_width;
17868 voffset = glyph->voffset;
17869
17870 for (++glyph;
17871 (glyph < last
17872 && glyph->type == STRETCH_GLYPH
17873 && glyph->voffset == voffset
17874 && glyph->face_id == face_id);
17875 ++glyph)
17876 s->width += glyph->pixel_width;
17877
17878 /* Adjust base line for subscript/superscript text. */
17879 s->ybase += voffset;
17880
17881 /* The case that face->gc == 0 is handled when drawing the glyph
17882 string by calling PREPARE_FACE_FOR_DISPLAY. */
17883 xassert (s->face);
17884 return glyph - s->row->glyphs[s->area];
17885 }
17886
17887
17888 /* EXPORT for RIF:
17889 Set *LEFT and *RIGHT to the left and right overhang of GLYPH on
17890 frame F. Overhangs of glyphs other than type CHAR_GLYPH are
17891 assumed to be zero. */
17892
17893 void
17894 x_get_glyph_overhangs (glyph, f, left, right)
17895 struct glyph *glyph;
17896 struct frame *f;
17897 int *left, *right;
17898 {
17899 *left = *right = 0;
17900
17901 if (glyph->type == CHAR_GLYPH)
17902 {
17903 XFontStruct *font;
17904 struct face *face;
17905 struct font_info *font_info;
17906 XChar2b char2b;
17907 XCharStruct *pcm;
17908
17909 face = get_glyph_face_and_encoding (f, glyph, &char2b, NULL);
17910 font = face->font;
17911 font_info = FONT_INFO_FROM_ID (f, face->font_info_id);
17912 if (font /* ++KFS: Should this be font_info ? */
17913 && (pcm = rif->per_char_metric (font, &char2b, glyph->font_type)))
17914 {
17915 if (pcm->rbearing > pcm->width)
17916 *right = pcm->rbearing - pcm->width;
17917 if (pcm->lbearing < 0)
17918 *left = -pcm->lbearing;
17919 }
17920 }
17921 }
17922
17923
17924 /* Return the index of the first glyph preceding glyph string S that
17925 is overwritten by S because of S's left overhang. Value is -1
17926 if no glyphs are overwritten. */
17927
17928 static int
17929 left_overwritten (s)
17930 struct glyph_string *s;
17931 {
17932 int k;
17933
17934 if (s->left_overhang)
17935 {
17936 int x = 0, i;
17937 struct glyph *glyphs = s->row->glyphs[s->area];
17938 int first = s->first_glyph - glyphs;
17939
17940 for (i = first - 1; i >= 0 && x > -s->left_overhang; --i)
17941 x -= glyphs[i].pixel_width;
17942
17943 k = i + 1;
17944 }
17945 else
17946 k = -1;
17947
17948 return k;
17949 }
17950
17951
17952 /* Return the index of the first glyph preceding glyph string S that
17953 is overwriting S because of its right overhang. Value is -1 if no
17954 glyph in front of S overwrites S. */
17955
17956 static int
17957 left_overwriting (s)
17958 struct glyph_string *s;
17959 {
17960 int i, k, x;
17961 struct glyph *glyphs = s->row->glyphs[s->area];
17962 int first = s->first_glyph - glyphs;
17963
17964 k = -1;
17965 x = 0;
17966 for (i = first - 1; i >= 0; --i)
17967 {
17968 int left, right;
17969 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
17970 if (x + right > 0)
17971 k = i;
17972 x -= glyphs[i].pixel_width;
17973 }
17974
17975 return k;
17976 }
17977
17978
17979 /* Return the index of the last glyph following glyph string S that is
17980 not overwritten by S because of S's right overhang. Value is -1 if
17981 no such glyph is found. */
17982
17983 static int
17984 right_overwritten (s)
17985 struct glyph_string *s;
17986 {
17987 int k = -1;
17988
17989 if (s->right_overhang)
17990 {
17991 int x = 0, i;
17992 struct glyph *glyphs = s->row->glyphs[s->area];
17993 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
17994 int end = s->row->used[s->area];
17995
17996 for (i = first; i < end && s->right_overhang > x; ++i)
17997 x += glyphs[i].pixel_width;
17998
17999 k = i;
18000 }
18001
18002 return k;
18003 }
18004
18005
18006 /* Return the index of the last glyph following glyph string S that
18007 overwrites S because of its left overhang. Value is negative
18008 if no such glyph is found. */
18009
18010 static int
18011 right_overwriting (s)
18012 struct glyph_string *s;
18013 {
18014 int i, k, x;
18015 int end = s->row->used[s->area];
18016 struct glyph *glyphs = s->row->glyphs[s->area];
18017 int first = (s->first_glyph - glyphs) + (s->cmp ? 1 : s->nchars);
18018
18019 k = -1;
18020 x = 0;
18021 for (i = first; i < end; ++i)
18022 {
18023 int left, right;
18024 x_get_glyph_overhangs (glyphs + i, s->f, &left, &right);
18025 if (x - left < 0)
18026 k = i;
18027 x += glyphs[i].pixel_width;
18028 }
18029
18030 return k;
18031 }
18032
18033
18034 /* Get face and two-byte form of character C in face FACE_ID on frame
18035 F. The encoding of C is returned in *CHAR2B. MULTIBYTE_P non-zero
18036 means we want to display multibyte text. DISPLAY_P non-zero means
18037 make sure that X resources for the face returned are allocated.
18038 Value is a pointer to a realized face that is ready for display if
18039 DISPLAY_P is non-zero. */
18040
18041 static INLINE struct face *
18042 get_char_face_and_encoding (f, c, face_id, char2b, multibyte_p, display_p)
18043 struct frame *f;
18044 int c, face_id;
18045 XChar2b *char2b;
18046 int multibyte_p, display_p;
18047 {
18048 struct face *face = FACE_FROM_ID (f, face_id);
18049
18050 if (!multibyte_p)
18051 {
18052 /* Unibyte case. We don't have to encode, but we have to make
18053 sure to use a face suitable for unibyte. */
18054 STORE_XCHAR2B (char2b, 0, c);
18055 face_id = FACE_FOR_CHAR (f, face, c);
18056 face = FACE_FROM_ID (f, face_id);
18057 }
18058 else if (c < 128 && face_id < BASIC_FACE_ID_SENTINEL)
18059 {
18060 /* Case of ASCII in a face known to fit ASCII. */
18061 STORE_XCHAR2B (char2b, 0, c);
18062 }
18063 else
18064 {
18065 int c1, c2, charset;
18066
18067 /* Split characters into bytes. If c2 is -1 afterwards, C is
18068 really a one-byte character so that byte1 is zero. */
18069 SPLIT_CHAR (c, charset, c1, c2);
18070 if (c2 > 0)
18071 STORE_XCHAR2B (char2b, c1, c2);
18072 else
18073 STORE_XCHAR2B (char2b, 0, c1);
18074
18075 /* Maybe encode the character in *CHAR2B. */
18076 if (face->font != NULL)
18077 {
18078 struct font_info *font_info
18079 = FONT_INFO_FROM_ID (f, face->font_info_id);
18080 if (font_info)
18081 rif->encode_char (c, char2b, font_info, 0);
18082 }
18083 }
18084
18085 /* Make sure X resources of the face are allocated. */
18086 #ifdef HAVE_X_WINDOWS
18087 if (display_p)
18088 #endif
18089 {
18090 xassert (face != NULL);
18091 PREPARE_FACE_FOR_DISPLAY (f, face);
18092 }
18093
18094 return face;
18095 }
18096
18097
18098 /* Set background width of glyph string S. START is the index of the
18099 first glyph following S. LAST_X is the right-most x-position + 1
18100 in the drawing area. */
18101
18102 static INLINE void
18103 set_glyph_string_background_width (s, start, last_x)
18104 struct glyph_string *s;
18105 int start;
18106 int last_x;
18107 {
18108 /* If the face of this glyph string has to be drawn to the end of
18109 the drawing area, set S->extends_to_end_of_line_p. */
18110 struct face *default_face = FACE_FROM_ID (s->f, DEFAULT_FACE_ID);
18111
18112 if (start == s->row->used[s->area]
18113 && s->area == TEXT_AREA
18114 && ((s->hl == DRAW_NORMAL_TEXT
18115 && (s->row->fill_line_p
18116 || s->face->background != default_face->background
18117 || s->face->stipple != default_face->stipple
18118 || s->row->mouse_face_p))
18119 || s->hl == DRAW_MOUSE_FACE
18120 || ((s->hl == DRAW_IMAGE_RAISED || s->hl == DRAW_IMAGE_SUNKEN)
18121 && s->row->fill_line_p)))
18122 s->extends_to_end_of_line_p = 1;
18123
18124 /* If S extends its face to the end of the line, set its
18125 background_width to the distance to the right edge of the drawing
18126 area. */
18127 if (s->extends_to_end_of_line_p)
18128 s->background_width = last_x - s->x + 1;
18129 else
18130 s->background_width = s->width;
18131 }
18132
18133
18134 /* Compute overhangs and x-positions for glyph string S and its
18135 predecessors, or successors. X is the starting x-position for S.
18136 BACKWARD_P non-zero means process predecessors. */
18137
18138 static void
18139 compute_overhangs_and_x (s, x, backward_p)
18140 struct glyph_string *s;
18141 int x;
18142 int backward_p;
18143 {
18144 if (backward_p)
18145 {
18146 while (s)
18147 {
18148 if (rif->compute_glyph_string_overhangs)
18149 rif->compute_glyph_string_overhangs (s);
18150 x -= s->width;
18151 s->x = x;
18152 s = s->prev;
18153 }
18154 }
18155 else
18156 {
18157 while (s)
18158 {
18159 if (rif->compute_glyph_string_overhangs)
18160 rif->compute_glyph_string_overhangs (s);
18161 s->x = x;
18162 x += s->width;
18163 s = s->next;
18164 }
18165 }
18166 }
18167
18168
18169
18170 /* The following macros are only called from draw_glyphs below.
18171 They reference the following parameters of that function directly:
18172 `w', `row', `area', and `overlap_p'
18173 as well as the following local variables:
18174 `s', `f', and `hdc' (in W32) */
18175
18176 #ifdef HAVE_NTGUI
18177 /* On W32, silently add local `hdc' variable to argument list of
18178 init_glyph_string. */
18179 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18180 init_glyph_string (s, hdc, char2b, w, row, area, start, hl)
18181 #else
18182 #define INIT_GLYPH_STRING(s, char2b, w, row, area, start, hl) \
18183 init_glyph_string (s, char2b, w, row, area, start, hl)
18184 #endif
18185
18186 /* Add a glyph string for a stretch glyph to the list of strings
18187 between HEAD and TAIL. START is the index of the stretch glyph in
18188 row area AREA of glyph row ROW. END is the index of the last glyph
18189 in that glyph row area. X is the current output position assigned
18190 to the new glyph string constructed. HL overrides that face of the
18191 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18192 is the right-most x-position of the drawing area. */
18193
18194 /* SunOS 4 bundled cc, barfed on continuations in the arg lists here
18195 and below -- keep them on one line. */
18196 #define BUILD_STRETCH_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18197 do \
18198 { \
18199 s = (struct glyph_string *) alloca (sizeof *s); \
18200 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18201 START = fill_stretch_glyph_string (s, row, area, START, END); \
18202 append_glyph_string (&HEAD, &TAIL, s); \
18203 s->x = (X); \
18204 } \
18205 while (0)
18206
18207
18208 /* Add a glyph string for an image glyph to the list of strings
18209 between HEAD and TAIL. START is the index of the image glyph in
18210 row area AREA of glyph row ROW. END is the index of the last glyph
18211 in that glyph row area. X is the current output position assigned
18212 to the new glyph string constructed. HL overrides that face of the
18213 glyph; e.g. it is DRAW_CURSOR if a cursor has to be drawn. LAST_X
18214 is the right-most x-position of the drawing area. */
18215
18216 #define BUILD_IMAGE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18217 do \
18218 { \
18219 s = (struct glyph_string *) alloca (sizeof *s); \
18220 INIT_GLYPH_STRING (s, NULL, w, row, area, START, HL); \
18221 fill_image_glyph_string (s); \
18222 append_glyph_string (&HEAD, &TAIL, s); \
18223 ++START; \
18224 s->x = (X); \
18225 } \
18226 while (0)
18227
18228
18229 /* Add a glyph string for a sequence of character glyphs to the list
18230 of strings between HEAD and TAIL. START is the index of the first
18231 glyph in row area AREA of glyph row ROW that is part of the new
18232 glyph string. END is the index of the last glyph in that glyph row
18233 area. X is the current output position assigned to the new glyph
18234 string constructed. HL overrides that face of the glyph; e.g. it
18235 is DRAW_CURSOR if a cursor has to be drawn. LAST_X is the
18236 right-most x-position of the drawing area. */
18237
18238 #define BUILD_CHAR_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18239 do \
18240 { \
18241 int c, face_id; \
18242 XChar2b *char2b; \
18243 \
18244 c = (row)->glyphs[area][START].u.ch; \
18245 face_id = (row)->glyphs[area][START].face_id; \
18246 \
18247 s = (struct glyph_string *) alloca (sizeof *s); \
18248 char2b = (XChar2b *) alloca ((END - START) * sizeof *char2b); \
18249 INIT_GLYPH_STRING (s, char2b, w, row, area, START, HL); \
18250 append_glyph_string (&HEAD, &TAIL, s); \
18251 s->x = (X); \
18252 START = fill_glyph_string (s, face_id, START, END, overlaps_p); \
18253 } \
18254 while (0)
18255
18256
18257 /* Add a glyph string for a composite sequence to the list of strings
18258 between HEAD and TAIL. START is the index of the first glyph in
18259 row area AREA of glyph row ROW that is part of the new glyph
18260 string. END is the index of the last glyph in that glyph row area.
18261 X is the current output position assigned to the new glyph string
18262 constructed. HL overrides that face of the glyph; e.g. it is
18263 DRAW_CURSOR if a cursor has to be drawn. LAST_X is the right-most
18264 x-position of the drawing area. */
18265
18266 #define BUILD_COMPOSITE_GLYPH_STRING(START, END, HEAD, TAIL, HL, X, LAST_X) \
18267 do { \
18268 int cmp_id = (row)->glyphs[area][START].u.cmp_id; \
18269 int face_id = (row)->glyphs[area][START].face_id; \
18270 struct face *base_face = FACE_FROM_ID (f, face_id); \
18271 struct composition *cmp = composition_table[cmp_id]; \
18272 int glyph_len = cmp->glyph_len; \
18273 XChar2b *char2b; \
18274 struct face **faces; \
18275 struct glyph_string *first_s = NULL; \
18276 int n; \
18277 \
18278 base_face = base_face->ascii_face; \
18279 char2b = (XChar2b *) alloca ((sizeof *char2b) * glyph_len); \
18280 faces = (struct face **) alloca ((sizeof *faces) * glyph_len); \
18281 /* At first, fill in `char2b' and `faces'. */ \
18282 for (n = 0; n < glyph_len; n++) \
18283 { \
18284 int c = COMPOSITION_GLYPH (cmp, n); \
18285 int this_face_id = FACE_FOR_CHAR (f, base_face, c); \
18286 faces[n] = FACE_FROM_ID (f, this_face_id); \
18287 get_char_face_and_encoding (f, c, this_face_id, \
18288 char2b + n, 1, 1); \
18289 } \
18290 \
18291 /* Make glyph_strings for each glyph sequence that is drawable by \
18292 the same face, and append them to HEAD/TAIL. */ \
18293 for (n = 0; n < cmp->glyph_len;) \
18294 { \
18295 s = (struct glyph_string *) alloca (sizeof *s); \
18296 INIT_GLYPH_STRING (s, char2b + n, w, row, area, START, HL); \
18297 append_glyph_string (&(HEAD), &(TAIL), s); \
18298 s->cmp = cmp; \
18299 s->gidx = n; \
18300 s->x = (X); \
18301 \
18302 if (n == 0) \
18303 first_s = s; \
18304 \
18305 n = fill_composite_glyph_string (s, faces, overlaps_p); \
18306 } \
18307 \
18308 ++START; \
18309 s = first_s; \
18310 } while (0)
18311
18312
18313 /* Build a list of glyph strings between HEAD and TAIL for the glyphs
18314 of AREA of glyph row ROW on window W between indices START and END.
18315 HL overrides the face for drawing glyph strings, e.g. it is
18316 DRAW_CURSOR to draw a cursor. X and LAST_X are start and end
18317 x-positions of the drawing area.
18318
18319 This is an ugly monster macro construct because we must use alloca
18320 to allocate glyph strings (because draw_glyphs can be called
18321 asynchronously). */
18322
18323 #define BUILD_GLYPH_STRINGS(START, END, HEAD, TAIL, HL, X, LAST_X) \
18324 do \
18325 { \
18326 HEAD = TAIL = NULL; \
18327 while (START < END) \
18328 { \
18329 struct glyph *first_glyph = (row)->glyphs[area] + START; \
18330 switch (first_glyph->type) \
18331 { \
18332 case CHAR_GLYPH: \
18333 BUILD_CHAR_GLYPH_STRINGS (START, END, HEAD, TAIL, \
18334 HL, X, LAST_X); \
18335 break; \
18336 \
18337 case COMPOSITE_GLYPH: \
18338 BUILD_COMPOSITE_GLYPH_STRING (START, END, HEAD, TAIL, \
18339 HL, X, LAST_X); \
18340 break; \
18341 \
18342 case STRETCH_GLYPH: \
18343 BUILD_STRETCH_GLYPH_STRING (START, END, HEAD, TAIL, \
18344 HL, X, LAST_X); \
18345 break; \
18346 \
18347 case IMAGE_GLYPH: \
18348 BUILD_IMAGE_GLYPH_STRING (START, END, HEAD, TAIL, \
18349 HL, X, LAST_X); \
18350 break; \
18351 \
18352 default: \
18353 abort (); \
18354 } \
18355 \
18356 set_glyph_string_background_width (s, START, LAST_X); \
18357 (X) += s->width; \
18358 } \
18359 } \
18360 while (0)
18361
18362
18363 /* Draw glyphs between START and END in AREA of ROW on window W,
18364 starting at x-position X. X is relative to AREA in W. HL is a
18365 face-override with the following meaning:
18366
18367 DRAW_NORMAL_TEXT draw normally
18368 DRAW_CURSOR draw in cursor face
18369 DRAW_MOUSE_FACE draw in mouse face.
18370 DRAW_INVERSE_VIDEO draw in mode line face
18371 DRAW_IMAGE_SUNKEN draw an image with a sunken relief around it
18372 DRAW_IMAGE_RAISED draw an image with a raised relief around it
18373
18374 If OVERLAPS_P is non-zero, draw only the foreground of characters
18375 and clip to the physical height of ROW.
18376
18377 Value is the x-position reached, relative to AREA of W. */
18378
18379 static int
18380 draw_glyphs (w, x, row, area, start, end, hl, overlaps_p)
18381 struct window *w;
18382 int x;
18383 struct glyph_row *row;
18384 enum glyph_row_area area;
18385 int start, end;
18386 enum draw_glyphs_face hl;
18387 int overlaps_p;
18388 {
18389 struct glyph_string *head, *tail;
18390 struct glyph_string *s;
18391 struct glyph_string *clip_head = NULL, *clip_tail = NULL;
18392 int last_x, area_width;
18393 int x_reached;
18394 int i, j;
18395 struct frame *f = XFRAME (WINDOW_FRAME (w));
18396 DECLARE_HDC (hdc);
18397
18398 ALLOCATE_HDC (hdc, f);
18399
18400 /* Let's rather be paranoid than getting a SEGV. */
18401 end = min (end, row->used[area]);
18402 start = max (0, start);
18403 start = min (end, start);
18404
18405 /* Translate X to frame coordinates. Set last_x to the right
18406 end of the drawing area. */
18407 if (row->full_width_p)
18408 {
18409 /* X is relative to the left edge of W, without scroll bars
18410 or fringes. */
18411 x += WINDOW_LEFT_EDGE_X (w);
18412 last_x = WINDOW_LEFT_EDGE_X (w) + WINDOW_TOTAL_WIDTH (w);
18413 }
18414 else
18415 {
18416 int area_left = window_box_left (w, area);
18417 x += area_left;
18418 area_width = window_box_width (w, area);
18419 last_x = area_left + area_width;
18420 }
18421
18422 /* Build a doubly-linked list of glyph_string structures between
18423 head and tail from what we have to draw. Note that the macro
18424 BUILD_GLYPH_STRINGS will modify its start parameter. That's
18425 the reason we use a separate variable `i'. */
18426 i = start;
18427 BUILD_GLYPH_STRINGS (i, end, head, tail, hl, x, last_x);
18428 if (tail)
18429 x_reached = tail->x + tail->background_width;
18430 else
18431 x_reached = x;
18432
18433 /* If there are any glyphs with lbearing < 0 or rbearing > width in
18434 the row, redraw some glyphs in front or following the glyph
18435 strings built above. */
18436 if (head && !overlaps_p && row->contains_overlapping_glyphs_p)
18437 {
18438 int dummy_x = 0;
18439 struct glyph_string *h, *t;
18440
18441 /* Compute overhangs for all glyph strings. */
18442 if (rif->compute_glyph_string_overhangs)
18443 for (s = head; s; s = s->next)
18444 rif->compute_glyph_string_overhangs (s);
18445
18446 /* Prepend glyph strings for glyphs in front of the first glyph
18447 string that are overwritten because of the first glyph
18448 string's left overhang. The background of all strings
18449 prepended must be drawn because the first glyph string
18450 draws over it. */
18451 i = left_overwritten (head);
18452 if (i >= 0)
18453 {
18454 j = i;
18455 BUILD_GLYPH_STRINGS (j, start, h, t,
18456 DRAW_NORMAL_TEXT, dummy_x, last_x);
18457 start = i;
18458 compute_overhangs_and_x (t, head->x, 1);
18459 prepend_glyph_string_lists (&head, &tail, h, t);
18460 clip_head = head;
18461 }
18462
18463 /* Prepend glyph strings for glyphs in front of the first glyph
18464 string that overwrite that glyph string because of their
18465 right overhang. For these strings, only the foreground must
18466 be drawn, because it draws over the glyph string at `head'.
18467 The background must not be drawn because this would overwrite
18468 right overhangs of preceding glyphs for which no glyph
18469 strings exist. */
18470 i = left_overwriting (head);
18471 if (i >= 0)
18472 {
18473 clip_head = head;
18474 BUILD_GLYPH_STRINGS (i, start, h, t,
18475 DRAW_NORMAL_TEXT, dummy_x, last_x);
18476 for (s = h; s; s = s->next)
18477 s->background_filled_p = 1;
18478 compute_overhangs_and_x (t, head->x, 1);
18479 prepend_glyph_string_lists (&head, &tail, h, t);
18480 }
18481
18482 /* Append glyphs strings for glyphs following the last glyph
18483 string tail that are overwritten by tail. The background of
18484 these strings has to be drawn because tail's foreground draws
18485 over it. */
18486 i = right_overwritten (tail);
18487 if (i >= 0)
18488 {
18489 BUILD_GLYPH_STRINGS (end, i, h, t,
18490 DRAW_NORMAL_TEXT, x, last_x);
18491 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18492 append_glyph_string_lists (&head, &tail, h, t);
18493 clip_tail = tail;
18494 }
18495
18496 /* Append glyph strings for glyphs following the last glyph
18497 string tail that overwrite tail. The foreground of such
18498 glyphs has to be drawn because it writes into the background
18499 of tail. The background must not be drawn because it could
18500 paint over the foreground of following glyphs. */
18501 i = right_overwriting (tail);
18502 if (i >= 0)
18503 {
18504 clip_tail = tail;
18505 BUILD_GLYPH_STRINGS (end, i, h, t,
18506 DRAW_NORMAL_TEXT, x, last_x);
18507 for (s = h; s; s = s->next)
18508 s->background_filled_p = 1;
18509 compute_overhangs_and_x (h, tail->x + tail->width, 0);
18510 append_glyph_string_lists (&head, &tail, h, t);
18511 }
18512 if (clip_head || clip_tail)
18513 for (s = head; s; s = s->next)
18514 {
18515 s->clip_head = clip_head;
18516 s->clip_tail = clip_tail;
18517 }
18518 }
18519
18520 /* Draw all strings. */
18521 for (s = head; s; s = s->next)
18522 rif->draw_glyph_string (s);
18523
18524 if (area == TEXT_AREA
18525 && !row->full_width_p
18526 /* When drawing overlapping rows, only the glyph strings'
18527 foreground is drawn, which doesn't erase a cursor
18528 completely. */
18529 && !overlaps_p)
18530 {
18531 int x0 = clip_head ? clip_head->x : (head ? head->x : x);
18532 int x1 = (clip_tail ? clip_tail->x + clip_tail->background_width
18533 : (tail ? tail->x + tail->background_width : x));
18534
18535 int text_left = window_box_left (w, TEXT_AREA);
18536 x0 -= text_left;
18537 x1 -= text_left;
18538
18539 notice_overwritten_cursor (w, TEXT_AREA, x0, x1,
18540 row->y, MATRIX_ROW_BOTTOM_Y (row));
18541 }
18542
18543 /* Value is the x-position up to which drawn, relative to AREA of W.
18544 This doesn't include parts drawn because of overhangs. */
18545 if (row->full_width_p)
18546 x_reached = FRAME_TO_WINDOW_PIXEL_X (w, x_reached);
18547 else
18548 x_reached -= window_box_left (w, area);
18549
18550 RELEASE_HDC (hdc, f);
18551
18552 return x_reached;
18553 }
18554
18555 /* Expand row matrix if too narrow. Don't expand if area
18556 is not present. */
18557
18558 #define IT_EXPAND_MATRIX_WIDTH(it, area) \
18559 { \
18560 if (!fonts_changed_p \
18561 && (it->glyph_row->glyphs[area] \
18562 < it->glyph_row->glyphs[area + 1])) \
18563 { \
18564 it->w->ncols_scale_factor++; \
18565 fonts_changed_p = 1; \
18566 } \
18567 }
18568
18569 /* Store one glyph for IT->char_to_display in IT->glyph_row.
18570 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18571
18572 static INLINE void
18573 append_glyph (it)
18574 struct it *it;
18575 {
18576 struct glyph *glyph;
18577 enum glyph_row_area area = it->area;
18578
18579 xassert (it->glyph_row);
18580 xassert (it->char_to_display != '\n' && it->char_to_display != '\t');
18581
18582 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18583 if (glyph < it->glyph_row->glyphs[area + 1])
18584 {
18585 glyph->charpos = CHARPOS (it->position);
18586 glyph->object = it->object;
18587 glyph->pixel_width = it->pixel_width;
18588 glyph->ascent = it->ascent;
18589 glyph->descent = it->descent;
18590 glyph->voffset = it->voffset;
18591 glyph->type = CHAR_GLYPH;
18592 glyph->multibyte_p = it->multibyte_p;
18593 glyph->left_box_line_p = it->start_of_box_run_p;
18594 glyph->right_box_line_p = it->end_of_box_run_p;
18595 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18596 || it->phys_descent > it->descent);
18597 glyph->padding_p = 0;
18598 glyph->glyph_not_available_p = it->glyph_not_available_p;
18599 glyph->face_id = it->face_id;
18600 glyph->u.ch = it->char_to_display;
18601 glyph->slice = null_glyph_slice;
18602 glyph->font_type = FONT_TYPE_UNKNOWN;
18603 ++it->glyph_row->used[area];
18604 }
18605 else
18606 IT_EXPAND_MATRIX_WIDTH (it, area);
18607 }
18608
18609 /* Store one glyph for the composition IT->cmp_id in IT->glyph_row.
18610 Called from x_produce_glyphs when IT->glyph_row is non-null. */
18611
18612 static INLINE void
18613 append_composite_glyph (it)
18614 struct it *it;
18615 {
18616 struct glyph *glyph;
18617 enum glyph_row_area area = it->area;
18618
18619 xassert (it->glyph_row);
18620
18621 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18622 if (glyph < it->glyph_row->glyphs[area + 1])
18623 {
18624 glyph->charpos = CHARPOS (it->position);
18625 glyph->object = it->object;
18626 glyph->pixel_width = it->pixel_width;
18627 glyph->ascent = it->ascent;
18628 glyph->descent = it->descent;
18629 glyph->voffset = it->voffset;
18630 glyph->type = COMPOSITE_GLYPH;
18631 glyph->multibyte_p = it->multibyte_p;
18632 glyph->left_box_line_p = it->start_of_box_run_p;
18633 glyph->right_box_line_p = it->end_of_box_run_p;
18634 glyph->overlaps_vertically_p = (it->phys_ascent > it->ascent
18635 || it->phys_descent > it->descent);
18636 glyph->padding_p = 0;
18637 glyph->glyph_not_available_p = 0;
18638 glyph->face_id = it->face_id;
18639 glyph->u.cmp_id = it->cmp_id;
18640 glyph->slice = null_glyph_slice;
18641 glyph->font_type = FONT_TYPE_UNKNOWN;
18642 ++it->glyph_row->used[area];
18643 }
18644 else
18645 IT_EXPAND_MATRIX_WIDTH (it, area);
18646 }
18647
18648
18649 /* Change IT->ascent and IT->height according to the setting of
18650 IT->voffset. */
18651
18652 static INLINE void
18653 take_vertical_position_into_account (it)
18654 struct it *it;
18655 {
18656 if (it->voffset)
18657 {
18658 if (it->voffset < 0)
18659 /* Increase the ascent so that we can display the text higher
18660 in the line. */
18661 it->ascent -= it->voffset;
18662 else
18663 /* Increase the descent so that we can display the text lower
18664 in the line. */
18665 it->descent += it->voffset;
18666 }
18667 }
18668
18669
18670 /* Produce glyphs/get display metrics for the image IT is loaded with.
18671 See the description of struct display_iterator in dispextern.h for
18672 an overview of struct display_iterator. */
18673
18674 static void
18675 produce_image_glyph (it)
18676 struct it *it;
18677 {
18678 struct image *img;
18679 struct face *face;
18680 int glyph_ascent;
18681 struct glyph_slice slice;
18682
18683 xassert (it->what == IT_IMAGE);
18684
18685 face = FACE_FROM_ID (it->f, it->face_id);
18686 xassert (face);
18687 /* Make sure X resources of the face is loaded. */
18688 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18689
18690 if (it->image_id < 0)
18691 {
18692 /* Fringe bitmap. */
18693 it->ascent = it->phys_ascent = 0;
18694 it->descent = it->phys_descent = 0;
18695 it->pixel_width = 0;
18696 it->nglyphs = 0;
18697 return;
18698 }
18699
18700 img = IMAGE_FROM_ID (it->f, it->image_id);
18701 xassert (img);
18702 /* Make sure X resources of the image is loaded. */
18703 prepare_image_for_display (it->f, img);
18704
18705 slice.x = slice.y = 0;
18706 slice.width = img->width;
18707 slice.height = img->height;
18708
18709 if (INTEGERP (it->slice.x))
18710 slice.x = XINT (it->slice.x);
18711 else if (FLOATP (it->slice.x))
18712 slice.x = XFLOAT_DATA (it->slice.x) * img->width;
18713
18714 if (INTEGERP (it->slice.y))
18715 slice.y = XINT (it->slice.y);
18716 else if (FLOATP (it->slice.y))
18717 slice.y = XFLOAT_DATA (it->slice.y) * img->height;
18718
18719 if (INTEGERP (it->slice.width))
18720 slice.width = XINT (it->slice.width);
18721 else if (FLOATP (it->slice.width))
18722 slice.width = XFLOAT_DATA (it->slice.width) * img->width;
18723
18724 if (INTEGERP (it->slice.height))
18725 slice.height = XINT (it->slice.height);
18726 else if (FLOATP (it->slice.height))
18727 slice.height = XFLOAT_DATA (it->slice.height) * img->height;
18728
18729 if (slice.x >= img->width)
18730 slice.x = img->width;
18731 if (slice.y >= img->height)
18732 slice.y = img->height;
18733 if (slice.x + slice.width >= img->width)
18734 slice.width = img->width - slice.x;
18735 if (slice.y + slice.height > img->height)
18736 slice.height = img->height - slice.y;
18737
18738 if (slice.width == 0 || slice.height == 0)
18739 return;
18740
18741 it->ascent = it->phys_ascent = glyph_ascent = image_ascent (img, face, &slice);
18742
18743 it->descent = slice.height - glyph_ascent;
18744 if (slice.y == 0)
18745 it->descent += img->vmargin;
18746 if (slice.y + slice.height == img->height)
18747 it->descent += img->vmargin;
18748 it->phys_descent = it->descent;
18749
18750 it->pixel_width = slice.width;
18751 if (slice.x == 0)
18752 it->pixel_width += img->hmargin;
18753 if (slice.x + slice.width == img->width)
18754 it->pixel_width += img->hmargin;
18755
18756 /* It's quite possible for images to have an ascent greater than
18757 their height, so don't get confused in that case. */
18758 if (it->descent < 0)
18759 it->descent = 0;
18760
18761 #if 0 /* this breaks image tiling */
18762 /* If this glyph is alone on the last line, adjust it.ascent to minimum row ascent. */
18763 int face_ascent = face->font ? FONT_BASE (face->font) : FRAME_BASELINE_OFFSET (it->f);
18764 if (face_ascent > it->ascent)
18765 it->ascent = it->phys_ascent = face_ascent;
18766 #endif
18767
18768 it->nglyphs = 1;
18769
18770 if (face->box != FACE_NO_BOX)
18771 {
18772 if (face->box_line_width > 0)
18773 {
18774 if (slice.y == 0)
18775 it->ascent += face->box_line_width;
18776 if (slice.y + slice.height == img->height)
18777 it->descent += face->box_line_width;
18778 }
18779
18780 if (it->start_of_box_run_p && slice.x == 0)
18781 it->pixel_width += abs (face->box_line_width);
18782 if (it->end_of_box_run_p && slice.x + slice.width == img->width)
18783 it->pixel_width += abs (face->box_line_width);
18784 }
18785
18786 take_vertical_position_into_account (it);
18787
18788 if (it->glyph_row)
18789 {
18790 struct glyph *glyph;
18791 enum glyph_row_area area = it->area;
18792
18793 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18794 if (glyph < it->glyph_row->glyphs[area + 1])
18795 {
18796 glyph->charpos = CHARPOS (it->position);
18797 glyph->object = it->object;
18798 glyph->pixel_width = it->pixel_width;
18799 glyph->ascent = glyph_ascent;
18800 glyph->descent = it->descent;
18801 glyph->voffset = it->voffset;
18802 glyph->type = IMAGE_GLYPH;
18803 glyph->multibyte_p = it->multibyte_p;
18804 glyph->left_box_line_p = it->start_of_box_run_p;
18805 glyph->right_box_line_p = it->end_of_box_run_p;
18806 glyph->overlaps_vertically_p = 0;
18807 glyph->padding_p = 0;
18808 glyph->glyph_not_available_p = 0;
18809 glyph->face_id = it->face_id;
18810 glyph->u.img_id = img->id;
18811 glyph->slice = slice;
18812 glyph->font_type = FONT_TYPE_UNKNOWN;
18813 ++it->glyph_row->used[area];
18814 }
18815 else
18816 IT_EXPAND_MATRIX_WIDTH (it, area);
18817 }
18818 }
18819
18820
18821 /* Append a stretch glyph to IT->glyph_row. OBJECT is the source
18822 of the glyph, WIDTH and HEIGHT are the width and height of the
18823 stretch. ASCENT is the ascent of the glyph (0 <= ASCENT <= HEIGHT). */
18824
18825 static void
18826 append_stretch_glyph (it, object, width, height, ascent)
18827 struct it *it;
18828 Lisp_Object object;
18829 int width, height;
18830 int ascent;
18831 {
18832 struct glyph *glyph;
18833 enum glyph_row_area area = it->area;
18834
18835 xassert (ascent >= 0 && ascent <= height);
18836
18837 glyph = it->glyph_row->glyphs[area] + it->glyph_row->used[area];
18838 if (glyph < it->glyph_row->glyphs[area + 1])
18839 {
18840 glyph->charpos = CHARPOS (it->position);
18841 glyph->object = object;
18842 glyph->pixel_width = width;
18843 glyph->ascent = ascent;
18844 glyph->descent = height - ascent;
18845 glyph->voffset = it->voffset;
18846 glyph->type = STRETCH_GLYPH;
18847 glyph->multibyte_p = it->multibyte_p;
18848 glyph->left_box_line_p = it->start_of_box_run_p;
18849 glyph->right_box_line_p = it->end_of_box_run_p;
18850 glyph->overlaps_vertically_p = 0;
18851 glyph->padding_p = 0;
18852 glyph->glyph_not_available_p = 0;
18853 glyph->face_id = it->face_id;
18854 glyph->u.stretch.ascent = ascent;
18855 glyph->u.stretch.height = height;
18856 glyph->slice = null_glyph_slice;
18857 glyph->font_type = FONT_TYPE_UNKNOWN;
18858 ++it->glyph_row->used[area];
18859 }
18860 else
18861 IT_EXPAND_MATRIX_WIDTH (it, area);
18862 }
18863
18864
18865 /* Produce a stretch glyph for iterator IT. IT->object is the value
18866 of the glyph property displayed. The value must be a list
18867 `(space KEYWORD VALUE ...)' with the following KEYWORD/VALUE pairs
18868 being recognized:
18869
18870 1. `:width WIDTH' specifies that the space should be WIDTH *
18871 canonical char width wide. WIDTH may be an integer or floating
18872 point number.
18873
18874 2. `:relative-width FACTOR' specifies that the width of the stretch
18875 should be computed from the width of the first character having the
18876 `glyph' property, and should be FACTOR times that width.
18877
18878 3. `:align-to HPOS' specifies that the space should be wide enough
18879 to reach HPOS, a value in canonical character units.
18880
18881 Exactly one of the above pairs must be present.
18882
18883 4. `:height HEIGHT' specifies that the height of the stretch produced
18884 should be HEIGHT, measured in canonical character units.
18885
18886 5. `:relative-height FACTOR' specifies that the height of the
18887 stretch should be FACTOR times the height of the characters having
18888 the glyph property.
18889
18890 Either none or exactly one of 4 or 5 must be present.
18891
18892 6. `:ascent ASCENT' specifies that ASCENT percent of the height
18893 of the stretch should be used for the ascent of the stretch.
18894 ASCENT must be in the range 0 <= ASCENT <= 100. */
18895
18896 static void
18897 produce_stretch_glyph (it)
18898 struct it *it;
18899 {
18900 /* (space :width WIDTH :height HEIGHT ...) */
18901 Lisp_Object prop, plist;
18902 int width = 0, height = 0, align_to = -1;
18903 int zero_width_ok_p = 0, zero_height_ok_p = 0;
18904 int ascent = 0;
18905 double tem;
18906 struct face *face = FACE_FROM_ID (it->f, it->face_id);
18907 XFontStruct *font = face->font ? face->font : FRAME_FONT (it->f);
18908
18909 PREPARE_FACE_FOR_DISPLAY (it->f, face);
18910
18911 /* List should start with `space'. */
18912 xassert (CONSP (it->object) && EQ (XCAR (it->object), Qspace));
18913 plist = XCDR (it->object);
18914
18915 /* Compute the width of the stretch. */
18916 if ((prop = Fplist_get (plist, QCwidth), !NILP (prop))
18917 && calc_pixel_width_or_height (&tem, it, prop, font, 1, 0))
18918 {
18919 /* Absolute width `:width WIDTH' specified and valid. */
18920 zero_width_ok_p = 1;
18921 width = (int)tem;
18922 }
18923 else if (prop = Fplist_get (plist, QCrelative_width),
18924 NUMVAL (prop) > 0)
18925 {
18926 /* Relative width `:relative-width FACTOR' specified and valid.
18927 Compute the width of the characters having the `glyph'
18928 property. */
18929 struct it it2;
18930 unsigned char *p = BYTE_POS_ADDR (IT_BYTEPOS (*it));
18931
18932 it2 = *it;
18933 if (it->multibyte_p)
18934 {
18935 int maxlen = ((IT_BYTEPOS (*it) >= GPT ? ZV : GPT)
18936 - IT_BYTEPOS (*it));
18937 it2.c = STRING_CHAR_AND_LENGTH (p, maxlen, it2.len);
18938 }
18939 else
18940 it2.c = *p, it2.len = 1;
18941
18942 it2.glyph_row = NULL;
18943 it2.what = IT_CHARACTER;
18944 x_produce_glyphs (&it2);
18945 width = NUMVAL (prop) * it2.pixel_width;
18946 }
18947 else if ((prop = Fplist_get (plist, QCalign_to), !NILP (prop))
18948 && calc_pixel_width_or_height (&tem, it, prop, font, 1, &align_to))
18949 {
18950 if (it->glyph_row == NULL || !it->glyph_row->mode_line_p)
18951 align_to = (align_to < 0
18952 ? 0
18953 : align_to - window_box_left_offset (it->w, TEXT_AREA));
18954 else if (align_to < 0)
18955 align_to = window_box_left_offset (it->w, TEXT_AREA);
18956 width = max (0, (int)tem + align_to - it->current_x);
18957 zero_width_ok_p = 1;
18958 }
18959 else
18960 /* Nothing specified -> width defaults to canonical char width. */
18961 width = FRAME_COLUMN_WIDTH (it->f);
18962
18963 if (width <= 0 && (width < 0 || !zero_width_ok_p))
18964 width = 1;
18965
18966 /* Compute height. */
18967 if ((prop = Fplist_get (plist, QCheight), !NILP (prop))
18968 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18969 {
18970 height = (int)tem;
18971 zero_height_ok_p = 1;
18972 }
18973 else if (prop = Fplist_get (plist, QCrelative_height),
18974 NUMVAL (prop) > 0)
18975 height = FONT_HEIGHT (font) * NUMVAL (prop);
18976 else
18977 height = FONT_HEIGHT (font);
18978
18979 if (height <= 0 && (height < 0 || !zero_height_ok_p))
18980 height = 1;
18981
18982 /* Compute percentage of height used for ascent. If
18983 `:ascent ASCENT' is present and valid, use that. Otherwise,
18984 derive the ascent from the font in use. */
18985 if (prop = Fplist_get (plist, QCascent),
18986 NUMVAL (prop) > 0 && NUMVAL (prop) <= 100)
18987 ascent = height * NUMVAL (prop) / 100.0;
18988 else if (!NILP (prop)
18989 && calc_pixel_width_or_height (&tem, it, prop, font, 0, 0))
18990 ascent = min (max (0, (int)tem), height);
18991 else
18992 ascent = (height * FONT_BASE (font)) / FONT_HEIGHT (font);
18993
18994 if (width > 0 && height > 0 && it->glyph_row)
18995 {
18996 Lisp_Object object = it->stack[it->sp - 1].string;
18997 if (!STRINGP (object))
18998 object = it->w->buffer;
18999 append_stretch_glyph (it, object, width, height, ascent);
19000 }
19001
19002 it->pixel_width = width;
19003 it->ascent = it->phys_ascent = ascent;
19004 it->descent = it->phys_descent = height - it->ascent;
19005 it->nglyphs = width > 0 && height > 0 ? 1 : 0;
19006
19007 if (width > 0 && height > 0 && face->box != FACE_NO_BOX)
19008 {
19009 if (face->box_line_width > 0)
19010 {
19011 it->ascent += face->box_line_width;
19012 it->descent += face->box_line_width;
19013 }
19014
19015 if (it->start_of_box_run_p)
19016 it->pixel_width += abs (face->box_line_width);
19017 if (it->end_of_box_run_p)
19018 it->pixel_width += abs (face->box_line_width);
19019 }
19020
19021 take_vertical_position_into_account (it);
19022 }
19023
19024 /* Get line-height and line-spacing property at point.
19025 If line-height has format (HEIGHT TOTAL), return TOTAL
19026 in TOTAL_HEIGHT. */
19027
19028 static Lisp_Object
19029 get_line_height_property (it, prop)
19030 struct it *it;
19031 Lisp_Object prop;
19032 {
19033 Lisp_Object position, val;
19034
19035 if (STRINGP (it->object))
19036 position = make_number (IT_STRING_CHARPOS (*it));
19037 else if (BUFFERP (it->object))
19038 position = make_number (IT_CHARPOS (*it));
19039 else
19040 return Qnil;
19041
19042 return Fget_char_property (position, prop, it->object);
19043 }
19044
19045 /* Calculate line-height and line-spacing properties.
19046 An integer value specifies explicit pixel value.
19047 A float value specifies relative value to current face height.
19048 A cons (float . face-name) specifies relative value to
19049 height of specified face font.
19050
19051 Returns height in pixels, or nil. */
19052
19053
19054 static Lisp_Object
19055 calc_line_height_property (it, val, font, boff, override)
19056 struct it *it;
19057 Lisp_Object val;
19058 XFontStruct *font;
19059 int boff, override;
19060 {
19061 Lisp_Object face_name = Qnil;
19062 int ascent, descent, height;
19063
19064 if (NILP (val) || INTEGERP (val) || (override && EQ (val, Qt)))
19065 return val;
19066
19067 if (CONSP (val))
19068 {
19069 face_name = XCAR (val);
19070 val = XCDR (val);
19071 if (!NUMBERP (val))
19072 val = make_number (1);
19073 if (NILP (face_name))
19074 {
19075 height = it->ascent + it->descent;
19076 goto scale;
19077 }
19078 }
19079
19080 if (NILP (face_name))
19081 {
19082 font = FRAME_FONT (it->f);
19083 boff = FRAME_BASELINE_OFFSET (it->f);
19084 }
19085 else if (EQ (face_name, Qt))
19086 {
19087 override = 0;
19088 }
19089 else
19090 {
19091 int face_id;
19092 struct face *face;
19093 struct font_info *font_info;
19094
19095 face_id = lookup_named_face (it->f, face_name, ' ', 0);
19096 if (face_id < 0)
19097 return make_number (-1);
19098
19099 face = FACE_FROM_ID (it->f, face_id);
19100 font = face->font;
19101 if (font == NULL)
19102 return make_number (-1);
19103
19104 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19105 boff = font_info->baseline_offset;
19106 if (font_info->vertical_centering)
19107 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19108 }
19109
19110 ascent = FONT_BASE (font) + boff;
19111 descent = FONT_DESCENT (font) - boff;
19112
19113 if (override)
19114 {
19115 it->override_ascent = ascent;
19116 it->override_descent = descent;
19117 it->override_boff = boff;
19118 }
19119
19120 height = ascent + descent;
19121
19122 scale:
19123 if (FLOATP (val))
19124 height = (int)(XFLOAT_DATA (val) * height);
19125 else if (INTEGERP (val))
19126 height *= XINT (val);
19127
19128 return make_number (height);
19129 }
19130
19131
19132 /* RIF:
19133 Produce glyphs/get display metrics for the display element IT is
19134 loaded with. See the description of struct display_iterator in
19135 dispextern.h for an overview of struct display_iterator. */
19136
19137 void
19138 x_produce_glyphs (it)
19139 struct it *it;
19140 {
19141 int extra_line_spacing = it->extra_line_spacing;
19142
19143 it->glyph_not_available_p = 0;
19144
19145 if (it->what == IT_CHARACTER)
19146 {
19147 XChar2b char2b;
19148 XFontStruct *font;
19149 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19150 XCharStruct *pcm;
19151 int font_not_found_p;
19152 struct font_info *font_info;
19153 int boff; /* baseline offset */
19154 /* We may change it->multibyte_p upon unibyte<->multibyte
19155 conversion. So, save the current value now and restore it
19156 later.
19157
19158 Note: It seems that we don't have to record multibyte_p in
19159 struct glyph because the character code itself tells if or
19160 not the character is multibyte. Thus, in the future, we must
19161 consider eliminating the field `multibyte_p' in the struct
19162 glyph. */
19163 int saved_multibyte_p = it->multibyte_p;
19164
19165 /* Maybe translate single-byte characters to multibyte, or the
19166 other way. */
19167 it->char_to_display = it->c;
19168 if (!ASCII_BYTE_P (it->c))
19169 {
19170 if (unibyte_display_via_language_environment
19171 && SINGLE_BYTE_CHAR_P (it->c)
19172 && (it->c >= 0240
19173 || !NILP (Vnonascii_translation_table)))
19174 {
19175 it->char_to_display = unibyte_char_to_multibyte (it->c);
19176 it->multibyte_p = 1;
19177 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19178 face = FACE_FROM_ID (it->f, it->face_id);
19179 }
19180 else if (!SINGLE_BYTE_CHAR_P (it->c)
19181 && !it->multibyte_p)
19182 {
19183 it->multibyte_p = 1;
19184 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19185 face = FACE_FROM_ID (it->f, it->face_id);
19186 }
19187 }
19188
19189 /* Get font to use. Encode IT->char_to_display. */
19190 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19191 &char2b, it->multibyte_p, 0);
19192 font = face->font;
19193
19194 /* When no suitable font found, use the default font. */
19195 font_not_found_p = font == NULL;
19196 if (font_not_found_p)
19197 {
19198 font = FRAME_FONT (it->f);
19199 boff = FRAME_BASELINE_OFFSET (it->f);
19200 font_info = NULL;
19201 }
19202 else
19203 {
19204 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19205 boff = font_info->baseline_offset;
19206 if (font_info->vertical_centering)
19207 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19208 }
19209
19210 if (it->char_to_display >= ' '
19211 && (!it->multibyte_p || it->char_to_display < 128))
19212 {
19213 /* Either unibyte or ASCII. */
19214 int stretched_p;
19215
19216 it->nglyphs = 1;
19217
19218 pcm = rif->per_char_metric (font, &char2b,
19219 FONT_TYPE_FOR_UNIBYTE (font, it->char_to_display));
19220
19221 if (it->override_ascent >= 0)
19222 {
19223 it->ascent = it->override_ascent;
19224 it->descent = it->override_descent;
19225 boff = it->override_boff;
19226 }
19227 else
19228 {
19229 it->ascent = FONT_BASE (font) + boff;
19230 it->descent = FONT_DESCENT (font) - boff;
19231 }
19232
19233 if (pcm)
19234 {
19235 it->phys_ascent = pcm->ascent + boff;
19236 it->phys_descent = pcm->descent - boff;
19237 it->pixel_width = pcm->width;
19238 }
19239 else
19240 {
19241 it->glyph_not_available_p = 1;
19242 it->phys_ascent = it->ascent;
19243 it->phys_descent = it->descent;
19244 it->pixel_width = FONT_WIDTH (font);
19245 }
19246
19247 if (it->constrain_row_ascent_descent_p)
19248 {
19249 if (it->descent > it->max_descent)
19250 {
19251 it->ascent += it->descent - it->max_descent;
19252 it->descent = it->max_descent;
19253 }
19254 if (it->ascent > it->max_ascent)
19255 {
19256 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19257 it->ascent = it->max_ascent;
19258 }
19259 it->phys_ascent = min (it->phys_ascent, it->ascent);
19260 it->phys_descent = min (it->phys_descent, it->descent);
19261 extra_line_spacing = 0;
19262 }
19263
19264 /* If this is a space inside a region of text with
19265 `space-width' property, change its width. */
19266 stretched_p = it->char_to_display == ' ' && !NILP (it->space_width);
19267 if (stretched_p)
19268 it->pixel_width *= XFLOATINT (it->space_width);
19269
19270 /* If face has a box, add the box thickness to the character
19271 height. If character has a box line to the left and/or
19272 right, add the box line width to the character's width. */
19273 if (face->box != FACE_NO_BOX)
19274 {
19275 int thick = face->box_line_width;
19276
19277 if (thick > 0)
19278 {
19279 it->ascent += thick;
19280 it->descent += thick;
19281 }
19282 else
19283 thick = -thick;
19284
19285 if (it->start_of_box_run_p)
19286 it->pixel_width += thick;
19287 if (it->end_of_box_run_p)
19288 it->pixel_width += thick;
19289 }
19290
19291 /* If face has an overline, add the height of the overline
19292 (1 pixel) and a 1 pixel margin to the character height. */
19293 if (face->overline_p)
19294 it->ascent += 2;
19295
19296 if (it->constrain_row_ascent_descent_p)
19297 {
19298 if (it->ascent > it->max_ascent)
19299 it->ascent = it->max_ascent;
19300 if (it->descent > it->max_descent)
19301 it->descent = it->max_descent;
19302 }
19303
19304 take_vertical_position_into_account (it);
19305
19306 /* If we have to actually produce glyphs, do it. */
19307 if (it->glyph_row)
19308 {
19309 if (stretched_p)
19310 {
19311 /* Translate a space with a `space-width' property
19312 into a stretch glyph. */
19313 int ascent = (((it->ascent + it->descent) * FONT_BASE (font))
19314 / FONT_HEIGHT (font));
19315 append_stretch_glyph (it, it->object, it->pixel_width,
19316 it->ascent + it->descent, ascent);
19317 }
19318 else
19319 append_glyph (it);
19320
19321 /* If characters with lbearing or rbearing are displayed
19322 in this line, record that fact in a flag of the
19323 glyph row. This is used to optimize X output code. */
19324 if (pcm && (pcm->lbearing < 0 || pcm->rbearing > pcm->width))
19325 it->glyph_row->contains_overlapping_glyphs_p = 1;
19326 }
19327 }
19328 else if (it->char_to_display == '\n')
19329 {
19330 /* A newline has no width but we need the height of the line.
19331 But if previous part of the line set a height, don't
19332 increase that height */
19333
19334 Lisp_Object height;
19335 Lisp_Object total_height = Qnil;
19336
19337 it->override_ascent = -1;
19338 it->pixel_width = 0;
19339 it->nglyphs = 0;
19340
19341 height = get_line_height_property(it, Qline_height);
19342 /* Split (line-height total-height) list */
19343 if (CONSP (height)
19344 && CONSP (XCDR (height))
19345 && NILP (XCDR (XCDR (height))))
19346 {
19347 total_height = XCAR (XCDR (height));
19348 height = XCAR (height);
19349 }
19350 height = calc_line_height_property(it, height, font, boff, 1);
19351
19352 if (it->override_ascent >= 0)
19353 {
19354 it->ascent = it->override_ascent;
19355 it->descent = it->override_descent;
19356 boff = it->override_boff;
19357 }
19358 else
19359 {
19360 it->ascent = FONT_BASE (font) + boff;
19361 it->descent = FONT_DESCENT (font) - boff;
19362 }
19363
19364 if (EQ (height, Qt))
19365 {
19366 if (it->descent > it->max_descent)
19367 {
19368 it->ascent += it->descent - it->max_descent;
19369 it->descent = it->max_descent;
19370 }
19371 if (it->ascent > it->max_ascent)
19372 {
19373 it->descent = min (it->max_descent, it->descent + it->ascent - it->max_ascent);
19374 it->ascent = it->max_ascent;
19375 }
19376 it->phys_ascent = min (it->phys_ascent, it->ascent);
19377 it->phys_descent = min (it->phys_descent, it->descent);
19378 it->constrain_row_ascent_descent_p = 1;
19379 extra_line_spacing = 0;
19380 }
19381 else
19382 {
19383 Lisp_Object spacing;
19384 int total = 0;
19385
19386 it->phys_ascent = it->ascent;
19387 it->phys_descent = it->descent;
19388
19389 if ((it->max_ascent > 0 || it->max_descent > 0)
19390 && face->box != FACE_NO_BOX
19391 && face->box_line_width > 0)
19392 {
19393 it->ascent += face->box_line_width;
19394 it->descent += face->box_line_width;
19395 }
19396 if (!NILP (height)
19397 && XINT (height) > it->ascent + it->descent)
19398 it->ascent = XINT (height) - it->descent;
19399
19400 if (!NILP (total_height))
19401 spacing = calc_line_height_property(it, total_height, font, boff, 0);
19402 else
19403 {
19404 spacing = get_line_height_property(it, Qline_spacing);
19405 spacing = calc_line_height_property(it, spacing, font, boff, 0);
19406 }
19407 if (INTEGERP (spacing))
19408 {
19409 extra_line_spacing = XINT (spacing);
19410 if (!NILP (total_height))
19411 extra_line_spacing -= (it->phys_ascent + it->phys_descent);
19412 }
19413 }
19414 }
19415 else if (it->char_to_display == '\t')
19416 {
19417 int tab_width = it->tab_width * FRAME_SPACE_WIDTH (it->f);
19418 int x = it->current_x + it->continuation_lines_width;
19419 int next_tab_x = ((1 + x + tab_width - 1) / tab_width) * tab_width;
19420
19421 /* If the distance from the current position to the next tab
19422 stop is less than a space character width, use the
19423 tab stop after that. */
19424 if (next_tab_x - x < FRAME_SPACE_WIDTH (it->f))
19425 next_tab_x += tab_width;
19426
19427 it->pixel_width = next_tab_x - x;
19428 it->nglyphs = 1;
19429 it->ascent = it->phys_ascent = FONT_BASE (font) + boff;
19430 it->descent = it->phys_descent = FONT_DESCENT (font) - boff;
19431
19432 if (it->glyph_row)
19433 {
19434 append_stretch_glyph (it, it->object, it->pixel_width,
19435 it->ascent + it->descent, it->ascent);
19436 }
19437 }
19438 else
19439 {
19440 /* A multi-byte character. Assume that the display width of the
19441 character is the width of the character multiplied by the
19442 width of the font. */
19443
19444 /* If we found a font, this font should give us the right
19445 metrics. If we didn't find a font, use the frame's
19446 default font and calculate the width of the character
19447 from the charset width; this is what old redisplay code
19448 did. */
19449
19450 pcm = rif->per_char_metric (font, &char2b,
19451 FONT_TYPE_FOR_MULTIBYTE (font, it->c));
19452
19453 if (font_not_found_p || !pcm)
19454 {
19455 int charset = CHAR_CHARSET (it->char_to_display);
19456
19457 it->glyph_not_available_p = 1;
19458 it->pixel_width = (FRAME_COLUMN_WIDTH (it->f)
19459 * CHARSET_WIDTH (charset));
19460 it->phys_ascent = FONT_BASE (font) + boff;
19461 it->phys_descent = FONT_DESCENT (font) - boff;
19462 }
19463 else
19464 {
19465 it->pixel_width = pcm->width;
19466 it->phys_ascent = pcm->ascent + boff;
19467 it->phys_descent = pcm->descent - boff;
19468 if (it->glyph_row
19469 && (pcm->lbearing < 0
19470 || pcm->rbearing > pcm->width))
19471 it->glyph_row->contains_overlapping_glyphs_p = 1;
19472 }
19473 it->nglyphs = 1;
19474 it->ascent = FONT_BASE (font) + boff;
19475 it->descent = FONT_DESCENT (font) - boff;
19476 if (face->box != FACE_NO_BOX)
19477 {
19478 int thick = face->box_line_width;
19479
19480 if (thick > 0)
19481 {
19482 it->ascent += thick;
19483 it->descent += thick;
19484 }
19485 else
19486 thick = - thick;
19487
19488 if (it->start_of_box_run_p)
19489 it->pixel_width += thick;
19490 if (it->end_of_box_run_p)
19491 it->pixel_width += thick;
19492 }
19493
19494 /* If face has an overline, add the height of the overline
19495 (1 pixel) and a 1 pixel margin to the character height. */
19496 if (face->overline_p)
19497 it->ascent += 2;
19498
19499 take_vertical_position_into_account (it);
19500
19501 if (it->glyph_row)
19502 append_glyph (it);
19503 }
19504 it->multibyte_p = saved_multibyte_p;
19505 }
19506 else if (it->what == IT_COMPOSITION)
19507 {
19508 /* Note: A composition is represented as one glyph in the
19509 glyph matrix. There are no padding glyphs. */
19510 XChar2b char2b;
19511 XFontStruct *font;
19512 struct face *face = FACE_FROM_ID (it->f, it->face_id);
19513 XCharStruct *pcm;
19514 int font_not_found_p;
19515 struct font_info *font_info;
19516 int boff; /* baseline offset */
19517 struct composition *cmp = composition_table[it->cmp_id];
19518
19519 /* Maybe translate single-byte characters to multibyte. */
19520 it->char_to_display = it->c;
19521 if (unibyte_display_via_language_environment
19522 && SINGLE_BYTE_CHAR_P (it->c)
19523 && (it->c >= 0240
19524 || (it->c >= 0200
19525 && !NILP (Vnonascii_translation_table))))
19526 {
19527 it->char_to_display = unibyte_char_to_multibyte (it->c);
19528 }
19529
19530 /* Get face and font to use. Encode IT->char_to_display. */
19531 it->face_id = FACE_FOR_CHAR (it->f, face, it->char_to_display);
19532 face = FACE_FROM_ID (it->f, it->face_id);
19533 get_char_face_and_encoding (it->f, it->char_to_display, it->face_id,
19534 &char2b, it->multibyte_p, 0);
19535 font = face->font;
19536
19537 /* When no suitable font found, use the default font. */
19538 font_not_found_p = font == NULL;
19539 if (font_not_found_p)
19540 {
19541 font = FRAME_FONT (it->f);
19542 boff = FRAME_BASELINE_OFFSET (it->f);
19543 font_info = NULL;
19544 }
19545 else
19546 {
19547 font_info = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19548 boff = font_info->baseline_offset;
19549 if (font_info->vertical_centering)
19550 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19551 }
19552
19553 /* There are no padding glyphs, so there is only one glyph to
19554 produce for the composition. Important is that pixel_width,
19555 ascent and descent are the values of what is drawn by
19556 draw_glyphs (i.e. the values of the overall glyphs composed). */
19557 it->nglyphs = 1;
19558
19559 /* If we have not yet calculated pixel size data of glyphs of
19560 the composition for the current face font, calculate them
19561 now. Theoretically, we have to check all fonts for the
19562 glyphs, but that requires much time and memory space. So,
19563 here we check only the font of the first glyph. This leads
19564 to incorrect display very rarely, and C-l (recenter) can
19565 correct the display anyway. */
19566 if (cmp->font != (void *) font)
19567 {
19568 /* Ascent and descent of the font of the first character of
19569 this composition (adjusted by baseline offset). Ascent
19570 and descent of overall glyphs should not be less than
19571 them respectively. */
19572 int font_ascent = FONT_BASE (font) + boff;
19573 int font_descent = FONT_DESCENT (font) - boff;
19574 /* Bounding box of the overall glyphs. */
19575 int leftmost, rightmost, lowest, highest;
19576 int i, width, ascent, descent;
19577
19578 cmp->font = (void *) font;
19579
19580 /* Initialize the bounding box. */
19581 if (font_info
19582 && (pcm = rif->per_char_metric (font, &char2b,
19583 FONT_TYPE_FOR_MULTIBYTE (font, it->c))))
19584 {
19585 width = pcm->width;
19586 ascent = pcm->ascent;
19587 descent = pcm->descent;
19588 }
19589 else
19590 {
19591 width = FONT_WIDTH (font);
19592 ascent = FONT_BASE (font);
19593 descent = FONT_DESCENT (font);
19594 }
19595
19596 rightmost = width;
19597 lowest = - descent + boff;
19598 highest = ascent + boff;
19599 leftmost = 0;
19600
19601 if (font_info
19602 && font_info->default_ascent
19603 && CHAR_TABLE_P (Vuse_default_ascent)
19604 && !NILP (Faref (Vuse_default_ascent,
19605 make_number (it->char_to_display))))
19606 highest = font_info->default_ascent + boff;
19607
19608 /* Draw the first glyph at the normal position. It may be
19609 shifted to right later if some other glyphs are drawn at
19610 the left. */
19611 cmp->offsets[0] = 0;
19612 cmp->offsets[1] = boff;
19613
19614 /* Set cmp->offsets for the remaining glyphs. */
19615 for (i = 1; i < cmp->glyph_len; i++)
19616 {
19617 int left, right, btm, top;
19618 int ch = COMPOSITION_GLYPH (cmp, i);
19619 int face_id = FACE_FOR_CHAR (it->f, face, ch);
19620
19621 face = FACE_FROM_ID (it->f, face_id);
19622 get_char_face_and_encoding (it->f, ch, face->id,
19623 &char2b, it->multibyte_p, 0);
19624 font = face->font;
19625 if (font == NULL)
19626 {
19627 font = FRAME_FONT (it->f);
19628 boff = FRAME_BASELINE_OFFSET (it->f);
19629 font_info = NULL;
19630 }
19631 else
19632 {
19633 font_info
19634 = FONT_INFO_FROM_ID (it->f, face->font_info_id);
19635 boff = font_info->baseline_offset;
19636 if (font_info->vertical_centering)
19637 boff = VCENTER_BASELINE_OFFSET (font, it->f) - boff;
19638 }
19639
19640 if (font_info
19641 && (pcm = rif->per_char_metric (font, &char2b,
19642 FONT_TYPE_FOR_MULTIBYTE (font, ch))))
19643 {
19644 width = pcm->width;
19645 ascent = pcm->ascent;
19646 descent = pcm->descent;
19647 }
19648 else
19649 {
19650 width = FONT_WIDTH (font);
19651 ascent = 1;
19652 descent = 0;
19653 }
19654
19655 if (cmp->method != COMPOSITION_WITH_RULE_ALTCHARS)
19656 {
19657 /* Relative composition with or without
19658 alternate chars. */
19659 left = (leftmost + rightmost - width) / 2;
19660 btm = - descent + boff;
19661 if (font_info && font_info->relative_compose
19662 && (! CHAR_TABLE_P (Vignore_relative_composition)
19663 || NILP (Faref (Vignore_relative_composition,
19664 make_number (ch)))))
19665 {
19666
19667 if (- descent >= font_info->relative_compose)
19668 /* One extra pixel between two glyphs. */
19669 btm = highest + 1;
19670 else if (ascent <= 0)
19671 /* One extra pixel between two glyphs. */
19672 btm = lowest - 1 - ascent - descent;
19673 }
19674 }
19675 else
19676 {
19677 /* A composition rule is specified by an integer
19678 value that encodes global and new reference
19679 points (GREF and NREF). GREF and NREF are
19680 specified by numbers as below:
19681
19682 0---1---2 -- ascent
19683 | |
19684 | |
19685 | |
19686 9--10--11 -- center
19687 | |
19688 ---3---4---5--- baseline
19689 | |
19690 6---7---8 -- descent
19691 */
19692 int rule = COMPOSITION_RULE (cmp, i);
19693 int gref, nref, grefx, grefy, nrefx, nrefy;
19694
19695 COMPOSITION_DECODE_RULE (rule, gref, nref);
19696 grefx = gref % 3, nrefx = nref % 3;
19697 grefy = gref / 3, nrefy = nref / 3;
19698
19699 left = (leftmost
19700 + grefx * (rightmost - leftmost) / 2
19701 - nrefx * width / 2);
19702 btm = ((grefy == 0 ? highest
19703 : grefy == 1 ? 0
19704 : grefy == 2 ? lowest
19705 : (highest + lowest) / 2)
19706 - (nrefy == 0 ? ascent + descent
19707 : nrefy == 1 ? descent - boff
19708 : nrefy == 2 ? 0
19709 : (ascent + descent) / 2));
19710 }
19711
19712 cmp->offsets[i * 2] = left;
19713 cmp->offsets[i * 2 + 1] = btm + descent;
19714
19715 /* Update the bounding box of the overall glyphs. */
19716 right = left + width;
19717 top = btm + descent + ascent;
19718 if (left < leftmost)
19719 leftmost = left;
19720 if (right > rightmost)
19721 rightmost = right;
19722 if (top > highest)
19723 highest = top;
19724 if (btm < lowest)
19725 lowest = btm;
19726 }
19727
19728 /* If there are glyphs whose x-offsets are negative,
19729 shift all glyphs to the right and make all x-offsets
19730 non-negative. */
19731 if (leftmost < 0)
19732 {
19733 for (i = 0; i < cmp->glyph_len; i++)
19734 cmp->offsets[i * 2] -= leftmost;
19735 rightmost -= leftmost;
19736 }
19737
19738 cmp->pixel_width = rightmost;
19739 cmp->ascent = highest;
19740 cmp->descent = - lowest;
19741 if (cmp->ascent < font_ascent)
19742 cmp->ascent = font_ascent;
19743 if (cmp->descent < font_descent)
19744 cmp->descent = font_descent;
19745 }
19746
19747 it->pixel_width = cmp->pixel_width;
19748 it->ascent = it->phys_ascent = cmp->ascent;
19749 it->descent = it->phys_descent = cmp->descent;
19750
19751 if (face->box != FACE_NO_BOX)
19752 {
19753 int thick = face->box_line_width;
19754
19755 if (thick > 0)
19756 {
19757 it->ascent += thick;
19758 it->descent += thick;
19759 }
19760 else
19761 thick = - thick;
19762
19763 if (it->start_of_box_run_p)
19764 it->pixel_width += thick;
19765 if (it->end_of_box_run_p)
19766 it->pixel_width += thick;
19767 }
19768
19769 /* If face has an overline, add the height of the overline
19770 (1 pixel) and a 1 pixel margin to the character height. */
19771 if (face->overline_p)
19772 it->ascent += 2;
19773
19774 take_vertical_position_into_account (it);
19775
19776 if (it->glyph_row)
19777 append_composite_glyph (it);
19778 }
19779 else if (it->what == IT_IMAGE)
19780 produce_image_glyph (it);
19781 else if (it->what == IT_STRETCH)
19782 produce_stretch_glyph (it);
19783
19784 /* Accumulate dimensions. Note: can't assume that it->descent > 0
19785 because this isn't true for images with `:ascent 100'. */
19786 xassert (it->ascent >= 0 && it->descent >= 0);
19787 if (it->area == TEXT_AREA)
19788 it->current_x += it->pixel_width;
19789
19790 if (extra_line_spacing > 0)
19791 {
19792 it->descent += extra_line_spacing;
19793 if (extra_line_spacing > it->max_extra_line_spacing)
19794 it->max_extra_line_spacing = extra_line_spacing;
19795 }
19796
19797 it->max_ascent = max (it->max_ascent, it->ascent);
19798 it->max_descent = max (it->max_descent, it->descent);
19799 it->max_phys_ascent = max (it->max_phys_ascent, it->phys_ascent);
19800 it->max_phys_descent = max (it->max_phys_descent, it->phys_descent);
19801 }
19802
19803 /* EXPORT for RIF:
19804 Output LEN glyphs starting at START at the nominal cursor position.
19805 Advance the nominal cursor over the text. The global variable
19806 updated_window contains the window being updated, updated_row is
19807 the glyph row being updated, and updated_area is the area of that
19808 row being updated. */
19809
19810 void
19811 x_write_glyphs (start, len)
19812 struct glyph *start;
19813 int len;
19814 {
19815 int x, hpos;
19816
19817 xassert (updated_window && updated_row);
19818 BLOCK_INPUT;
19819
19820 /* Write glyphs. */
19821
19822 hpos = start - updated_row->glyphs[updated_area];
19823 x = draw_glyphs (updated_window, output_cursor.x,
19824 updated_row, updated_area,
19825 hpos, hpos + len,
19826 DRAW_NORMAL_TEXT, 0);
19827
19828 /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
19829 if (updated_area == TEXT_AREA
19830 && updated_window->phys_cursor_on_p
19831 && updated_window->phys_cursor.vpos == output_cursor.vpos
19832 && updated_window->phys_cursor.hpos >= hpos
19833 && updated_window->phys_cursor.hpos < hpos + len)
19834 updated_window->phys_cursor_on_p = 0;
19835
19836 UNBLOCK_INPUT;
19837
19838 /* Advance the output cursor. */
19839 output_cursor.hpos += len;
19840 output_cursor.x = x;
19841 }
19842
19843
19844 /* EXPORT for RIF:
19845 Insert LEN glyphs from START at the nominal cursor position. */
19846
19847 void
19848 x_insert_glyphs (start, len)
19849 struct glyph *start;
19850 int len;
19851 {
19852 struct frame *f;
19853 struct window *w;
19854 int line_height, shift_by_width, shifted_region_width;
19855 struct glyph_row *row;
19856 struct glyph *glyph;
19857 int frame_x, frame_y, hpos;
19858
19859 xassert (updated_window && updated_row);
19860 BLOCK_INPUT;
19861 w = updated_window;
19862 f = XFRAME (WINDOW_FRAME (w));
19863
19864 /* Get the height of the line we are in. */
19865 row = updated_row;
19866 line_height = row->height;
19867
19868 /* Get the width of the glyphs to insert. */
19869 shift_by_width = 0;
19870 for (glyph = start; glyph < start + len; ++glyph)
19871 shift_by_width += glyph->pixel_width;
19872
19873 /* Get the width of the region to shift right. */
19874 shifted_region_width = (window_box_width (w, updated_area)
19875 - output_cursor.x
19876 - shift_by_width);
19877
19878 /* Shift right. */
19879 frame_x = window_box_left (w, updated_area) + output_cursor.x;
19880 frame_y = WINDOW_TO_FRAME_PIXEL_Y (w, output_cursor.y);
19881
19882 rif->shift_glyphs_for_insert (f, frame_x, frame_y, shifted_region_width,
19883 line_height, shift_by_width);
19884
19885 /* Write the glyphs. */
19886 hpos = start - row->glyphs[updated_area];
19887 draw_glyphs (w, output_cursor.x, row, updated_area,
19888 hpos, hpos + len,
19889 DRAW_NORMAL_TEXT, 0);
19890
19891 /* Advance the output cursor. */
19892 output_cursor.hpos += len;
19893 output_cursor.x += shift_by_width;
19894 UNBLOCK_INPUT;
19895 }
19896
19897
19898 /* EXPORT for RIF:
19899 Erase the current text line from the nominal cursor position
19900 (inclusive) to pixel column TO_X (exclusive). The idea is that
19901 everything from TO_X onward is already erased.
19902
19903 TO_X is a pixel position relative to updated_area of
19904 updated_window. TO_X == -1 means clear to the end of this area. */
19905
19906 void
19907 x_clear_end_of_line (to_x)
19908 int to_x;
19909 {
19910 struct frame *f;
19911 struct window *w = updated_window;
19912 int max_x, min_y, max_y;
19913 int from_x, from_y, to_y;
19914
19915 xassert (updated_window && updated_row);
19916 f = XFRAME (w->frame);
19917
19918 if (updated_row->full_width_p)
19919 max_x = WINDOW_TOTAL_WIDTH (w);
19920 else
19921 max_x = window_box_width (w, updated_area);
19922 max_y = window_text_bottom_y (w);
19923
19924 /* TO_X == 0 means don't do anything. TO_X < 0 means clear to end
19925 of window. For TO_X > 0, truncate to end of drawing area. */
19926 if (to_x == 0)
19927 return;
19928 else if (to_x < 0)
19929 to_x = max_x;
19930 else
19931 to_x = min (to_x, max_x);
19932
19933 to_y = min (max_y, output_cursor.y + updated_row->height);
19934
19935 /* Notice if the cursor will be cleared by this operation. */
19936 if (!updated_row->full_width_p)
19937 notice_overwritten_cursor (w, updated_area,
19938 output_cursor.x, -1,
19939 updated_row->y,
19940 MATRIX_ROW_BOTTOM_Y (updated_row));
19941
19942 from_x = output_cursor.x;
19943
19944 /* Translate to frame coordinates. */
19945 if (updated_row->full_width_p)
19946 {
19947 from_x = WINDOW_TO_FRAME_PIXEL_X (w, from_x);
19948 to_x = WINDOW_TO_FRAME_PIXEL_X (w, to_x);
19949 }
19950 else
19951 {
19952 int area_left = window_box_left (w, updated_area);
19953 from_x += area_left;
19954 to_x += area_left;
19955 }
19956
19957 min_y = WINDOW_HEADER_LINE_HEIGHT (w);
19958 from_y = WINDOW_TO_FRAME_PIXEL_Y (w, max (min_y, output_cursor.y));
19959 to_y = WINDOW_TO_FRAME_PIXEL_Y (w, to_y);
19960
19961 /* Prevent inadvertently clearing to end of the X window. */
19962 if (to_x > from_x && to_y > from_y)
19963 {
19964 BLOCK_INPUT;
19965 rif->clear_frame_area (f, from_x, from_y,
19966 to_x - from_x, to_y - from_y);
19967 UNBLOCK_INPUT;
19968 }
19969 }
19970
19971 #endif /* HAVE_WINDOW_SYSTEM */
19972
19973
19974 \f
19975 /***********************************************************************
19976 Cursor types
19977 ***********************************************************************/
19978
19979 /* Value is the internal representation of the specified cursor type
19980 ARG. If type is BAR_CURSOR, return in *WIDTH the specified width
19981 of the bar cursor. */
19982
19983 static enum text_cursor_kinds
19984 get_specified_cursor_type (arg, width)
19985 Lisp_Object arg;
19986 int *width;
19987 {
19988 enum text_cursor_kinds type;
19989
19990 if (NILP (arg))
19991 return NO_CURSOR;
19992
19993 if (EQ (arg, Qbox))
19994 return FILLED_BOX_CURSOR;
19995
19996 if (EQ (arg, Qhollow))
19997 return HOLLOW_BOX_CURSOR;
19998
19999 if (EQ (arg, Qbar))
20000 {
20001 *width = 2;
20002 return BAR_CURSOR;
20003 }
20004
20005 if (CONSP (arg)
20006 && EQ (XCAR (arg), Qbar)
20007 && INTEGERP (XCDR (arg))
20008 && XINT (XCDR (arg)) >= 0)
20009 {
20010 *width = XINT (XCDR (arg));
20011 return BAR_CURSOR;
20012 }
20013
20014 if (EQ (arg, Qhbar))
20015 {
20016 *width = 2;
20017 return HBAR_CURSOR;
20018 }
20019
20020 if (CONSP (arg)
20021 && EQ (XCAR (arg), Qhbar)
20022 && INTEGERP (XCDR (arg))
20023 && XINT (XCDR (arg)) >= 0)
20024 {
20025 *width = XINT (XCDR (arg));
20026 return HBAR_CURSOR;
20027 }
20028
20029 /* Treat anything unknown as "hollow box cursor".
20030 It was bad to signal an error; people have trouble fixing
20031 .Xdefaults with Emacs, when it has something bad in it. */
20032 type = HOLLOW_BOX_CURSOR;
20033
20034 return type;
20035 }
20036
20037 /* Set the default cursor types for specified frame. */
20038 void
20039 set_frame_cursor_types (f, arg)
20040 struct frame *f;
20041 Lisp_Object arg;
20042 {
20043 int width;
20044 Lisp_Object tem;
20045
20046 FRAME_DESIRED_CURSOR (f) = get_specified_cursor_type (arg, &width);
20047 FRAME_CURSOR_WIDTH (f) = width;
20048
20049 /* By default, set up the blink-off state depending on the on-state. */
20050
20051 tem = Fassoc (arg, Vblink_cursor_alist);
20052 if (!NILP (tem))
20053 {
20054 FRAME_BLINK_OFF_CURSOR (f)
20055 = get_specified_cursor_type (XCDR (tem), &width);
20056 FRAME_BLINK_OFF_CURSOR_WIDTH (f) = width;
20057 }
20058 else
20059 FRAME_BLINK_OFF_CURSOR (f) = DEFAULT_CURSOR;
20060 }
20061
20062
20063 /* Return the cursor we want to be displayed in window W. Return
20064 width of bar/hbar cursor through WIDTH arg. Return with
20065 ACTIVE_CURSOR arg set to 1 if cursor in window W is `active'
20066 (i.e. if the `system caret' should track this cursor).
20067
20068 In a mini-buffer window, we want the cursor only to appear if we
20069 are reading input from this window. For the selected window, we
20070 want the cursor type given by the frame parameter or buffer local
20071 setting of cursor-type. If explicitly marked off, draw no cursor.
20072 In all other cases, we want a hollow box cursor. */
20073
20074 static enum text_cursor_kinds
20075 get_window_cursor_type (w, glyph, width, active_cursor)
20076 struct window *w;
20077 struct glyph *glyph;
20078 int *width;
20079 int *active_cursor;
20080 {
20081 struct frame *f = XFRAME (w->frame);
20082 struct buffer *b = XBUFFER (w->buffer);
20083 int cursor_type = DEFAULT_CURSOR;
20084 Lisp_Object alt_cursor;
20085 int non_selected = 0;
20086
20087 *active_cursor = 1;
20088
20089 /* Echo area */
20090 if (cursor_in_echo_area
20091 && FRAME_HAS_MINIBUF_P (f)
20092 && EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
20093 {
20094 if (w == XWINDOW (echo_area_window))
20095 {
20096 *width = FRAME_CURSOR_WIDTH (f);
20097 return FRAME_DESIRED_CURSOR (f);
20098 }
20099
20100 *active_cursor = 0;
20101 non_selected = 1;
20102 }
20103
20104 /* Nonselected window or nonselected frame. */
20105 else if (w != XWINDOW (f->selected_window)
20106 #ifdef HAVE_WINDOW_SYSTEM
20107 || f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
20108 #endif
20109 )
20110 {
20111 *active_cursor = 0;
20112
20113 if (MINI_WINDOW_P (w) && minibuf_level == 0)
20114 return NO_CURSOR;
20115
20116 non_selected = 1;
20117 }
20118
20119 /* Never display a cursor in a window in which cursor-type is nil. */
20120 if (NILP (b->cursor_type))
20121 return NO_CURSOR;
20122
20123 /* Use cursor-in-non-selected-windows for non-selected window or frame. */
20124 if (non_selected)
20125 {
20126 alt_cursor = Fbuffer_local_value (Qcursor_in_non_selected_windows, w->buffer);
20127 return get_specified_cursor_type (alt_cursor, width);
20128 }
20129
20130 /* Get the normal cursor type for this window. */
20131 if (EQ (b->cursor_type, Qt))
20132 {
20133 cursor_type = FRAME_DESIRED_CURSOR (f);
20134 *width = FRAME_CURSOR_WIDTH (f);
20135 }
20136 else
20137 cursor_type = get_specified_cursor_type (b->cursor_type, width);
20138
20139 /* Use normal cursor if not blinked off. */
20140 if (!w->cursor_off_p)
20141 {
20142 if (glyph != NULL && glyph->type == IMAGE_GLYPH) {
20143 if (cursor_type == FILLED_BOX_CURSOR)
20144 cursor_type = HOLLOW_BOX_CURSOR;
20145 }
20146 return cursor_type;
20147 }
20148
20149 /* Cursor is blinked off, so determine how to "toggle" it. */
20150
20151 /* First look for an entry matching the buffer's cursor-type in blink-cursor-alist. */
20152 if ((alt_cursor = Fassoc (b->cursor_type, Vblink_cursor_alist), !NILP (alt_cursor)))
20153 return get_specified_cursor_type (XCDR (alt_cursor), width);
20154
20155 /* Then see if frame has specified a specific blink off cursor type. */
20156 if (FRAME_BLINK_OFF_CURSOR (f) != DEFAULT_CURSOR)
20157 {
20158 *width = FRAME_BLINK_OFF_CURSOR_WIDTH (f);
20159 return FRAME_BLINK_OFF_CURSOR (f);
20160 }
20161
20162 #if 0
20163 /* Some people liked having a permanently visible blinking cursor,
20164 while others had very strong opinions against it. So it was
20165 decided to remove it. KFS 2003-09-03 */
20166
20167 /* Finally perform built-in cursor blinking:
20168 filled box <-> hollow box
20169 wide [h]bar <-> narrow [h]bar
20170 narrow [h]bar <-> no cursor
20171 other type <-> no cursor */
20172
20173 if (cursor_type == FILLED_BOX_CURSOR)
20174 return HOLLOW_BOX_CURSOR;
20175
20176 if ((cursor_type == BAR_CURSOR || cursor_type == HBAR_CURSOR) && *width > 1)
20177 {
20178 *width = 1;
20179 return cursor_type;
20180 }
20181 #endif
20182
20183 return NO_CURSOR;
20184 }
20185
20186
20187 #ifdef HAVE_WINDOW_SYSTEM
20188
20189 /* Notice when the text cursor of window W has been completely
20190 overwritten by a drawing operation that outputs glyphs in AREA
20191 starting at X0 and ending at X1 in the line starting at Y0 and
20192 ending at Y1. X coordinates are area-relative. X1 < 0 means all
20193 the rest of the line after X0 has been written. Y coordinates
20194 are window-relative. */
20195
20196 static void
20197 notice_overwritten_cursor (w, area, x0, x1, y0, y1)
20198 struct window *w;
20199 enum glyph_row_area area;
20200 int x0, y0, x1, y1;
20201 {
20202 int cx0, cx1, cy0, cy1;
20203 struct glyph_row *row;
20204
20205 if (!w->phys_cursor_on_p)
20206 return;
20207 if (area != TEXT_AREA)
20208 return;
20209
20210 if (w->phys_cursor.vpos < 0
20211 || w->phys_cursor.vpos >= w->current_matrix->nrows
20212 || (row = w->current_matrix->rows + w->phys_cursor.vpos,
20213 !(row->enabled_p && row->displays_text_p)))
20214 return;
20215
20216 if (row->cursor_in_fringe_p)
20217 {
20218 row->cursor_in_fringe_p = 0;
20219 draw_fringe_bitmap (w, row, 0);
20220 w->phys_cursor_on_p = 0;
20221 return;
20222 }
20223
20224 cx0 = w->phys_cursor.x;
20225 cx1 = cx0 + w->phys_cursor_width;
20226 if (x0 > cx0 || (x1 >= 0 && x1 < cx1))
20227 return;
20228
20229 /* The cursor image will be completely removed from the
20230 screen if the output area intersects the cursor area in
20231 y-direction. When we draw in [y0 y1[, and some part of
20232 the cursor is at y < y0, that part must have been drawn
20233 before. When scrolling, the cursor is erased before
20234 actually scrolling, so we don't come here. When not
20235 scrolling, the rows above the old cursor row must have
20236 changed, and in this case these rows must have written
20237 over the cursor image.
20238
20239 Likewise if part of the cursor is below y1, with the
20240 exception of the cursor being in the first blank row at
20241 the buffer and window end because update_text_area
20242 doesn't draw that row. (Except when it does, but
20243 that's handled in update_text_area.) */
20244
20245 cy0 = w->phys_cursor.y;
20246 cy1 = cy0 + w->phys_cursor_height;
20247 if ((y0 < cy0 || y0 >= cy1) && (y1 <= cy0 || y1 >= cy1))
20248 return;
20249
20250 w->phys_cursor_on_p = 0;
20251 }
20252
20253 #endif /* HAVE_WINDOW_SYSTEM */
20254
20255 \f
20256 /************************************************************************
20257 Mouse Face
20258 ************************************************************************/
20259
20260 #ifdef HAVE_WINDOW_SYSTEM
20261
20262 /* EXPORT for RIF:
20263 Fix the display of area AREA of overlapping row ROW in window W. */
20264
20265 void
20266 x_fix_overlapping_area (w, row, area)
20267 struct window *w;
20268 struct glyph_row *row;
20269 enum glyph_row_area area;
20270 {
20271 int i, x;
20272
20273 BLOCK_INPUT;
20274
20275 x = 0;
20276 for (i = 0; i < row->used[area];)
20277 {
20278 if (row->glyphs[area][i].overlaps_vertically_p)
20279 {
20280 int start = i, start_x = x;
20281
20282 do
20283 {
20284 x += row->glyphs[area][i].pixel_width;
20285 ++i;
20286 }
20287 while (i < row->used[area]
20288 && row->glyphs[area][i].overlaps_vertically_p);
20289
20290 draw_glyphs (w, start_x, row, area,
20291 start, i,
20292 DRAW_NORMAL_TEXT, 1);
20293 }
20294 else
20295 {
20296 x += row->glyphs[area][i].pixel_width;
20297 ++i;
20298 }
20299 }
20300
20301 UNBLOCK_INPUT;
20302 }
20303
20304
20305 /* EXPORT:
20306 Draw the cursor glyph of window W in glyph row ROW. See the
20307 comment of draw_glyphs for the meaning of HL. */
20308
20309 void
20310 draw_phys_cursor_glyph (w, row, hl)
20311 struct window *w;
20312 struct glyph_row *row;
20313 enum draw_glyphs_face hl;
20314 {
20315 /* If cursor hpos is out of bounds, don't draw garbage. This can
20316 happen in mini-buffer windows when switching between echo area
20317 glyphs and mini-buffer. */
20318 if (w->phys_cursor.hpos < row->used[TEXT_AREA])
20319 {
20320 int on_p = w->phys_cursor_on_p;
20321 int x1;
20322 x1 = draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
20323 w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
20324 hl, 0);
20325 w->phys_cursor_on_p = on_p;
20326
20327 if (hl == DRAW_CURSOR)
20328 w->phys_cursor_width = x1 - w->phys_cursor.x;
20329 /* When we erase the cursor, and ROW is overlapped by other
20330 rows, make sure that these overlapping parts of other rows
20331 are redrawn. */
20332 else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
20333 {
20334 if (row > w->current_matrix->rows
20335 && MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
20336 x_fix_overlapping_area (w, row - 1, TEXT_AREA);
20337
20338 if (MATRIX_ROW_BOTTOM_Y (row) < window_text_bottom_y (w)
20339 && MATRIX_ROW_OVERLAPS_PRED_P (row + 1))
20340 x_fix_overlapping_area (w, row + 1, TEXT_AREA);
20341 }
20342 }
20343 }
20344
20345
20346 /* EXPORT:
20347 Erase the image of a cursor of window W from the screen. */
20348
20349 void
20350 erase_phys_cursor (w)
20351 struct window *w;
20352 {
20353 struct frame *f = XFRAME (w->frame);
20354 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
20355 int hpos = w->phys_cursor.hpos;
20356 int vpos = w->phys_cursor.vpos;
20357 int mouse_face_here_p = 0;
20358 struct glyph_matrix *active_glyphs = w->current_matrix;
20359 struct glyph_row *cursor_row;
20360 struct glyph *cursor_glyph;
20361 enum draw_glyphs_face hl;
20362
20363 /* No cursor displayed or row invalidated => nothing to do on the
20364 screen. */
20365 if (w->phys_cursor_type == NO_CURSOR)
20366 goto mark_cursor_off;
20367
20368 /* VPOS >= active_glyphs->nrows means that window has been resized.
20369 Don't bother to erase the cursor. */
20370 if (vpos >= active_glyphs->nrows)
20371 goto mark_cursor_off;
20372
20373 /* If row containing cursor is marked invalid, there is nothing we
20374 can do. */
20375 cursor_row = MATRIX_ROW (active_glyphs, vpos);
20376 if (!cursor_row->enabled_p)
20377 goto mark_cursor_off;
20378
20379 /* If line spacing is > 0, old cursor may only be partially visible in
20380 window after split-window. So adjust visible height. */
20381 cursor_row->visible_height = min (cursor_row->visible_height,
20382 window_text_bottom_y (w) - cursor_row->y);
20383
20384 /* If row is completely invisible, don't attempt to delete a cursor which
20385 isn't there. This can happen if cursor is at top of a window, and
20386 we switch to a buffer with a header line in that window. */
20387 if (cursor_row->visible_height <= 0)
20388 goto mark_cursor_off;
20389
20390 /* If cursor is in the fringe, erase by drawing actual bitmap there. */
20391 if (cursor_row->cursor_in_fringe_p)
20392 {
20393 cursor_row->cursor_in_fringe_p = 0;
20394 draw_fringe_bitmap (w, cursor_row, 0);
20395 goto mark_cursor_off;
20396 }
20397
20398 /* This can happen when the new row is shorter than the old one.
20399 In this case, either draw_glyphs or clear_end_of_line
20400 should have cleared the cursor. Note that we wouldn't be
20401 able to erase the cursor in this case because we don't have a
20402 cursor glyph at hand. */
20403 if (w->phys_cursor.hpos >= cursor_row->used[TEXT_AREA])
20404 goto mark_cursor_off;
20405
20406 /* If the cursor is in the mouse face area, redisplay that when
20407 we clear the cursor. */
20408 if (! NILP (dpyinfo->mouse_face_window)
20409 && w == XWINDOW (dpyinfo->mouse_face_window)
20410 && (vpos > dpyinfo->mouse_face_beg_row
20411 || (vpos == dpyinfo->mouse_face_beg_row
20412 && hpos >= dpyinfo->mouse_face_beg_col))
20413 && (vpos < dpyinfo->mouse_face_end_row
20414 || (vpos == dpyinfo->mouse_face_end_row
20415 && hpos < dpyinfo->mouse_face_end_col))
20416 /* Don't redraw the cursor's spot in mouse face if it is at the
20417 end of a line (on a newline). The cursor appears there, but
20418 mouse highlighting does not. */
20419 && cursor_row->used[TEXT_AREA] > hpos)
20420 mouse_face_here_p = 1;
20421
20422 /* Maybe clear the display under the cursor. */
20423 if (w->phys_cursor_type == HOLLOW_BOX_CURSOR)
20424 {
20425 int x, y;
20426 int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
20427 int width;
20428
20429 cursor_glyph = get_phys_cursor_glyph (w);
20430 if (cursor_glyph == NULL)
20431 goto mark_cursor_off;
20432
20433 x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
20434 y = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height, cursor_row->y));
20435 width = min (cursor_glyph->pixel_width,
20436 window_box_width (w, TEXT_AREA) - w->phys_cursor.x);
20437
20438 rif->clear_frame_area (f, x, y, width, cursor_row->visible_height);
20439 }
20440
20441 /* Erase the cursor by redrawing the character underneath it. */
20442 if (mouse_face_here_p)
20443 hl = DRAW_MOUSE_FACE;
20444 else
20445 hl = DRAW_NORMAL_TEXT;
20446 draw_phys_cursor_glyph (w, cursor_row, hl);
20447
20448 mark_cursor_off:
20449 w->phys_cursor_on_p = 0;
20450 w->phys_cursor_type = NO_CURSOR;
20451 }
20452
20453
20454 /* EXPORT:
20455 Display or clear cursor of window W. If ON is zero, clear the
20456 cursor. If it is non-zero, display the cursor. If ON is nonzero,
20457 where to put the cursor is specified by HPOS, VPOS, X and Y. */
20458
20459 void
20460 display_and_set_cursor (w, on, hpos, vpos, x, y)
20461 struct window *w;
20462 int on, hpos, vpos, x, y;
20463 {
20464 struct frame *f = XFRAME (w->frame);
20465 int new_cursor_type;
20466 int new_cursor_width;
20467 int active_cursor;
20468 struct glyph_row *glyph_row;
20469 struct glyph *glyph;
20470
20471 /* This is pointless on invisible frames, and dangerous on garbaged
20472 windows and frames; in the latter case, the frame or window may
20473 be in the midst of changing its size, and x and y may be off the
20474 window. */
20475 if (! FRAME_VISIBLE_P (f)
20476 || FRAME_GARBAGED_P (f)
20477 || vpos >= w->current_matrix->nrows
20478 || hpos >= w->current_matrix->matrix_w)
20479 return;
20480
20481 /* If cursor is off and we want it off, return quickly. */
20482 if (!on && !w->phys_cursor_on_p)
20483 return;
20484
20485 glyph_row = MATRIX_ROW (w->current_matrix, vpos);
20486 /* If cursor row is not enabled, we don't really know where to
20487 display the cursor. */
20488 if (!glyph_row->enabled_p)
20489 {
20490 w->phys_cursor_on_p = 0;
20491 return;
20492 }
20493
20494 glyph = NULL;
20495 if (!glyph_row->exact_window_width_line_p
20496 || hpos < glyph_row->used[TEXT_AREA])
20497 glyph = glyph_row->glyphs[TEXT_AREA] + hpos;
20498
20499 xassert (interrupt_input_blocked);
20500
20501 /* Set new_cursor_type to the cursor we want to be displayed. */
20502 new_cursor_type = get_window_cursor_type (w, glyph,
20503 &new_cursor_width, &active_cursor);
20504
20505 /* If cursor is currently being shown and we don't want it to be or
20506 it is in the wrong place, or the cursor type is not what we want,
20507 erase it. */
20508 if (w->phys_cursor_on_p
20509 && (!on
20510 || w->phys_cursor.x != x
20511 || w->phys_cursor.y != y
20512 || new_cursor_type != w->phys_cursor_type
20513 || ((new_cursor_type == BAR_CURSOR || new_cursor_type == HBAR_CURSOR)
20514 && new_cursor_width != w->phys_cursor_width)))
20515 erase_phys_cursor (w);
20516
20517 /* Don't check phys_cursor_on_p here because that flag is only set
20518 to zero in some cases where we know that the cursor has been
20519 completely erased, to avoid the extra work of erasing the cursor
20520 twice. In other words, phys_cursor_on_p can be 1 and the cursor
20521 still not be visible, or it has only been partly erased. */
20522 if (on)
20523 {
20524 w->phys_cursor_ascent = glyph_row->ascent;
20525 w->phys_cursor_height = glyph_row->height;
20526
20527 /* Set phys_cursor_.* before x_draw_.* is called because some
20528 of them may need the information. */
20529 w->phys_cursor.x = x;
20530 w->phys_cursor.y = glyph_row->y;
20531 w->phys_cursor.hpos = hpos;
20532 w->phys_cursor.vpos = vpos;
20533 }
20534
20535 rif->draw_window_cursor (w, glyph_row, x, y,
20536 new_cursor_type, new_cursor_width,
20537 on, active_cursor);
20538 }
20539
20540
20541 /* Switch the display of W's cursor on or off, according to the value
20542 of ON. */
20543
20544 static void
20545 update_window_cursor (w, on)
20546 struct window *w;
20547 int on;
20548 {
20549 /* Don't update cursor in windows whose frame is in the process
20550 of being deleted. */
20551 if (w->current_matrix)
20552 {
20553 BLOCK_INPUT;
20554 display_and_set_cursor (w, on, w->phys_cursor.hpos, w->phys_cursor.vpos,
20555 w->phys_cursor.x, w->phys_cursor.y);
20556 UNBLOCK_INPUT;
20557 }
20558 }
20559
20560
20561 /* Call update_window_cursor with parameter ON_P on all leaf windows
20562 in the window tree rooted at W. */
20563
20564 static void
20565 update_cursor_in_window_tree (w, on_p)
20566 struct window *w;
20567 int on_p;
20568 {
20569 while (w)
20570 {
20571 if (!NILP (w->hchild))
20572 update_cursor_in_window_tree (XWINDOW (w->hchild), on_p);
20573 else if (!NILP (w->vchild))
20574 update_cursor_in_window_tree (XWINDOW (w->vchild), on_p);
20575 else
20576 update_window_cursor (w, on_p);
20577
20578 w = NILP (w->next) ? 0 : XWINDOW (w->next);
20579 }
20580 }
20581
20582
20583 /* EXPORT:
20584 Display the cursor on window W, or clear it, according to ON_P.
20585 Don't change the cursor's position. */
20586
20587 void
20588 x_update_cursor (f, on_p)
20589 struct frame *f;
20590 int on_p;
20591 {
20592 update_cursor_in_window_tree (XWINDOW (f->root_window), on_p);
20593 }
20594
20595
20596 /* EXPORT:
20597 Clear the cursor of window W to background color, and mark the
20598 cursor as not shown. This is used when the text where the cursor
20599 is is about to be rewritten. */
20600
20601 void
20602 x_clear_cursor (w)
20603 struct window *w;
20604 {
20605 if (FRAME_VISIBLE_P (XFRAME (w->frame)) && w->phys_cursor_on_p)
20606 update_window_cursor (w, 0);
20607 }
20608
20609
20610 /* EXPORT:
20611 Display the active region described by mouse_face_* according to DRAW. */
20612
20613 void
20614 show_mouse_face (dpyinfo, draw)
20615 Display_Info *dpyinfo;
20616 enum draw_glyphs_face draw;
20617 {
20618 struct window *w = XWINDOW (dpyinfo->mouse_face_window);
20619 struct frame *f = XFRAME (WINDOW_FRAME (w));
20620
20621 if (/* If window is in the process of being destroyed, don't bother
20622 to do anything. */
20623 w->current_matrix != NULL
20624 /* Don't update mouse highlight if hidden */
20625 && (draw != DRAW_MOUSE_FACE || !dpyinfo->mouse_face_hidden)
20626 /* Recognize when we are called to operate on rows that don't exist
20627 anymore. This can happen when a window is split. */
20628 && dpyinfo->mouse_face_end_row < w->current_matrix->nrows)
20629 {
20630 int phys_cursor_on_p = w->phys_cursor_on_p;
20631 struct glyph_row *row, *first, *last;
20632
20633 first = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_beg_row);
20634 last = MATRIX_ROW (w->current_matrix, dpyinfo->mouse_face_end_row);
20635
20636 for (row = first; row <= last && row->enabled_p; ++row)
20637 {
20638 int start_hpos, end_hpos, start_x;
20639
20640 /* For all but the first row, the highlight starts at column 0. */
20641 if (row == first)
20642 {
20643 start_hpos = dpyinfo->mouse_face_beg_col;
20644 start_x = dpyinfo->mouse_face_beg_x;
20645 }
20646 else
20647 {
20648 start_hpos = 0;
20649 start_x = 0;
20650 }
20651
20652 if (row == last)
20653 end_hpos = dpyinfo->mouse_face_end_col;
20654 else
20655 end_hpos = row->used[TEXT_AREA];
20656
20657 if (end_hpos > start_hpos)
20658 {
20659 draw_glyphs (w, start_x, row, TEXT_AREA,
20660 start_hpos, end_hpos,
20661 draw, 0);
20662
20663 row->mouse_face_p
20664 = draw == DRAW_MOUSE_FACE || draw == DRAW_IMAGE_RAISED;
20665 }
20666 }
20667
20668 /* When we've written over the cursor, arrange for it to
20669 be displayed again. */
20670 if (phys_cursor_on_p && !w->phys_cursor_on_p)
20671 {
20672 BLOCK_INPUT;
20673 display_and_set_cursor (w, 1,
20674 w->phys_cursor.hpos, w->phys_cursor.vpos,
20675 w->phys_cursor.x, w->phys_cursor.y);
20676 UNBLOCK_INPUT;
20677 }
20678 }
20679
20680 /* Change the mouse cursor. */
20681 if (draw == DRAW_NORMAL_TEXT)
20682 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->text_cursor);
20683 else if (draw == DRAW_MOUSE_FACE)
20684 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->hand_cursor);
20685 else
20686 rif->define_frame_cursor (f, FRAME_X_OUTPUT (f)->nontext_cursor);
20687 }
20688
20689 /* EXPORT:
20690 Clear out the mouse-highlighted active region.
20691 Redraw it un-highlighted first. Value is non-zero if mouse
20692 face was actually drawn unhighlighted. */
20693
20694 int
20695 clear_mouse_face (dpyinfo)
20696 Display_Info *dpyinfo;
20697 {
20698 int cleared = 0;
20699
20700 if (!dpyinfo->mouse_face_hidden && !NILP (dpyinfo->mouse_face_window))
20701 {
20702 show_mouse_face (dpyinfo, DRAW_NORMAL_TEXT);
20703 cleared = 1;
20704 }
20705
20706 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
20707 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
20708 dpyinfo->mouse_face_window = Qnil;
20709 dpyinfo->mouse_face_overlay = Qnil;
20710 return cleared;
20711 }
20712
20713
20714 /* EXPORT:
20715 Non-zero if physical cursor of window W is within mouse face. */
20716
20717 int
20718 cursor_in_mouse_face_p (w)
20719 struct window *w;
20720 {
20721 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
20722 int in_mouse_face = 0;
20723
20724 if (WINDOWP (dpyinfo->mouse_face_window)
20725 && XWINDOW (dpyinfo->mouse_face_window) == w)
20726 {
20727 int hpos = w->phys_cursor.hpos;
20728 int vpos = w->phys_cursor.vpos;
20729
20730 if (vpos >= dpyinfo->mouse_face_beg_row
20731 && vpos <= dpyinfo->mouse_face_end_row
20732 && (vpos > dpyinfo->mouse_face_beg_row
20733 || hpos >= dpyinfo->mouse_face_beg_col)
20734 && (vpos < dpyinfo->mouse_face_end_row
20735 || hpos < dpyinfo->mouse_face_end_col
20736 || dpyinfo->mouse_face_past_end))
20737 in_mouse_face = 1;
20738 }
20739
20740 return in_mouse_face;
20741 }
20742
20743
20744
20745 \f
20746 /* Find the glyph matrix position of buffer position CHARPOS in window
20747 *W. HPOS, *VPOS, *X, and *Y are set to the positions found. W's
20748 current glyphs must be up to date. If CHARPOS is above window
20749 start return (0, 0, 0, 0). If CHARPOS is after end of W, return end
20750 of last line in W. In the row containing CHARPOS, stop before glyphs
20751 having STOP as object. */
20752
20753 #if 1 /* This is a version of fast_find_position that's more correct
20754 in the presence of hscrolling, for example. I didn't install
20755 it right away because the problem fixed is minor, it failed
20756 in 20.x as well, and I think it's too risky to install
20757 so near the release of 21.1. 2001-09-25 gerd. */
20758
20759 static int
20760 fast_find_position (w, charpos, hpos, vpos, x, y, stop)
20761 struct window *w;
20762 int charpos;
20763 int *hpos, *vpos, *x, *y;
20764 Lisp_Object stop;
20765 {
20766 struct glyph_row *row, *first;
20767 struct glyph *glyph, *end;
20768 int past_end = 0;
20769
20770 first = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20771 if (charpos < MATRIX_ROW_START_CHARPOS (first))
20772 {
20773 *x = first->x;
20774 *y = first->y;
20775 *hpos = 0;
20776 *vpos = MATRIX_ROW_VPOS (first, w->current_matrix);
20777 return 1;
20778 }
20779
20780 row = row_containing_pos (w, charpos, first, NULL, 0);
20781 if (row == NULL)
20782 {
20783 row = MATRIX_ROW (w->current_matrix, XFASTINT (w->window_end_vpos));
20784 past_end = 1;
20785 }
20786
20787 /* If whole rows or last part of a row came from a display overlay,
20788 row_containing_pos will skip over such rows because their end pos
20789 equals the start pos of the overlay or interval.
20790
20791 Move back if we have a STOP object and previous row's
20792 end glyph came from STOP. */
20793 if (!NILP (stop))
20794 {
20795 struct glyph_row *prev;
20796 while ((prev = row - 1, prev >= first)
20797 && MATRIX_ROW_END_CHARPOS (prev) == charpos
20798 && prev->used[TEXT_AREA] > 0)
20799 {
20800 struct glyph *beg = prev->glyphs[TEXT_AREA];
20801 glyph = beg + prev->used[TEXT_AREA];
20802 while (--glyph >= beg
20803 && INTEGERP (glyph->object));
20804 if (glyph < beg
20805 || !EQ (stop, glyph->object))
20806 break;
20807 row = prev;
20808 }
20809 }
20810
20811 *x = row->x;
20812 *y = row->y;
20813 *vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20814
20815 glyph = row->glyphs[TEXT_AREA];
20816 end = glyph + row->used[TEXT_AREA];
20817
20818 /* Skip over glyphs not having an object at the start of the row.
20819 These are special glyphs like truncation marks on terminal
20820 frames. */
20821 if (row->displays_text_p)
20822 while (glyph < end
20823 && INTEGERP (glyph->object)
20824 && !EQ (stop, glyph->object)
20825 && glyph->charpos < 0)
20826 {
20827 *x += glyph->pixel_width;
20828 ++glyph;
20829 }
20830
20831 while (glyph < end
20832 && !INTEGERP (glyph->object)
20833 && !EQ (stop, glyph->object)
20834 && (!BUFFERP (glyph->object)
20835 || glyph->charpos < charpos))
20836 {
20837 *x += glyph->pixel_width;
20838 ++glyph;
20839 }
20840
20841 *hpos = glyph - row->glyphs[TEXT_AREA];
20842 return !past_end;
20843 }
20844
20845 #else /* not 1 */
20846
20847 static int
20848 fast_find_position (w, pos, hpos, vpos, x, y, stop)
20849 struct window *w;
20850 int pos;
20851 int *hpos, *vpos, *x, *y;
20852 Lisp_Object stop;
20853 {
20854 int i;
20855 int lastcol;
20856 int maybe_next_line_p = 0;
20857 int line_start_position;
20858 int yb = window_text_bottom_y (w);
20859 struct glyph_row *row, *best_row;
20860 int row_vpos, best_row_vpos;
20861 int current_x;
20862
20863 row = best_row = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20864 row_vpos = best_row_vpos = MATRIX_ROW_VPOS (row, w->current_matrix);
20865
20866 while (row->y < yb)
20867 {
20868 if (row->used[TEXT_AREA])
20869 line_start_position = row->glyphs[TEXT_AREA]->charpos;
20870 else
20871 line_start_position = 0;
20872
20873 if (line_start_position > pos)
20874 break;
20875 /* If the position sought is the end of the buffer,
20876 don't include the blank lines at the bottom of the window. */
20877 else if (line_start_position == pos
20878 && pos == BUF_ZV (XBUFFER (w->buffer)))
20879 {
20880 maybe_next_line_p = 1;
20881 break;
20882 }
20883 else if (line_start_position > 0)
20884 {
20885 best_row = row;
20886 best_row_vpos = row_vpos;
20887 }
20888
20889 if (row->y + row->height >= yb)
20890 break;
20891
20892 ++row;
20893 ++row_vpos;
20894 }
20895
20896 /* Find the right column within BEST_ROW. */
20897 lastcol = 0;
20898 current_x = best_row->x;
20899 for (i = 0; i < best_row->used[TEXT_AREA]; i++)
20900 {
20901 struct glyph *glyph = best_row->glyphs[TEXT_AREA] + i;
20902 int charpos = glyph->charpos;
20903
20904 if (BUFFERP (glyph->object))
20905 {
20906 if (charpos == pos)
20907 {
20908 *hpos = i;
20909 *vpos = best_row_vpos;
20910 *x = current_x;
20911 *y = best_row->y;
20912 return 1;
20913 }
20914 else if (charpos > pos)
20915 break;
20916 }
20917 else if (EQ (glyph->object, stop))
20918 break;
20919
20920 if (charpos > 0)
20921 lastcol = i;
20922 current_x += glyph->pixel_width;
20923 }
20924
20925 /* If we're looking for the end of the buffer,
20926 and we didn't find it in the line we scanned,
20927 use the start of the following line. */
20928 if (maybe_next_line_p)
20929 {
20930 ++best_row;
20931 ++best_row_vpos;
20932 lastcol = 0;
20933 current_x = best_row->x;
20934 }
20935
20936 *vpos = best_row_vpos;
20937 *hpos = lastcol + 1;
20938 *x = current_x;
20939 *y = best_row->y;
20940 return 0;
20941 }
20942
20943 #endif /* not 1 */
20944
20945
20946 /* Find the position of the glyph for position POS in OBJECT in
20947 window W's current matrix, and return in *X, *Y the pixel
20948 coordinates, and return in *HPOS, *VPOS the column/row of the glyph.
20949
20950 RIGHT_P non-zero means return the position of the right edge of the
20951 glyph, RIGHT_P zero means return the left edge position.
20952
20953 If no glyph for POS exists in the matrix, return the position of
20954 the glyph with the next smaller position that is in the matrix, if
20955 RIGHT_P is zero. If RIGHT_P is non-zero, and no glyph for POS
20956 exists in the matrix, return the position of the glyph with the
20957 next larger position in OBJECT.
20958
20959 Value is non-zero if a glyph was found. */
20960
20961 static int
20962 fast_find_string_pos (w, pos, object, hpos, vpos, x, y, right_p)
20963 struct window *w;
20964 int pos;
20965 Lisp_Object object;
20966 int *hpos, *vpos, *x, *y;
20967 int right_p;
20968 {
20969 int yb = window_text_bottom_y (w);
20970 struct glyph_row *r;
20971 struct glyph *best_glyph = NULL;
20972 struct glyph_row *best_row = NULL;
20973 int best_x = 0;
20974
20975 for (r = MATRIX_FIRST_TEXT_ROW (w->current_matrix);
20976 r->enabled_p && r->y < yb;
20977 ++r)
20978 {
20979 struct glyph *g = r->glyphs[TEXT_AREA];
20980 struct glyph *e = g + r->used[TEXT_AREA];
20981 int gx;
20982
20983 for (gx = r->x; g < e; gx += g->pixel_width, ++g)
20984 if (EQ (g->object, object))
20985 {
20986 if (g->charpos == pos)
20987 {
20988 best_glyph = g;
20989 best_x = gx;
20990 best_row = r;
20991 goto found;
20992 }
20993 else if (best_glyph == NULL
20994 || ((abs (g->charpos - pos)
20995 < abs (best_glyph->charpos - pos))
20996 && (right_p
20997 ? g->charpos < pos
20998 : g->charpos > pos)))
20999 {
21000 best_glyph = g;
21001 best_x = gx;
21002 best_row = r;
21003 }
21004 }
21005 }
21006
21007 found:
21008
21009 if (best_glyph)
21010 {
21011 *x = best_x;
21012 *hpos = best_glyph - best_row->glyphs[TEXT_AREA];
21013
21014 if (right_p)
21015 {
21016 *x += best_glyph->pixel_width;
21017 ++*hpos;
21018 }
21019
21020 *y = best_row->y;
21021 *vpos = best_row - w->current_matrix->rows;
21022 }
21023
21024 return best_glyph != NULL;
21025 }
21026
21027
21028 /* See if position X, Y is within a hot-spot of an image. */
21029
21030 static int
21031 on_hot_spot_p (hot_spot, x, y)
21032 Lisp_Object hot_spot;
21033 int x, y;
21034 {
21035 if (!CONSP (hot_spot))
21036 return 0;
21037
21038 if (EQ (XCAR (hot_spot), Qrect))
21039 {
21040 /* CDR is (Top-Left . Bottom-Right) = ((x0 . y0) . (x1 . y1)) */
21041 Lisp_Object rect = XCDR (hot_spot);
21042 Lisp_Object tem;
21043 if (!CONSP (rect))
21044 return 0;
21045 if (!CONSP (XCAR (rect)))
21046 return 0;
21047 if (!CONSP (XCDR (rect)))
21048 return 0;
21049 if (!(tem = XCAR (XCAR (rect)), INTEGERP (tem) && x >= XINT (tem)))
21050 return 0;
21051 if (!(tem = XCDR (XCAR (rect)), INTEGERP (tem) && y >= XINT (tem)))
21052 return 0;
21053 if (!(tem = XCAR (XCDR (rect)), INTEGERP (tem) && x <= XINT (tem)))
21054 return 0;
21055 if (!(tem = XCDR (XCDR (rect)), INTEGERP (tem) && y <= XINT (tem)))
21056 return 0;
21057 return 1;
21058 }
21059 else if (EQ (XCAR (hot_spot), Qcircle))
21060 {
21061 /* CDR is (Center . Radius) = ((x0 . y0) . r) */
21062 Lisp_Object circ = XCDR (hot_spot);
21063 Lisp_Object lr, lx0, ly0;
21064 if (CONSP (circ)
21065 && CONSP (XCAR (circ))
21066 && (lr = XCDR (circ), INTEGERP (lr) || FLOATP (lr))
21067 && (lx0 = XCAR (XCAR (circ)), INTEGERP (lx0))
21068 && (ly0 = XCDR (XCAR (circ)), INTEGERP (ly0)))
21069 {
21070 double r = XFLOATINT (lr);
21071 double dx = XINT (lx0) - x;
21072 double dy = XINT (ly0) - y;
21073 return (dx * dx + dy * dy <= r * r);
21074 }
21075 }
21076 else if (EQ (XCAR (hot_spot), Qpoly))
21077 {
21078 /* CDR is [x0 y0 x1 y1 x2 y2 ...x(n-1) y(n-1)] */
21079 if (VECTORP (XCDR (hot_spot)))
21080 {
21081 struct Lisp_Vector *v = XVECTOR (XCDR (hot_spot));
21082 Lisp_Object *poly = v->contents;
21083 int n = v->size;
21084 int i;
21085 int inside = 0;
21086 Lisp_Object lx, ly;
21087 int x0, y0;
21088
21089 /* Need an even number of coordinates, and at least 3 edges. */
21090 if (n < 6 || n & 1)
21091 return 0;
21092
21093 /* Count edge segments intersecting line from (X,Y) to (X,infinity).
21094 If count is odd, we are inside polygon. Pixels on edges
21095 may or may not be included depending on actual geometry of the
21096 polygon. */
21097 if ((lx = poly[n-2], !INTEGERP (lx))
21098 || (ly = poly[n-1], !INTEGERP (lx)))
21099 return 0;
21100 x0 = XINT (lx), y0 = XINT (ly);
21101 for (i = 0; i < n; i += 2)
21102 {
21103 int x1 = x0, y1 = y0;
21104 if ((lx = poly[i], !INTEGERP (lx))
21105 || (ly = poly[i+1], !INTEGERP (ly)))
21106 return 0;
21107 x0 = XINT (lx), y0 = XINT (ly);
21108
21109 /* Does this segment cross the X line? */
21110 if (x0 >= x)
21111 {
21112 if (x1 >= x)
21113 continue;
21114 }
21115 else if (x1 < x)
21116 continue;
21117 if (y > y0 && y > y1)
21118 continue;
21119 if (y < y0 + ((y1 - y0) * (x - x0)) / (x1 - x0))
21120 inside = !inside;
21121 }
21122 return inside;
21123 }
21124 }
21125 /* If we don't understand the format, pretend we're not in the hot-spot. */
21126 return 0;
21127 }
21128
21129 Lisp_Object
21130 find_hot_spot (map, x, y)
21131 Lisp_Object map;
21132 int x, y;
21133 {
21134 while (CONSP (map))
21135 {
21136 if (CONSP (XCAR (map))
21137 && on_hot_spot_p (XCAR (XCAR (map)), x, y))
21138 return XCAR (map);
21139 map = XCDR (map);
21140 }
21141
21142 return Qnil;
21143 }
21144
21145 DEFUN ("lookup-image-map", Flookup_image_map, Slookup_image_map,
21146 3, 3, 0,
21147 doc: /* Lookup in image map MAP coordinates X and Y.
21148 An image map is an alist where each element has the format (AREA ID PLIST).
21149 An AREA is specified as either a rectangle, a circle, or a polygon:
21150 A rectangle is a cons (rect . ((x0 . y0) . (x1 . y1))) specifying the
21151 pixel coordinates of the upper left and bottom right corners.
21152 A circle is a cons (circle . ((x0 . y0) . r)) specifying the center
21153 and the radius of the circle; r may be a float or integer.
21154 A polygon is a cons (poly . [x0 y0 x1 y1 ...]) where each pair in the
21155 vector describes one corner in the polygon.
21156 Returns the alist element for the first matching AREA in MAP. */)
21157 (map, x, y)
21158 Lisp_Object map;
21159 Lisp_Object x, y;
21160 {
21161 if (NILP (map))
21162 return Qnil;
21163
21164 CHECK_NUMBER (x);
21165 CHECK_NUMBER (y);
21166
21167 return find_hot_spot (map, XINT (x), XINT (y));
21168 }
21169
21170
21171 /* Display frame CURSOR, optionally using shape defined by POINTER. */
21172 static void
21173 define_frame_cursor1 (f, cursor, pointer)
21174 struct frame *f;
21175 Cursor cursor;
21176 Lisp_Object pointer;
21177 {
21178 /* Do not change cursor shape while dragging mouse. */
21179 if (!NILP (do_mouse_tracking))
21180 return;
21181
21182 if (!NILP (pointer))
21183 {
21184 if (EQ (pointer, Qarrow))
21185 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21186 else if (EQ (pointer, Qhand))
21187 cursor = FRAME_X_OUTPUT (f)->hand_cursor;
21188 else if (EQ (pointer, Qtext))
21189 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21190 else if (EQ (pointer, intern ("hdrag")))
21191 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21192 #ifdef HAVE_X_WINDOWS
21193 else if (EQ (pointer, intern ("vdrag")))
21194 cursor = FRAME_X_DISPLAY_INFO (f)->vertical_scroll_bar_cursor;
21195 #endif
21196 else if (EQ (pointer, intern ("hourglass")))
21197 cursor = FRAME_X_OUTPUT (f)->hourglass_cursor;
21198 else if (EQ (pointer, Qmodeline))
21199 cursor = FRAME_X_OUTPUT (f)->modeline_cursor;
21200 else
21201 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21202 }
21203
21204 if (cursor != No_Cursor)
21205 rif->define_frame_cursor (f, cursor);
21206 }
21207
21208 /* Take proper action when mouse has moved to the mode or header line
21209 or marginal area AREA of window W, x-position X and y-position Y.
21210 X is relative to the start of the text display area of W, so the
21211 width of bitmap areas and scroll bars must be subtracted to get a
21212 position relative to the start of the mode line. */
21213
21214 static void
21215 note_mode_line_or_margin_highlight (w, x, y, area)
21216 struct window *w;
21217 int x, y;
21218 enum window_part area;
21219 {
21220 struct frame *f = XFRAME (w->frame);
21221 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21222 Cursor cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21223 Lisp_Object pointer = Qnil;
21224 int charpos, dx, dy, width, height;
21225 Lisp_Object string, object = Qnil;
21226 Lisp_Object pos, help;
21227
21228 if (area == ON_MODE_LINE || area == ON_HEADER_LINE)
21229 string = mode_line_string (w, area, &x, &y, &charpos,
21230 &object, &dx, &dy, &width, &height);
21231 else
21232 {
21233 x -= WINDOW_LEFT_SCROLL_BAR_AREA_WIDTH (w);
21234 string = marginal_area_string (w, area, &x, &y, &charpos,
21235 &object, &dx, &dy, &width, &height);
21236 }
21237
21238 help = Qnil;
21239
21240 if (IMAGEP (object))
21241 {
21242 Lisp_Object image_map, hotspot;
21243 if ((image_map = Fplist_get (XCDR (object), QCmap),
21244 !NILP (image_map))
21245 && (hotspot = find_hot_spot (image_map, dx, dy),
21246 CONSP (hotspot))
21247 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21248 {
21249 Lisp_Object area_id, plist;
21250
21251 area_id = XCAR (hotspot);
21252 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21253 If so, we could look for mouse-enter, mouse-leave
21254 properties in PLIST (and do something...). */
21255 hotspot = XCDR (hotspot);
21256 if (CONSP (hotspot)
21257 && (plist = XCAR (hotspot), CONSP (plist)))
21258 {
21259 pointer = Fplist_get (plist, Qpointer);
21260 if (NILP (pointer))
21261 pointer = Qhand;
21262 help = Fplist_get (plist, Qhelp_echo);
21263 if (!NILP (help))
21264 {
21265 help_echo_string = help;
21266 /* Is this correct? ++kfs */
21267 XSETWINDOW (help_echo_window, w);
21268 help_echo_object = w->buffer;
21269 help_echo_pos = charpos;
21270 }
21271 }
21272 }
21273 if (NILP (pointer))
21274 pointer = Fplist_get (XCDR (object), QCpointer);
21275 }
21276
21277 if (STRINGP (string))
21278 {
21279 pos = make_number (charpos);
21280 /* If we're on a string with `help-echo' text property, arrange
21281 for the help to be displayed. This is done by setting the
21282 global variable help_echo_string to the help string. */
21283 if (NILP (help))
21284 {
21285 help = Fget_text_property (pos, Qhelp_echo, string);
21286 if (!NILP (help))
21287 {
21288 help_echo_string = help;
21289 XSETWINDOW (help_echo_window, w);
21290 help_echo_object = string;
21291 help_echo_pos = charpos;
21292 }
21293 }
21294
21295 if (NILP (pointer))
21296 pointer = Fget_text_property (pos, Qpointer, string);
21297
21298 /* Change the mouse pointer according to what is under X/Y. */
21299 if (NILP (pointer) && ((area == ON_MODE_LINE) || (area == ON_HEADER_LINE)))
21300 {
21301 Lisp_Object map;
21302 map = Fget_text_property (pos, Qlocal_map, string);
21303 if (!KEYMAPP (map))
21304 map = Fget_text_property (pos, Qkeymap, string);
21305 if (!KEYMAPP (map))
21306 cursor = dpyinfo->vertical_scroll_bar_cursor;
21307 }
21308 }
21309
21310 define_frame_cursor1 (f, cursor, pointer);
21311 }
21312
21313
21314 /* EXPORT:
21315 Take proper action when the mouse has moved to position X, Y on
21316 frame F as regards highlighting characters that have mouse-face
21317 properties. Also de-highlighting chars where the mouse was before.
21318 X and Y can be negative or out of range. */
21319
21320 void
21321 note_mouse_highlight (f, x, y)
21322 struct frame *f;
21323 int x, y;
21324 {
21325 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21326 enum window_part part;
21327 Lisp_Object window;
21328 struct window *w;
21329 Cursor cursor = No_Cursor;
21330 Lisp_Object pointer = Qnil; /* Takes precedence over cursor! */
21331 struct buffer *b;
21332
21333 /* When a menu is active, don't highlight because this looks odd. */
21334 #if defined (USE_X_TOOLKIT) || defined (USE_GTK) || defined (HAVE_NTGUI)
21335 if (popup_activated ())
21336 return;
21337 #endif
21338
21339 if (NILP (Vmouse_highlight)
21340 || !f->glyphs_initialized_p)
21341 return;
21342
21343 dpyinfo->mouse_face_mouse_x = x;
21344 dpyinfo->mouse_face_mouse_y = y;
21345 dpyinfo->mouse_face_mouse_frame = f;
21346
21347 if (dpyinfo->mouse_face_defer)
21348 return;
21349
21350 if (gc_in_progress)
21351 {
21352 dpyinfo->mouse_face_deferred_gc = 1;
21353 return;
21354 }
21355
21356 /* Which window is that in? */
21357 window = window_from_coordinates (f, x, y, &part, 0, 0, 1);
21358
21359 /* If we were displaying active text in another window, clear that.
21360 Also clear if we move out of text area in same window. */
21361 if (! EQ (window, dpyinfo->mouse_face_window)
21362 || (part != ON_TEXT && !NILP (dpyinfo->mouse_face_window)))
21363 clear_mouse_face (dpyinfo);
21364
21365 /* Not on a window -> return. */
21366 if (!WINDOWP (window))
21367 return;
21368
21369 /* Reset help_echo_string. It will get recomputed below. */
21370 help_echo_string = Qnil;
21371
21372 /* Convert to window-relative pixel coordinates. */
21373 w = XWINDOW (window);
21374 frame_to_window_pixel_xy (w, &x, &y);
21375
21376 /* Handle tool-bar window differently since it doesn't display a
21377 buffer. */
21378 if (EQ (window, f->tool_bar_window))
21379 {
21380 note_tool_bar_highlight (f, x, y);
21381 return;
21382 }
21383
21384 /* Mouse is on the mode, header line or margin? */
21385 if (part == ON_MODE_LINE || part == ON_HEADER_LINE
21386 || part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN)
21387 {
21388 note_mode_line_or_margin_highlight (w, x, y, part);
21389 return;
21390 }
21391
21392 if (part == ON_VERTICAL_BORDER)
21393 cursor = FRAME_X_OUTPUT (f)->horizontal_drag_cursor;
21394 else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE
21395 || part == ON_SCROLL_BAR)
21396 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21397 else
21398 cursor = FRAME_X_OUTPUT (f)->text_cursor;
21399
21400 /* Are we in a window whose display is up to date?
21401 And verify the buffer's text has not changed. */
21402 b = XBUFFER (w->buffer);
21403 if (part == ON_TEXT
21404 && EQ (w->window_end_valid, w->buffer)
21405 && XFASTINT (w->last_modified) == BUF_MODIFF (b)
21406 && XFASTINT (w->last_overlay_modified) == BUF_OVERLAY_MODIFF (b))
21407 {
21408 int hpos, vpos, pos, i, dx, dy, area;
21409 struct glyph *glyph;
21410 Lisp_Object object;
21411 Lisp_Object mouse_face = Qnil, overlay = Qnil, position;
21412 Lisp_Object *overlay_vec = NULL;
21413 int noverlays;
21414 struct buffer *obuf;
21415 int obegv, ozv, same_region;
21416
21417 /* Find the glyph under X/Y. */
21418 glyph = x_y_to_hpos_vpos (w, x, y, &hpos, &vpos, &dx, &dy, &area);
21419
21420 /* Look for :pointer property on image. */
21421 if (glyph != NULL && glyph->type == IMAGE_GLYPH)
21422 {
21423 struct image *img = IMAGE_FROM_ID (f, glyph->u.img_id);
21424 if (img != NULL && IMAGEP (img->spec))
21425 {
21426 Lisp_Object image_map, hotspot;
21427 if ((image_map = Fplist_get (XCDR (img->spec), QCmap),
21428 !NILP (image_map))
21429 && (hotspot = find_hot_spot (image_map,
21430 glyph->slice.x + dx,
21431 glyph->slice.y + dy),
21432 CONSP (hotspot))
21433 && (hotspot = XCDR (hotspot), CONSP (hotspot)))
21434 {
21435 Lisp_Object area_id, plist;
21436
21437 area_id = XCAR (hotspot);
21438 /* Could check AREA_ID to see if we enter/leave this hot-spot.
21439 If so, we could look for mouse-enter, mouse-leave
21440 properties in PLIST (and do something...). */
21441 hotspot = XCDR (hotspot);
21442 if (CONSP (hotspot)
21443 && (plist = XCAR (hotspot), CONSP (plist)))
21444 {
21445 pointer = Fplist_get (plist, Qpointer);
21446 if (NILP (pointer))
21447 pointer = Qhand;
21448 help_echo_string = Fplist_get (plist, Qhelp_echo);
21449 if (!NILP (help_echo_string))
21450 {
21451 help_echo_window = window;
21452 help_echo_object = glyph->object;
21453 help_echo_pos = glyph->charpos;
21454 }
21455 }
21456 }
21457 if (NILP (pointer))
21458 pointer = Fplist_get (XCDR (img->spec), QCpointer);
21459 }
21460 }
21461
21462 /* Clear mouse face if X/Y not over text. */
21463 if (glyph == NULL
21464 || area != TEXT_AREA
21465 || !MATRIX_ROW (w->current_matrix, vpos)->displays_text_p)
21466 {
21467 if (clear_mouse_face (dpyinfo))
21468 cursor = No_Cursor;
21469 if (NILP (pointer))
21470 {
21471 if (area != TEXT_AREA)
21472 cursor = FRAME_X_OUTPUT (f)->nontext_cursor;
21473 else
21474 pointer = Vvoid_text_area_pointer;
21475 }
21476 goto set_cursor;
21477 }
21478
21479 pos = glyph->charpos;
21480 object = glyph->object;
21481 if (!STRINGP (object) && !BUFFERP (object))
21482 goto set_cursor;
21483
21484 /* If we get an out-of-range value, return now; avoid an error. */
21485 if (BUFFERP (object) && pos > BUF_Z (b))
21486 goto set_cursor;
21487
21488 /* Make the window's buffer temporarily current for
21489 overlays_at and compute_char_face. */
21490 obuf = current_buffer;
21491 current_buffer = b;
21492 obegv = BEGV;
21493 ozv = ZV;
21494 BEGV = BEG;
21495 ZV = Z;
21496
21497 /* Is this char mouse-active or does it have help-echo? */
21498 position = make_number (pos);
21499
21500 if (BUFFERP (object))
21501 {
21502 /* Put all the overlays we want in a vector in overlay_vec. */
21503 GET_OVERLAYS_AT (pos, overlay_vec, noverlays, NULL, 0);
21504 /* Sort overlays into increasing priority order. */
21505 noverlays = sort_overlays (overlay_vec, noverlays, w);
21506 }
21507 else
21508 noverlays = 0;
21509
21510 same_region = (EQ (window, dpyinfo->mouse_face_window)
21511 && vpos >= dpyinfo->mouse_face_beg_row
21512 && vpos <= dpyinfo->mouse_face_end_row
21513 && (vpos > dpyinfo->mouse_face_beg_row
21514 || hpos >= dpyinfo->mouse_face_beg_col)
21515 && (vpos < dpyinfo->mouse_face_end_row
21516 || hpos < dpyinfo->mouse_face_end_col
21517 || dpyinfo->mouse_face_past_end));
21518
21519 if (same_region)
21520 cursor = No_Cursor;
21521
21522 /* Check mouse-face highlighting. */
21523 if (! same_region
21524 /* If there exists an overlay with mouse-face overlapping
21525 the one we are currently highlighting, we have to
21526 check if we enter the overlapping overlay, and then
21527 highlight only that. */
21528 || (OVERLAYP (dpyinfo->mouse_face_overlay)
21529 && mouse_face_overlay_overlaps (dpyinfo->mouse_face_overlay)))
21530 {
21531 /* Find the highest priority overlay that has a mouse-face
21532 property. */
21533 overlay = Qnil;
21534 for (i = noverlays - 1; i >= 0 && NILP (overlay); --i)
21535 {
21536 mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
21537 if (!NILP (mouse_face))
21538 overlay = overlay_vec[i];
21539 }
21540
21541 /* If we're actually highlighting the same overlay as
21542 before, there's no need to do that again. */
21543 if (!NILP (overlay)
21544 && EQ (overlay, dpyinfo->mouse_face_overlay))
21545 goto check_help_echo;
21546
21547 dpyinfo->mouse_face_overlay = overlay;
21548
21549 /* Clear the display of the old active region, if any. */
21550 if (clear_mouse_face (dpyinfo))
21551 cursor = No_Cursor;
21552
21553 /* If no overlay applies, get a text property. */
21554 if (NILP (overlay))
21555 mouse_face = Fget_text_property (position, Qmouse_face, object);
21556
21557 /* Handle the overlay case. */
21558 if (!NILP (overlay))
21559 {
21560 /* Find the range of text around this char that
21561 should be active. */
21562 Lisp_Object before, after;
21563 int ignore;
21564
21565 before = Foverlay_start (overlay);
21566 after = Foverlay_end (overlay);
21567 /* Record this as the current active region. */
21568 fast_find_position (w, XFASTINT (before),
21569 &dpyinfo->mouse_face_beg_col,
21570 &dpyinfo->mouse_face_beg_row,
21571 &dpyinfo->mouse_face_beg_x,
21572 &dpyinfo->mouse_face_beg_y, Qnil);
21573
21574 dpyinfo->mouse_face_past_end
21575 = !fast_find_position (w, XFASTINT (after),
21576 &dpyinfo->mouse_face_end_col,
21577 &dpyinfo->mouse_face_end_row,
21578 &dpyinfo->mouse_face_end_x,
21579 &dpyinfo->mouse_face_end_y, Qnil);
21580 dpyinfo->mouse_face_window = window;
21581
21582 dpyinfo->mouse_face_face_id
21583 = face_at_buffer_position (w, pos, 0, 0,
21584 &ignore, pos + 1,
21585 !dpyinfo->mouse_face_hidden);
21586
21587 /* Display it as active. */
21588 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21589 cursor = No_Cursor;
21590 }
21591 /* Handle the text property case. */
21592 else if (!NILP (mouse_face) && BUFFERP (object))
21593 {
21594 /* Find the range of text around this char that
21595 should be active. */
21596 Lisp_Object before, after, beginning, end;
21597 int ignore;
21598
21599 beginning = Fmarker_position (w->start);
21600 end = make_number (BUF_Z (XBUFFER (object))
21601 - XFASTINT (w->window_end_pos));
21602 before
21603 = Fprevious_single_property_change (make_number (pos + 1),
21604 Qmouse_face,
21605 object, beginning);
21606 after
21607 = Fnext_single_property_change (position, Qmouse_face,
21608 object, end);
21609
21610 /* Record this as the current active region. */
21611 fast_find_position (w, XFASTINT (before),
21612 &dpyinfo->mouse_face_beg_col,
21613 &dpyinfo->mouse_face_beg_row,
21614 &dpyinfo->mouse_face_beg_x,
21615 &dpyinfo->mouse_face_beg_y, Qnil);
21616 dpyinfo->mouse_face_past_end
21617 = !fast_find_position (w, XFASTINT (after),
21618 &dpyinfo->mouse_face_end_col,
21619 &dpyinfo->mouse_face_end_row,
21620 &dpyinfo->mouse_face_end_x,
21621 &dpyinfo->mouse_face_end_y, Qnil);
21622 dpyinfo->mouse_face_window = window;
21623
21624 if (BUFFERP (object))
21625 dpyinfo->mouse_face_face_id
21626 = face_at_buffer_position (w, pos, 0, 0,
21627 &ignore, pos + 1,
21628 !dpyinfo->mouse_face_hidden);
21629
21630 /* Display it as active. */
21631 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21632 cursor = No_Cursor;
21633 }
21634 else if (!NILP (mouse_face) && STRINGP (object))
21635 {
21636 Lisp_Object b, e;
21637 int ignore;
21638
21639 b = Fprevious_single_property_change (make_number (pos + 1),
21640 Qmouse_face,
21641 object, Qnil);
21642 e = Fnext_single_property_change (position, Qmouse_face,
21643 object, Qnil);
21644 if (NILP (b))
21645 b = make_number (0);
21646 if (NILP (e))
21647 e = make_number (SCHARS (object) - 1);
21648 fast_find_string_pos (w, XINT (b), object,
21649 &dpyinfo->mouse_face_beg_col,
21650 &dpyinfo->mouse_face_beg_row,
21651 &dpyinfo->mouse_face_beg_x,
21652 &dpyinfo->mouse_face_beg_y, 0);
21653 fast_find_string_pos (w, XINT (e), object,
21654 &dpyinfo->mouse_face_end_col,
21655 &dpyinfo->mouse_face_end_row,
21656 &dpyinfo->mouse_face_end_x,
21657 &dpyinfo->mouse_face_end_y, 1);
21658 dpyinfo->mouse_face_past_end = 0;
21659 dpyinfo->mouse_face_window = window;
21660 dpyinfo->mouse_face_face_id
21661 = face_at_string_position (w, object, pos, 0, 0, 0, &ignore,
21662 glyph->face_id, 1);
21663 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21664 cursor = No_Cursor;
21665 }
21666 else if (STRINGP (object) && NILP (mouse_face))
21667 {
21668 /* A string which doesn't have mouse-face, but
21669 the text ``under'' it might have. */
21670 struct glyph_row *r = MATRIX_ROW (w->current_matrix, vpos);
21671 int start = MATRIX_ROW_START_CHARPOS (r);
21672
21673 pos = string_buffer_position (w, object, start);
21674 if (pos > 0)
21675 mouse_face = get_char_property_and_overlay (make_number (pos),
21676 Qmouse_face,
21677 w->buffer,
21678 &overlay);
21679 if (!NILP (mouse_face) && !NILP (overlay))
21680 {
21681 Lisp_Object before = Foverlay_start (overlay);
21682 Lisp_Object after = Foverlay_end (overlay);
21683 int ignore;
21684
21685 /* Note that we might not be able to find position
21686 BEFORE in the glyph matrix if the overlay is
21687 entirely covered by a `display' property. In
21688 this case, we overshoot. So let's stop in
21689 the glyph matrix before glyphs for OBJECT. */
21690 fast_find_position (w, XFASTINT (before),
21691 &dpyinfo->mouse_face_beg_col,
21692 &dpyinfo->mouse_face_beg_row,
21693 &dpyinfo->mouse_face_beg_x,
21694 &dpyinfo->mouse_face_beg_y,
21695 object);
21696
21697 dpyinfo->mouse_face_past_end
21698 = !fast_find_position (w, XFASTINT (after),
21699 &dpyinfo->mouse_face_end_col,
21700 &dpyinfo->mouse_face_end_row,
21701 &dpyinfo->mouse_face_end_x,
21702 &dpyinfo->mouse_face_end_y,
21703 Qnil);
21704 dpyinfo->mouse_face_window = window;
21705 dpyinfo->mouse_face_face_id
21706 = face_at_buffer_position (w, pos, 0, 0,
21707 &ignore, pos + 1,
21708 !dpyinfo->mouse_face_hidden);
21709
21710 /* Display it as active. */
21711 show_mouse_face (dpyinfo, DRAW_MOUSE_FACE);
21712 cursor = No_Cursor;
21713 }
21714 }
21715 }
21716
21717 check_help_echo:
21718
21719 /* Look for a `help-echo' property. */
21720 if (NILP (help_echo_string)) {
21721 Lisp_Object help, overlay;
21722
21723 /* Check overlays first. */
21724 help = overlay = Qnil;
21725 for (i = noverlays - 1; i >= 0 && NILP (help); --i)
21726 {
21727 overlay = overlay_vec[i];
21728 help = Foverlay_get (overlay, Qhelp_echo);
21729 }
21730
21731 if (!NILP (help))
21732 {
21733 help_echo_string = help;
21734 help_echo_window = window;
21735 help_echo_object = overlay;
21736 help_echo_pos = pos;
21737 }
21738 else
21739 {
21740 Lisp_Object object = glyph->object;
21741 int charpos = glyph->charpos;
21742
21743 /* Try text properties. */
21744 if (STRINGP (object)
21745 && charpos >= 0
21746 && charpos < SCHARS (object))
21747 {
21748 help = Fget_text_property (make_number (charpos),
21749 Qhelp_echo, object);
21750 if (NILP (help))
21751 {
21752 /* If the string itself doesn't specify a help-echo,
21753 see if the buffer text ``under'' it does. */
21754 struct glyph_row *r
21755 = MATRIX_ROW (w->current_matrix, vpos);
21756 int start = MATRIX_ROW_START_CHARPOS (r);
21757 int pos = string_buffer_position (w, object, start);
21758 if (pos > 0)
21759 {
21760 help = Fget_char_property (make_number (pos),
21761 Qhelp_echo, w->buffer);
21762 if (!NILP (help))
21763 {
21764 charpos = pos;
21765 object = w->buffer;
21766 }
21767 }
21768 }
21769 }
21770 else if (BUFFERP (object)
21771 && charpos >= BEGV
21772 && charpos < ZV)
21773 help = Fget_text_property (make_number (charpos), Qhelp_echo,
21774 object);
21775
21776 if (!NILP (help))
21777 {
21778 help_echo_string = help;
21779 help_echo_window = window;
21780 help_echo_object = object;
21781 help_echo_pos = charpos;
21782 }
21783 }
21784 }
21785
21786 /* Look for a `pointer' property. */
21787 if (NILP (pointer))
21788 {
21789 /* Check overlays first. */
21790 for (i = noverlays - 1; i >= 0 && NILP (pointer); --i)
21791 pointer = Foverlay_get (overlay_vec[i], Qpointer);
21792
21793 if (NILP (pointer))
21794 {
21795 Lisp_Object object = glyph->object;
21796 int charpos = glyph->charpos;
21797
21798 /* Try text properties. */
21799 if (STRINGP (object)
21800 && charpos >= 0
21801 && charpos < SCHARS (object))
21802 {
21803 pointer = Fget_text_property (make_number (charpos),
21804 Qpointer, object);
21805 if (NILP (pointer))
21806 {
21807 /* If the string itself doesn't specify a pointer,
21808 see if the buffer text ``under'' it does. */
21809 struct glyph_row *r
21810 = MATRIX_ROW (w->current_matrix, vpos);
21811 int start = MATRIX_ROW_START_CHARPOS (r);
21812 int pos = string_buffer_position (w, object, start);
21813 if (pos > 0)
21814 pointer = Fget_char_property (make_number (pos),
21815 Qpointer, w->buffer);
21816 }
21817 }
21818 else if (BUFFERP (object)
21819 && charpos >= BEGV
21820 && charpos < ZV)
21821 pointer = Fget_text_property (make_number (charpos),
21822 Qpointer, object);
21823 }
21824 }
21825
21826 BEGV = obegv;
21827 ZV = ozv;
21828 current_buffer = obuf;
21829 }
21830
21831 set_cursor:
21832
21833 define_frame_cursor1 (f, cursor, pointer);
21834 }
21835
21836
21837 /* EXPORT for RIF:
21838 Clear any mouse-face on window W. This function is part of the
21839 redisplay interface, and is called from try_window_id and similar
21840 functions to ensure the mouse-highlight is off. */
21841
21842 void
21843 x_clear_window_mouse_face (w)
21844 struct window *w;
21845 {
21846 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
21847 Lisp_Object window;
21848
21849 BLOCK_INPUT;
21850 XSETWINDOW (window, w);
21851 if (EQ (window, dpyinfo->mouse_face_window))
21852 clear_mouse_face (dpyinfo);
21853 UNBLOCK_INPUT;
21854 }
21855
21856
21857 /* EXPORT:
21858 Just discard the mouse face information for frame F, if any.
21859 This is used when the size of F is changed. */
21860
21861 void
21862 cancel_mouse_face (f)
21863 struct frame *f;
21864 {
21865 Lisp_Object window;
21866 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
21867
21868 window = dpyinfo->mouse_face_window;
21869 if (! NILP (window) && XFRAME (XWINDOW (window)->frame) == f)
21870 {
21871 dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
21872 dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
21873 dpyinfo->mouse_face_window = Qnil;
21874 }
21875 }
21876
21877
21878 #endif /* HAVE_WINDOW_SYSTEM */
21879
21880 \f
21881 /***********************************************************************
21882 Exposure Events
21883 ***********************************************************************/
21884
21885 #ifdef HAVE_WINDOW_SYSTEM
21886
21887 /* Redraw the part of glyph row area AREA of glyph row ROW on window W
21888 which intersects rectangle R. R is in window-relative coordinates. */
21889
21890 static void
21891 expose_area (w, row, r, area)
21892 struct window *w;
21893 struct glyph_row *row;
21894 XRectangle *r;
21895 enum glyph_row_area area;
21896 {
21897 struct glyph *first = row->glyphs[area];
21898 struct glyph *end = row->glyphs[area] + row->used[area];
21899 struct glyph *last;
21900 int first_x, start_x, x;
21901
21902 if (area == TEXT_AREA && row->fill_line_p)
21903 /* If row extends face to end of line write the whole line. */
21904 draw_glyphs (w, 0, row, area,
21905 0, row->used[area],
21906 DRAW_NORMAL_TEXT, 0);
21907 else
21908 {
21909 /* Set START_X to the window-relative start position for drawing glyphs of
21910 AREA. The first glyph of the text area can be partially visible.
21911 The first glyphs of other areas cannot. */
21912 start_x = window_box_left_offset (w, area);
21913 x = start_x;
21914 if (area == TEXT_AREA)
21915 x += row->x;
21916
21917 /* Find the first glyph that must be redrawn. */
21918 while (first < end
21919 && x + first->pixel_width < r->x)
21920 {
21921 x += first->pixel_width;
21922 ++first;
21923 }
21924
21925 /* Find the last one. */
21926 last = first;
21927 first_x = x;
21928 while (last < end
21929 && x < r->x + r->width)
21930 {
21931 x += last->pixel_width;
21932 ++last;
21933 }
21934
21935 /* Repaint. */
21936 if (last > first)
21937 draw_glyphs (w, first_x - start_x, row, area,
21938 first - row->glyphs[area], last - row->glyphs[area],
21939 DRAW_NORMAL_TEXT, 0);
21940 }
21941 }
21942
21943
21944 /* Redraw the parts of the glyph row ROW on window W intersecting
21945 rectangle R. R is in window-relative coordinates. Value is
21946 non-zero if mouse-face was overwritten. */
21947
21948 static int
21949 expose_line (w, row, r)
21950 struct window *w;
21951 struct glyph_row *row;
21952 XRectangle *r;
21953 {
21954 xassert (row->enabled_p);
21955
21956 if (row->mode_line_p || w->pseudo_window_p)
21957 draw_glyphs (w, 0, row, TEXT_AREA,
21958 0, row->used[TEXT_AREA],
21959 DRAW_NORMAL_TEXT, 0);
21960 else
21961 {
21962 if (row->used[LEFT_MARGIN_AREA])
21963 expose_area (w, row, r, LEFT_MARGIN_AREA);
21964 if (row->used[TEXT_AREA])
21965 expose_area (w, row, r, TEXT_AREA);
21966 if (row->used[RIGHT_MARGIN_AREA])
21967 expose_area (w, row, r, RIGHT_MARGIN_AREA);
21968 draw_row_fringe_bitmaps (w, row);
21969 }
21970
21971 return row->mouse_face_p;
21972 }
21973
21974
21975 /* Redraw those parts of glyphs rows during expose event handling that
21976 overlap other rows. Redrawing of an exposed line writes over parts
21977 of lines overlapping that exposed line; this function fixes that.
21978
21979 W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
21980 row in W's current matrix that is exposed and overlaps other rows.
21981 LAST_OVERLAPPING_ROW is the last such row. */
21982
21983 static void
21984 expose_overlaps (w, first_overlapping_row, last_overlapping_row)
21985 struct window *w;
21986 struct glyph_row *first_overlapping_row;
21987 struct glyph_row *last_overlapping_row;
21988 {
21989 struct glyph_row *row;
21990
21991 for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
21992 if (row->overlapping_p)
21993 {
21994 xassert (row->enabled_p && !row->mode_line_p);
21995
21996 if (row->used[LEFT_MARGIN_AREA])
21997 x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
21998
21999 if (row->used[TEXT_AREA])
22000 x_fix_overlapping_area (w, row, TEXT_AREA);
22001
22002 if (row->used[RIGHT_MARGIN_AREA])
22003 x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
22004 }
22005 }
22006
22007
22008 /* Return non-zero if W's cursor intersects rectangle R. */
22009
22010 static int
22011 phys_cursor_in_rect_p (w, r)
22012 struct window *w;
22013 XRectangle *r;
22014 {
22015 XRectangle cr, result;
22016 struct glyph *cursor_glyph;
22017
22018 cursor_glyph = get_phys_cursor_glyph (w);
22019 if (cursor_glyph)
22020 {
22021 /* r is relative to W's box, but w->phys_cursor.x is relative
22022 to left edge of W's TEXT area. Adjust it. */
22023 cr.x = window_box_left_offset (w, TEXT_AREA) + w->phys_cursor.x;
22024 cr.y = w->phys_cursor.y;
22025 cr.width = cursor_glyph->pixel_width;
22026 cr.height = w->phys_cursor_height;
22027 /* ++KFS: W32 version used W32-specific IntersectRect here, but
22028 I assume the effect is the same -- and this is portable. */
22029 return x_intersect_rectangles (&cr, r, &result);
22030 }
22031 else
22032 return 0;
22033 }
22034
22035
22036 /* EXPORT:
22037 Draw a vertical window border to the right of window W if W doesn't
22038 have vertical scroll bars. */
22039
22040 void
22041 x_draw_vertical_border (w)
22042 struct window *w;
22043 {
22044 /* We could do better, if we knew what type of scroll-bar the adjacent
22045 windows (on either side) have... But we don't :-(
22046 However, I think this works ok. ++KFS 2003-04-25 */
22047
22048 /* Redraw borders between horizontally adjacent windows. Don't
22049 do it for frames with vertical scroll bars because either the
22050 right scroll bar of a window, or the left scroll bar of its
22051 neighbor will suffice as a border. */
22052 if (FRAME_HAS_VERTICAL_SCROLL_BARS (XFRAME (w->frame)))
22053 return;
22054
22055 if (!WINDOW_RIGHTMOST_P (w)
22056 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
22057 {
22058 int x0, x1, y0, y1;
22059
22060 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22061 y1 -= 1;
22062
22063 rif->draw_vertical_window_border (w, x1, y0, y1);
22064 }
22065 else if (!WINDOW_LEFTMOST_P (w)
22066 && !WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
22067 {
22068 int x0, x1, y0, y1;
22069
22070 window_box_edges (w, -1, &x0, &y0, &x1, &y1);
22071 y1 -= 1;
22072
22073 rif->draw_vertical_window_border (w, x0, y0, y1);
22074 }
22075 }
22076
22077
22078 /* Redraw the part of window W intersection rectangle FR. Pixel
22079 coordinates in FR are frame-relative. Call this function with
22080 input blocked. Value is non-zero if the exposure overwrites
22081 mouse-face. */
22082
22083 static int
22084 expose_window (w, fr)
22085 struct window *w;
22086 XRectangle *fr;
22087 {
22088 struct frame *f = XFRAME (w->frame);
22089 XRectangle wr, r;
22090 int mouse_face_overwritten_p = 0;
22091
22092 /* If window is not yet fully initialized, do nothing. This can
22093 happen when toolkit scroll bars are used and a window is split.
22094 Reconfiguring the scroll bar will generate an expose for a newly
22095 created window. */
22096 if (w->current_matrix == NULL)
22097 return 0;
22098
22099 /* When we're currently updating the window, display and current
22100 matrix usually don't agree. Arrange for a thorough display
22101 later. */
22102 if (w == updated_window)
22103 {
22104 SET_FRAME_GARBAGED (f);
22105 return 0;
22106 }
22107
22108 /* Frame-relative pixel rectangle of W. */
22109 wr.x = WINDOW_LEFT_EDGE_X (w);
22110 wr.y = WINDOW_TOP_EDGE_Y (w);
22111 wr.width = WINDOW_TOTAL_WIDTH (w);
22112 wr.height = WINDOW_TOTAL_HEIGHT (w);
22113
22114 if (x_intersect_rectangles (fr, &wr, &r))
22115 {
22116 int yb = window_text_bottom_y (w);
22117 struct glyph_row *row;
22118 int cursor_cleared_p;
22119 struct glyph_row *first_overlapping_row, *last_overlapping_row;
22120
22121 TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
22122 r.x, r.y, r.width, r.height));
22123
22124 /* Convert to window coordinates. */
22125 r.x -= WINDOW_LEFT_EDGE_X (w);
22126 r.y -= WINDOW_TOP_EDGE_Y (w);
22127
22128 /* Turn off the cursor. */
22129 if (!w->pseudo_window_p
22130 && phys_cursor_in_rect_p (w, &r))
22131 {
22132 x_clear_cursor (w);
22133 cursor_cleared_p = 1;
22134 }
22135 else
22136 cursor_cleared_p = 0;
22137
22138 /* Update lines intersecting rectangle R. */
22139 first_overlapping_row = last_overlapping_row = NULL;
22140 for (row = w->current_matrix->rows;
22141 row->enabled_p;
22142 ++row)
22143 {
22144 int y0 = row->y;
22145 int y1 = MATRIX_ROW_BOTTOM_Y (row);
22146
22147 if ((y0 >= r.y && y0 < r.y + r.height)
22148 || (y1 > r.y && y1 < r.y + r.height)
22149 || (r.y >= y0 && r.y < y1)
22150 || (r.y + r.height > y0 && r.y + r.height < y1))
22151 {
22152 /* A header line may be overlapping, but there is no need
22153 to fix overlapping areas for them. KFS 2005-02-12 */
22154 if (row->overlapping_p && !row->mode_line_p)
22155 {
22156 if (first_overlapping_row == NULL)
22157 first_overlapping_row = row;
22158 last_overlapping_row = row;
22159 }
22160
22161 if (expose_line (w, row, &r))
22162 mouse_face_overwritten_p = 1;
22163 }
22164
22165 if (y1 >= yb)
22166 break;
22167 }
22168
22169 /* Display the mode line if there is one. */
22170 if (WINDOW_WANTS_MODELINE_P (w)
22171 && (row = MATRIX_MODE_LINE_ROW (w->current_matrix),
22172 row->enabled_p)
22173 && row->y < r.y + r.height)
22174 {
22175 if (expose_line (w, row, &r))
22176 mouse_face_overwritten_p = 1;
22177 }
22178
22179 if (!w->pseudo_window_p)
22180 {
22181 /* Fix the display of overlapping rows. */
22182 if (first_overlapping_row)
22183 expose_overlaps (w, first_overlapping_row, last_overlapping_row);
22184
22185 /* Draw border between windows. */
22186 x_draw_vertical_border (w);
22187
22188 /* Turn the cursor on again. */
22189 if (cursor_cleared_p)
22190 update_window_cursor (w, 1);
22191 }
22192 }
22193
22194 return mouse_face_overwritten_p;
22195 }
22196
22197
22198
22199 /* Redraw (parts) of all windows in the window tree rooted at W that
22200 intersect R. R contains frame pixel coordinates. Value is
22201 non-zero if the exposure overwrites mouse-face. */
22202
22203 static int
22204 expose_window_tree (w, r)
22205 struct window *w;
22206 XRectangle *r;
22207 {
22208 struct frame *f = XFRAME (w->frame);
22209 int mouse_face_overwritten_p = 0;
22210
22211 while (w && !FRAME_GARBAGED_P (f))
22212 {
22213 if (!NILP (w->hchild))
22214 mouse_face_overwritten_p
22215 |= expose_window_tree (XWINDOW (w->hchild), r);
22216 else if (!NILP (w->vchild))
22217 mouse_face_overwritten_p
22218 |= expose_window_tree (XWINDOW (w->vchild), r);
22219 else
22220 mouse_face_overwritten_p |= expose_window (w, r);
22221
22222 w = NILP (w->next) ? NULL : XWINDOW (w->next);
22223 }
22224
22225 return mouse_face_overwritten_p;
22226 }
22227
22228
22229 /* EXPORT:
22230 Redisplay an exposed area of frame F. X and Y are the upper-left
22231 corner of the exposed rectangle. W and H are width and height of
22232 the exposed area. All are pixel values. W or H zero means redraw
22233 the entire frame. */
22234
22235 void
22236 expose_frame (f, x, y, w, h)
22237 struct frame *f;
22238 int x, y, w, h;
22239 {
22240 XRectangle r;
22241 int mouse_face_overwritten_p = 0;
22242
22243 TRACE ((stderr, "expose_frame "));
22244
22245 /* No need to redraw if frame will be redrawn soon. */
22246 if (FRAME_GARBAGED_P (f))
22247 {
22248 TRACE ((stderr, " garbaged\n"));
22249 return;
22250 }
22251
22252 /* If basic faces haven't been realized yet, there is no point in
22253 trying to redraw anything. This can happen when we get an expose
22254 event while Emacs is starting, e.g. by moving another window. */
22255 if (FRAME_FACE_CACHE (f) == NULL
22256 || FRAME_FACE_CACHE (f)->used < BASIC_FACE_ID_SENTINEL)
22257 {
22258 TRACE ((stderr, " no faces\n"));
22259 return;
22260 }
22261
22262 if (w == 0 || h == 0)
22263 {
22264 r.x = r.y = 0;
22265 r.width = FRAME_COLUMN_WIDTH (f) * FRAME_COLS (f);
22266 r.height = FRAME_LINE_HEIGHT (f) * FRAME_LINES (f);
22267 }
22268 else
22269 {
22270 r.x = x;
22271 r.y = y;
22272 r.width = w;
22273 r.height = h;
22274 }
22275
22276 TRACE ((stderr, "(%d, %d, %d, %d)\n", r.x, r.y, r.width, r.height));
22277 mouse_face_overwritten_p = expose_window_tree (XWINDOW (f->root_window), &r);
22278
22279 if (WINDOWP (f->tool_bar_window))
22280 mouse_face_overwritten_p
22281 |= expose_window (XWINDOW (f->tool_bar_window), &r);
22282
22283 #ifdef HAVE_X_WINDOWS
22284 #ifndef MSDOS
22285 #ifndef USE_X_TOOLKIT
22286 if (WINDOWP (f->menu_bar_window))
22287 mouse_face_overwritten_p
22288 |= expose_window (XWINDOW (f->menu_bar_window), &r);
22289 #endif /* not USE_X_TOOLKIT */
22290 #endif
22291 #endif
22292
22293 /* Some window managers support a focus-follows-mouse style with
22294 delayed raising of frames. Imagine a partially obscured frame,
22295 and moving the mouse into partially obscured mouse-face on that
22296 frame. The visible part of the mouse-face will be highlighted,
22297 then the WM raises the obscured frame. With at least one WM, KDE
22298 2.1, Emacs is not getting any event for the raising of the frame
22299 (even tried with SubstructureRedirectMask), only Expose events.
22300 These expose events will draw text normally, i.e. not
22301 highlighted. Which means we must redo the highlight here.
22302 Subsume it under ``we love X''. --gerd 2001-08-15 */
22303 /* Included in Windows version because Windows most likely does not
22304 do the right thing if any third party tool offers
22305 focus-follows-mouse with delayed raise. --jason 2001-10-12 */
22306 if (mouse_face_overwritten_p && !FRAME_GARBAGED_P (f))
22307 {
22308 Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
22309 if (f == dpyinfo->mouse_face_mouse_frame)
22310 {
22311 int x = dpyinfo->mouse_face_mouse_x;
22312 int y = dpyinfo->mouse_face_mouse_y;
22313 clear_mouse_face (dpyinfo);
22314 note_mouse_highlight (f, x, y);
22315 }
22316 }
22317 }
22318
22319
22320 /* EXPORT:
22321 Determine the intersection of two rectangles R1 and R2. Return
22322 the intersection in *RESULT. Value is non-zero if RESULT is not
22323 empty. */
22324
22325 int
22326 x_intersect_rectangles (r1, r2, result)
22327 XRectangle *r1, *r2, *result;
22328 {
22329 XRectangle *left, *right;
22330 XRectangle *upper, *lower;
22331 int intersection_p = 0;
22332
22333 /* Rearrange so that R1 is the left-most rectangle. */
22334 if (r1->x < r2->x)
22335 left = r1, right = r2;
22336 else
22337 left = r2, right = r1;
22338
22339 /* X0 of the intersection is right.x0, if this is inside R1,
22340 otherwise there is no intersection. */
22341 if (right->x <= left->x + left->width)
22342 {
22343 result->x = right->x;
22344
22345 /* The right end of the intersection is the minimum of the
22346 the right ends of left and right. */
22347 result->width = (min (left->x + left->width, right->x + right->width)
22348 - result->x);
22349
22350 /* Same game for Y. */
22351 if (r1->y < r2->y)
22352 upper = r1, lower = r2;
22353 else
22354 upper = r2, lower = r1;
22355
22356 /* The upper end of the intersection is lower.y0, if this is inside
22357 of upper. Otherwise, there is no intersection. */
22358 if (lower->y <= upper->y + upper->height)
22359 {
22360 result->y = lower->y;
22361
22362 /* The lower end of the intersection is the minimum of the lower
22363 ends of upper and lower. */
22364 result->height = (min (lower->y + lower->height,
22365 upper->y + upper->height)
22366 - result->y);
22367 intersection_p = 1;
22368 }
22369 }
22370
22371 return intersection_p;
22372 }
22373
22374 #endif /* HAVE_WINDOW_SYSTEM */
22375
22376 \f
22377 /***********************************************************************
22378 Initialization
22379 ***********************************************************************/
22380
22381 void
22382 syms_of_xdisp ()
22383 {
22384 Vwith_echo_area_save_vector = Qnil;
22385 staticpro (&Vwith_echo_area_save_vector);
22386
22387 Vmessage_stack = Qnil;
22388 staticpro (&Vmessage_stack);
22389
22390 Qinhibit_redisplay = intern ("inhibit-redisplay");
22391 staticpro (&Qinhibit_redisplay);
22392
22393 message_dolog_marker1 = Fmake_marker ();
22394 staticpro (&message_dolog_marker1);
22395 message_dolog_marker2 = Fmake_marker ();
22396 staticpro (&message_dolog_marker2);
22397 message_dolog_marker3 = Fmake_marker ();
22398 staticpro (&message_dolog_marker3);
22399
22400 #if GLYPH_DEBUG
22401 defsubr (&Sdump_frame_glyph_matrix);
22402 defsubr (&Sdump_glyph_matrix);
22403 defsubr (&Sdump_glyph_row);
22404 defsubr (&Sdump_tool_bar_row);
22405 defsubr (&Strace_redisplay);
22406 defsubr (&Strace_to_stderr);
22407 #endif
22408 #ifdef HAVE_WINDOW_SYSTEM
22409 defsubr (&Stool_bar_lines_needed);
22410 defsubr (&Slookup_image_map);
22411 #endif
22412 defsubr (&Sformat_mode_line);
22413
22414 staticpro (&Qmenu_bar_update_hook);
22415 Qmenu_bar_update_hook = intern ("menu-bar-update-hook");
22416
22417 staticpro (&Qoverriding_terminal_local_map);
22418 Qoverriding_terminal_local_map = intern ("overriding-terminal-local-map");
22419
22420 staticpro (&Qoverriding_local_map);
22421 Qoverriding_local_map = intern ("overriding-local-map");
22422
22423 staticpro (&Qwindow_scroll_functions);
22424 Qwindow_scroll_functions = intern ("window-scroll-functions");
22425
22426 staticpro (&Qredisplay_end_trigger_functions);
22427 Qredisplay_end_trigger_functions = intern ("redisplay-end-trigger-functions");
22428
22429 staticpro (&Qinhibit_point_motion_hooks);
22430 Qinhibit_point_motion_hooks = intern ("inhibit-point-motion-hooks");
22431
22432 QCdata = intern (":data");
22433 staticpro (&QCdata);
22434 Qdisplay = intern ("display");
22435 staticpro (&Qdisplay);
22436 Qspace_width = intern ("space-width");
22437 staticpro (&Qspace_width);
22438 Qraise = intern ("raise");
22439 staticpro (&Qraise);
22440 Qslice = intern ("slice");
22441 staticpro (&Qslice);
22442 Qspace = intern ("space");
22443 staticpro (&Qspace);
22444 Qmargin = intern ("margin");
22445 staticpro (&Qmargin);
22446 Qpointer = intern ("pointer");
22447 staticpro (&Qpointer);
22448 Qleft_margin = intern ("left-margin");
22449 staticpro (&Qleft_margin);
22450 Qright_margin = intern ("right-margin");
22451 staticpro (&Qright_margin);
22452 Qcenter = intern ("center");
22453 staticpro (&Qcenter);
22454 Qline_height = intern ("line-height");
22455 staticpro (&Qline_height);
22456 QCalign_to = intern (":align-to");
22457 staticpro (&QCalign_to);
22458 QCrelative_width = intern (":relative-width");
22459 staticpro (&QCrelative_width);
22460 QCrelative_height = intern (":relative-height");
22461 staticpro (&QCrelative_height);
22462 QCeval = intern (":eval");
22463 staticpro (&QCeval);
22464 QCpropertize = intern (":propertize");
22465 staticpro (&QCpropertize);
22466 QCfile = intern (":file");
22467 staticpro (&QCfile);
22468 Qfontified = intern ("fontified");
22469 staticpro (&Qfontified);
22470 Qfontification_functions = intern ("fontification-functions");
22471 staticpro (&Qfontification_functions);
22472 Qtrailing_whitespace = intern ("trailing-whitespace");
22473 staticpro (&Qtrailing_whitespace);
22474 Qescape_glyph = intern ("escape-glyph");
22475 staticpro (&Qescape_glyph);
22476 Qimage = intern ("image");
22477 staticpro (&Qimage);
22478 QCmap = intern (":map");
22479 staticpro (&QCmap);
22480 QCpointer = intern (":pointer");
22481 staticpro (&QCpointer);
22482 Qrect = intern ("rect");
22483 staticpro (&Qrect);
22484 Qcircle = intern ("circle");
22485 staticpro (&Qcircle);
22486 Qpoly = intern ("poly");
22487 staticpro (&Qpoly);
22488 Qmessage_truncate_lines = intern ("message-truncate-lines");
22489 staticpro (&Qmessage_truncate_lines);
22490 Qcursor_in_non_selected_windows = intern ("cursor-in-non-selected-windows");
22491 staticpro (&Qcursor_in_non_selected_windows);
22492 Qgrow_only = intern ("grow-only");
22493 staticpro (&Qgrow_only);
22494 Qinhibit_menubar_update = intern ("inhibit-menubar-update");
22495 staticpro (&Qinhibit_menubar_update);
22496 Qinhibit_eval_during_redisplay = intern ("inhibit-eval-during-redisplay");
22497 staticpro (&Qinhibit_eval_during_redisplay);
22498 Qposition = intern ("position");
22499 staticpro (&Qposition);
22500 Qbuffer_position = intern ("buffer-position");
22501 staticpro (&Qbuffer_position);
22502 Qobject = intern ("object");
22503 staticpro (&Qobject);
22504 Qbar = intern ("bar");
22505 staticpro (&Qbar);
22506 Qhbar = intern ("hbar");
22507 staticpro (&Qhbar);
22508 Qbox = intern ("box");
22509 staticpro (&Qbox);
22510 Qhollow = intern ("hollow");
22511 staticpro (&Qhollow);
22512 Qhand = intern ("hand");
22513 staticpro (&Qhand);
22514 Qarrow = intern ("arrow");
22515 staticpro (&Qarrow);
22516 Qtext = intern ("text");
22517 staticpro (&Qtext);
22518 Qrisky_local_variable = intern ("risky-local-variable");
22519 staticpro (&Qrisky_local_variable);
22520 Qinhibit_free_realized_faces = intern ("inhibit-free-realized-faces");
22521 staticpro (&Qinhibit_free_realized_faces);
22522
22523 list_of_error = Fcons (Fcons (intern ("error"),
22524 Fcons (intern ("void-variable"), Qnil)),
22525 Qnil);
22526 staticpro (&list_of_error);
22527
22528 Qlast_arrow_position = intern ("last-arrow-position");
22529 staticpro (&Qlast_arrow_position);
22530 Qlast_arrow_string = intern ("last-arrow-string");
22531 staticpro (&Qlast_arrow_string);
22532
22533 Qoverlay_arrow_string = intern ("overlay-arrow-string");
22534 staticpro (&Qoverlay_arrow_string);
22535 Qoverlay_arrow_bitmap = intern ("overlay-arrow-bitmap");
22536 staticpro (&Qoverlay_arrow_bitmap);
22537
22538 echo_buffer[0] = echo_buffer[1] = Qnil;
22539 staticpro (&echo_buffer[0]);
22540 staticpro (&echo_buffer[1]);
22541
22542 echo_area_buffer[0] = echo_area_buffer[1] = Qnil;
22543 staticpro (&echo_area_buffer[0]);
22544 staticpro (&echo_area_buffer[1]);
22545
22546 Vmessages_buffer_name = build_string ("*Messages*");
22547 staticpro (&Vmessages_buffer_name);
22548
22549 mode_line_proptrans_alist = Qnil;
22550 staticpro (&mode_line_proptrans_alist);
22551
22552 mode_line_string_list = Qnil;
22553 staticpro (&mode_line_string_list);
22554
22555 help_echo_string = Qnil;
22556 staticpro (&help_echo_string);
22557 help_echo_object = Qnil;
22558 staticpro (&help_echo_object);
22559 help_echo_window = Qnil;
22560 staticpro (&help_echo_window);
22561 previous_help_echo_string = Qnil;
22562 staticpro (&previous_help_echo_string);
22563 help_echo_pos = -1;
22564
22565 #ifdef HAVE_WINDOW_SYSTEM
22566 DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
22567 doc: /* *Non-nil means draw block cursor as wide as the glyph under it.
22568 For example, if a block cursor is over a tab, it will be drawn as
22569 wide as that tab on the display. */);
22570 x_stretch_cursor_p = 0;
22571 #endif
22572
22573 DEFVAR_LISP ("show-trailing-whitespace", &Vshow_trailing_whitespace,
22574 doc: /* *Non-nil means highlight trailing whitespace.
22575 The face used for trailing whitespace is `trailing-whitespace'. */);
22576 Vshow_trailing_whitespace = Qnil;
22577
22578 DEFVAR_LISP ("show-nonbreak-escape", &Vshow_nonbreak_escape,
22579 doc: /* *Non-nil means display escape character before non-break space and hyphen. */);
22580 Vshow_nonbreak_escape = Qt;
22581
22582 DEFVAR_LISP ("void-text-area-pointer", &Vvoid_text_area_pointer,
22583 doc: /* *The pointer shape to show in void text areas.
22584 Nil means to show the text pointer. Other options are `arrow', `text',
22585 `hand', `vdrag', `hdrag', `modeline', and `hourglass'. */);
22586 Vvoid_text_area_pointer = Qarrow;
22587
22588 DEFVAR_LISP ("inhibit-redisplay", &Vinhibit_redisplay,
22589 doc: /* Non-nil means don't actually do any redisplay.
22590 This is used for internal purposes. */);
22591 Vinhibit_redisplay = Qnil;
22592
22593 DEFVAR_LISP ("global-mode-string", &Vglobal_mode_string,
22594 doc: /* String (or mode line construct) included (normally) in `mode-line-format'. */);
22595 Vglobal_mode_string = Qnil;
22596
22597 DEFVAR_LISP ("overlay-arrow-position", &Voverlay_arrow_position,
22598 doc: /* Marker for where to display an arrow on top of the buffer text.
22599 This must be the beginning of a line in order to work.
22600 See also `overlay-arrow-string'. */);
22601 Voverlay_arrow_position = Qnil;
22602
22603 DEFVAR_LISP ("overlay-arrow-string", &Voverlay_arrow_string,
22604 doc: /* String to display as an arrow in non-window frames.
22605 See also `overlay-arrow-position'. */);
22606 Voverlay_arrow_string = build_string ("=>");
22607
22608 DEFVAR_LISP ("overlay-arrow-variable-list", &Voverlay_arrow_variable_list,
22609 doc: /* List of variables (symbols) which hold markers for overlay arrows.
22610 The symbols on this list are examined during redisplay to determine
22611 where to display overlay arrows. */);
22612 Voverlay_arrow_variable_list
22613 = Fcons (intern ("overlay-arrow-position"), Qnil);
22614
22615 DEFVAR_INT ("scroll-step", &scroll_step,
22616 doc: /* *The number of lines to try scrolling a window by when point moves out.
22617 If that fails to bring point back on frame, point is centered instead.
22618 If this is zero, point is always centered after it moves off frame.
22619 If you want scrolling to always be a line at a time, you should set
22620 `scroll-conservatively' to a large value rather than set this to 1. */);
22621
22622 DEFVAR_INT ("scroll-conservatively", &scroll_conservatively,
22623 doc: /* *Scroll up to this many lines, to bring point back on screen.
22624 A value of zero means to scroll the text to center point vertically
22625 in the window. */);
22626 scroll_conservatively = 0;
22627
22628 DEFVAR_INT ("scroll-margin", &scroll_margin,
22629 doc: /* *Number of lines of margin at the top and bottom of a window.
22630 Recenter the window whenever point gets within this many lines
22631 of the top or bottom of the window. */);
22632 scroll_margin = 0;
22633
22634 DEFVAR_LISP ("display-pixels-per-inch", &Vdisplay_pixels_per_inch,
22635 doc: /* Pixels per inch on current display.
22636 Value is a number or a cons (WIDTH-DPI . HEIGHT-DPI). */);
22637 Vdisplay_pixels_per_inch = make_float (72.0);
22638
22639 #if GLYPH_DEBUG
22640 DEFVAR_INT ("debug-end-pos", &debug_end_pos, doc: /* Don't ask. */);
22641 #endif
22642
22643 DEFVAR_BOOL ("truncate-partial-width-windows",
22644 &truncate_partial_width_windows,
22645 doc: /* *Non-nil means truncate lines in all windows less than full frame wide. */);
22646 truncate_partial_width_windows = 1;
22647
22648 DEFVAR_BOOL ("mode-line-inverse-video", &mode_line_inverse_video,
22649 doc: /* nil means display the mode-line/header-line/menu-bar in the default face.
22650 Any other value means to use the appropriate face, `mode-line',
22651 `header-line', or `menu' respectively. */);
22652 mode_line_inverse_video = 1;
22653
22654 DEFVAR_LISP ("line-number-display-limit", &Vline_number_display_limit,
22655 doc: /* *Maximum buffer size for which line number should be displayed.
22656 If the buffer is bigger than this, the line number does not appear
22657 in the mode line. A value of nil means no limit. */);
22658 Vline_number_display_limit = Qnil;
22659
22660 DEFVAR_INT ("line-number-display-limit-width",
22661 &line_number_display_limit_width,
22662 doc: /* *Maximum line width (in characters) for line number display.
22663 If the average length of the lines near point is bigger than this, then the
22664 line number may be omitted from the mode line. */);
22665 line_number_display_limit_width = 200;
22666
22667 DEFVAR_BOOL ("highlight-nonselected-windows", &highlight_nonselected_windows,
22668 doc: /* *Non-nil means highlight region even in nonselected windows. */);
22669 highlight_nonselected_windows = 0;
22670
22671 DEFVAR_BOOL ("multiple-frames", &multiple_frames,
22672 doc: /* Non-nil if more than one frame is visible on this display.
22673 Minibuffer-only frames don't count, but iconified frames do.
22674 This variable is not guaranteed to be accurate except while processing
22675 `frame-title-format' and `icon-title-format'. */);
22676
22677 DEFVAR_LISP ("frame-title-format", &Vframe_title_format,
22678 doc: /* Template for displaying the title bar of visible frames.
22679 \(Assuming the window manager supports this feature.)
22680 This variable has the same structure as `mode-line-format' (which see),
22681 and is used only on frames for which no explicit name has been set
22682 \(see `modify-frame-parameters'). */);
22683
22684 DEFVAR_LISP ("icon-title-format", &Vicon_title_format,
22685 doc: /* Template for displaying the title bar of an iconified frame.
22686 \(Assuming the window manager supports this feature.)
22687 This variable has the same structure as `mode-line-format' (which see),
22688 and is used only on frames for which no explicit name has been set
22689 \(see `modify-frame-parameters'). */);
22690 Vicon_title_format
22691 = Vframe_title_format
22692 = Fcons (intern ("multiple-frames"),
22693 Fcons (build_string ("%b"),
22694 Fcons (Fcons (empty_string,
22695 Fcons (intern ("invocation-name"),
22696 Fcons (build_string ("@"),
22697 Fcons (intern ("system-name"),
22698 Qnil)))),
22699 Qnil)));
22700
22701 DEFVAR_LISP ("message-log-max", &Vmessage_log_max,
22702 doc: /* Maximum number of lines to keep in the message log buffer.
22703 If nil, disable message logging. If t, log messages but don't truncate
22704 the buffer when it becomes large. */);
22705 Vmessage_log_max = make_number (50);
22706
22707 DEFVAR_LISP ("window-size-change-functions", &Vwindow_size_change_functions,
22708 doc: /* Functions called before redisplay, if window sizes have changed.
22709 The value should be a list of functions that take one argument.
22710 Just before redisplay, for each frame, if any of its windows have changed
22711 size since the last redisplay, or have been split or deleted,
22712 all the functions in the list are called, with the frame as argument. */);
22713 Vwindow_size_change_functions = Qnil;
22714
22715 DEFVAR_LISP ("window-scroll-functions", &Vwindow_scroll_functions,
22716 doc: /* List of functions to call before redisplaying a window with scrolling.
22717 Each function is called with two arguments, the window
22718 and its new display-start position. Note that the value of `window-end'
22719 is not valid when these functions are called. */);
22720 Vwindow_scroll_functions = Qnil;
22721
22722 DEFVAR_BOOL ("mouse-autoselect-window", &mouse_autoselect_window,
22723 doc: /* *Non-nil means autoselect window with mouse pointer. */);
22724 mouse_autoselect_window = 0;
22725
22726 DEFVAR_BOOL ("auto-resize-tool-bars", &auto_resize_tool_bars_p,
22727 doc: /* *Non-nil means automatically resize tool-bars.
22728 This increases a tool-bar's height if not all tool-bar items are visible.
22729 It decreases a tool-bar's height when it would display blank lines
22730 otherwise. */);
22731 auto_resize_tool_bars_p = 1;
22732
22733 DEFVAR_BOOL ("auto-raise-tool-bar-buttons", &auto_raise_tool_bar_buttons_p,
22734 doc: /* *Non-nil means raise tool-bar buttons when the mouse moves over them. */);
22735 auto_raise_tool_bar_buttons_p = 1;
22736
22737 DEFVAR_BOOL ("make-cursor-line-fully-visible", &make_cursor_line_fully_visible_p,
22738 doc: /* *Non-nil means to scroll (recenter) cursor line if it is not fully visible. */);
22739 make_cursor_line_fully_visible_p = 1;
22740
22741 DEFVAR_LISP ("tool-bar-button-margin", &Vtool_bar_button_margin,
22742 doc: /* *Margin around tool-bar buttons in pixels.
22743 If an integer, use that for both horizontal and vertical margins.
22744 Otherwise, value should be a pair of integers `(HORZ . VERT)' with
22745 HORZ specifying the horizontal margin, and VERT specifying the
22746 vertical margin. */);
22747 Vtool_bar_button_margin = make_number (DEFAULT_TOOL_BAR_BUTTON_MARGIN);
22748
22749 DEFVAR_INT ("tool-bar-button-relief", &tool_bar_button_relief,
22750 doc: /* *Relief thickness of tool-bar buttons. */);
22751 tool_bar_button_relief = DEFAULT_TOOL_BAR_BUTTON_RELIEF;
22752
22753 DEFVAR_LISP ("fontification-functions", &Vfontification_functions,
22754 doc: /* List of functions to call to fontify regions of text.
22755 Each function is called with one argument POS. Functions must
22756 fontify a region starting at POS in the current buffer, and give
22757 fontified regions the property `fontified'. */);
22758 Vfontification_functions = Qnil;
22759 Fmake_variable_buffer_local (Qfontification_functions);
22760
22761 DEFVAR_BOOL ("unibyte-display-via-language-environment",
22762 &unibyte_display_via_language_environment,
22763 doc: /* *Non-nil means display unibyte text according to language environment.
22764 Specifically this means that unibyte non-ASCII characters
22765 are displayed by converting them to the equivalent multibyte characters
22766 according to the current language environment. As a result, they are
22767 displayed according to the current fontset. */);
22768 unibyte_display_via_language_environment = 0;
22769
22770 DEFVAR_LISP ("max-mini-window-height", &Vmax_mini_window_height,
22771 doc: /* *Maximum height for resizing mini-windows.
22772 If a float, it specifies a fraction of the mini-window frame's height.
22773 If an integer, it specifies a number of lines. */);
22774 Vmax_mini_window_height = make_float (0.25);
22775
22776 DEFVAR_LISP ("resize-mini-windows", &Vresize_mini_windows,
22777 doc: /* *How to resize mini-windows.
22778 A value of nil means don't automatically resize mini-windows.
22779 A value of t means resize them to fit the text displayed in them.
22780 A value of `grow-only', the default, means let mini-windows grow
22781 only, until their display becomes empty, at which point the windows
22782 go back to their normal size. */);
22783 Vresize_mini_windows = Qgrow_only;
22784
22785 DEFVAR_LISP ("cursor-in-non-selected-windows",
22786 &Vcursor_in_non_selected_windows,
22787 doc: /* *Cursor type to display in non-selected windows.
22788 t means to use hollow box cursor. See `cursor-type' for other values. */);
22789 Vcursor_in_non_selected_windows = Qt;
22790
22791 DEFVAR_LISP ("blink-cursor-alist", &Vblink_cursor_alist,
22792 doc: /* Alist specifying how to blink the cursor off.
22793 Each element has the form (ON-STATE . OFF-STATE). Whenever the
22794 `cursor-type' frame-parameter or variable equals ON-STATE,
22795 comparing using `equal', Emacs uses OFF-STATE to specify
22796 how to blink it off. */);
22797 Vblink_cursor_alist = Qnil;
22798
22799 DEFVAR_BOOL ("auto-hscroll-mode", &automatic_hscrolling_p,
22800 doc: /* *Non-nil means scroll the display automatically to make point visible. */);
22801 automatic_hscrolling_p = 1;
22802
22803 DEFVAR_INT ("hscroll-margin", &hscroll_margin,
22804 doc: /* *How many columns away from the window edge point is allowed to get
22805 before automatic hscrolling will horizontally scroll the window. */);
22806 hscroll_margin = 5;
22807
22808 DEFVAR_LISP ("hscroll-step", &Vhscroll_step,
22809 doc: /* *How many columns to scroll the window when point gets too close to the edge.
22810 When point is less than `automatic-hscroll-margin' columns from the window
22811 edge, automatic hscrolling will scroll the window by the amount of columns
22812 determined by this variable. If its value is a positive integer, scroll that
22813 many columns. If it's a positive floating-point number, it specifies the
22814 fraction of the window's width to scroll. If it's nil or zero, point will be
22815 centered horizontally after the scroll. Any other value, including negative
22816 numbers, are treated as if the value were zero.
22817
22818 Automatic hscrolling always moves point outside the scroll margin, so if
22819 point was more than scroll step columns inside the margin, the window will
22820 scroll more than the value given by the scroll step.
22821
22822 Note that the lower bound for automatic hscrolling specified by `scroll-left'
22823 and `scroll-right' overrides this variable's effect. */);
22824 Vhscroll_step = make_number (0);
22825
22826 DEFVAR_BOOL ("message-truncate-lines", &message_truncate_lines,
22827 doc: /* If non-nil, messages are truncated instead of resizing the echo area.
22828 Bind this around calls to `message' to let it take effect. */);
22829 message_truncate_lines = 0;
22830
22831 DEFVAR_LISP ("menu-bar-update-hook", &Vmenu_bar_update_hook,
22832 doc: /* Normal hook run to update the menu bar definitions.
22833 Redisplay runs this hook before it redisplays the menu bar.
22834 This is used to update submenus such as Buffers,
22835 whose contents depend on various data. */);
22836 Vmenu_bar_update_hook = Qnil;
22837
22838 DEFVAR_BOOL ("inhibit-menubar-update", &inhibit_menubar_update,
22839 doc: /* Non-nil means don't update menu bars. Internal use only. */);
22840 inhibit_menubar_update = 0;
22841
22842 DEFVAR_BOOL ("inhibit-eval-during-redisplay", &inhibit_eval_during_redisplay,
22843 doc: /* Non-nil means don't eval Lisp during redisplay. */);
22844 inhibit_eval_during_redisplay = 0;
22845
22846 DEFVAR_BOOL ("inhibit-free-realized-faces", &inhibit_free_realized_faces,
22847 doc: /* Non-nil means don't free realized faces. Internal use only. */);
22848 inhibit_free_realized_faces = 0;
22849
22850 #if GLYPH_DEBUG
22851 DEFVAR_BOOL ("inhibit-try-window-id", &inhibit_try_window_id,
22852 doc: /* Inhibit try_window_id display optimization. */);
22853 inhibit_try_window_id = 0;
22854
22855 DEFVAR_BOOL ("inhibit-try-window-reusing", &inhibit_try_window_reusing,
22856 doc: /* Inhibit try_window_reusing display optimization. */);
22857 inhibit_try_window_reusing = 0;
22858
22859 DEFVAR_BOOL ("inhibit-try-cursor-movement", &inhibit_try_cursor_movement,
22860 doc: /* Inhibit try_cursor_movement display optimization. */);
22861 inhibit_try_cursor_movement = 0;
22862 #endif /* GLYPH_DEBUG */
22863 }
22864
22865
22866 /* Initialize this module when Emacs starts. */
22867
22868 void
22869 init_xdisp ()
22870 {
22871 Lisp_Object root_window;
22872 struct window *mini_w;
22873
22874 current_header_line_height = current_mode_line_height = -1;
22875
22876 CHARPOS (this_line_start_pos) = 0;
22877
22878 mini_w = XWINDOW (minibuf_window);
22879 root_window = FRAME_ROOT_WINDOW (XFRAME (WINDOW_FRAME (mini_w)));
22880
22881 if (!noninteractive)
22882 {
22883 struct frame *f = XFRAME (WINDOW_FRAME (XWINDOW (root_window)));
22884 int i;
22885
22886 XWINDOW (root_window)->top_line = make_number (FRAME_TOP_MARGIN (f));
22887 set_window_height (root_window,
22888 FRAME_LINES (f) - 1 - FRAME_TOP_MARGIN (f),
22889 0);
22890 mini_w->top_line = make_number (FRAME_LINES (f) - 1);
22891 set_window_height (minibuf_window, 1, 0);
22892
22893 XWINDOW (root_window)->total_cols = make_number (FRAME_COLS (f));
22894 mini_w->total_cols = make_number (FRAME_COLS (f));
22895
22896 scratch_glyph_row.glyphs[TEXT_AREA] = scratch_glyphs;
22897 scratch_glyph_row.glyphs[TEXT_AREA + 1]
22898 = scratch_glyphs + MAX_SCRATCH_GLYPHS;
22899
22900 /* The default ellipsis glyphs `...'. */
22901 for (i = 0; i < 3; ++i)
22902 default_invis_vector[i] = make_number ('.');
22903 }
22904
22905 {
22906 /* Allocate the buffer for frame titles.
22907 Also used for `format-mode-line'. */
22908 int size = 100;
22909 frame_title_buf = (char *) xmalloc (size);
22910 frame_title_buf_end = frame_title_buf + size;
22911 frame_title_ptr = NULL;
22912 }
22913
22914 help_echo_showing_p = 0;
22915 }
22916
22917
22918 /* arch-tag: eacc864d-bb6a-4b74-894a-1a4399a1358b
22919 (do not change this comment) */